/* * CPSC 465 * Principles of Computer Graphics * Section 1 * Spring 2006 * * Assignment 7 * * Analytic Clipping * */ #include #include #include #if defined(__APPLE__) || defined(MACOSX) #include #else #include #endif #if !defined(__cplusplus) #define bool int #define false 0 #define true !false #endif #define INITIAL_WIDTH 640 #define INITIAL_HEIGHT 480 /* Window Size */ int width = INITIAL_WIDTH, height = INITIAL_HEIGHT; double clip_left = 40, clip_bottom = 40; double clip_right = INITIAL_WIDTH - 40, clip_top = INITIAL_HEIGHT - 40; double p0_x = 80, p0_y = 20; double p1_x = 560, p1_y = 460; enum drag_state { LEFT_BOTTOM, RIGHT_TOP, P0, P1, NONE }; enum drag_state dragging = NONE; void drawClipRectangle() { glColor3d(0.0, 0.0, 1.0); glBegin(GL_LINE_LOOP); glVertex2i(clip_left, clip_bottom); glVertex2i(clip_right, clip_bottom); glVertex2i(clip_right, clip_top); glVertex2i(clip_left, clip_top); glEnd(); } void clipLine(void) { /* TODO: Clip (p0_x, p0_y) and (p1_x, p1_y) */ } void drawLine(void) { glColor3d(1.0, 1.0, 0.0); glBegin(GL_LINES); glVertex2i(p0_x, p0_y); glVertex2i(p1_x, p1_y); glEnd(); } void drawHandle(int x, int y) { glPushAttrib(GL_ALL_ATTRIB_BITS); glPointSize(10.0); glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); glPopAttrib(); } void drawHandles(void) { glColor3d(0.0, 1.0, 0.0); drawHandle(clip_left, clip_bottom); drawHandle(clip_right, clip_top); glColor3d(1.0, 0.0, 0.0); drawHandle(p0_x, p0_y); drawHandle(p1_x, p1_y); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, width, 0.0, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); clipLine(); drawLine(); drawClipRectangle(); drawHandles(); glutSwapBuffers(); } bool hit_test(int x, int y, int tx, int ty) { return (x > tx - 10 && x < tx + 10 && y > ty - 10 && y < ty + 10); } void mouse(int button, int state, int x, int y) { if (state == GLUT_UP) { dragging = NONE; } if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && dragging == NONE) { y = height - y; if (hit_test(x, y, clip_left, clip_bottom)) { dragging = LEFT_BOTTOM; } else if (hit_test(x, y, clip_right, clip_top)) { dragging = RIGHT_TOP; } else if (hit_test(x, y, p0_x, p0_y)) { dragging = P0; } else if (hit_test(x, y, p1_x, p1_y)) { dragging = P1; } glutPostRedisplay(); } } void motion(int x, int y) { y = height - y; switch (dragging) { case LEFT_BOTTOM: clip_left = x; clip_bottom = y; break; case RIGHT_TOP: clip_right = x; clip_top = y; break; case P0: p0_x = x; p0_y = y; break; case P1: p1_x = x; p1_y = y; break; } glutPostRedisplay(); } void reshape(int w, int h) { width = w; height = h; glViewport(0, 0, width, height); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(width, height); glutInitWindowPosition(100, 100); glutCreateWindow("Analytical Clipping"); glClearColor(0.0, 0.0, 0.0, 0.0); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); return 0; }