/* Rendering a Bezier curve using OpenGL calls. Click and drag left button to specify first two control points. Click and drag right button to specify last two control points. Scott D. Anderson Fall 2002 */ #include #include #include #include int win_width = 500; int win_height = 500; typedef GLfloat point[3]; GLfloat bezier[] = { 20, 350, 0, 150, 360, 0, 390, 150, 0, 300, 40, 0}; int steps; void draw_curve() { glMap1f(GL_MAP1_VERTEX_3, 0, 1, 3, 4, bezier); glEnable(GL_MAP1_VERTEX_3); glMapGrid1f(steps,0.0,1.0); glEvalMesh1(GL_LINE,0,steps); } void display(void) { int i; twTriple point; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_POINTS); for(i=0; i<12; i+=3) { // stride is 3 twTripleInit(point, bezier[i], bezier[i+1], bezier[i+2]); glVertex3fv(point); twDrawString(point,10,10,"P%d",i/3); } glEnd(); glColor3f(0.0,1.0,0.0); draw_curve(); glFlush(); } void myReshape(int w, int h) { win_width=w; win_height=h; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,w,0,h); glMatrixMode(GL_MODELVIEW); } int mod_point; /* index of point to modify */ float old_x, old_y; /* old point for motion function */ int mouse_motion = 0; /* true when tracking mouse */ void mouse(int button, int state, int x, int y) { // transform (x,y) to world coordinates GLfloat fx=x; GLfloat fy=win_height-y; if(button==GLUT_MIDDLE_BUTTON) return; if(state==GLUT_DOWN) { glColor3f(1,0,0); glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_XOR); mouse_motion = 1; old_x = fx; old_y = fy; if(button==GLUT_LEFT_BUTTON) mod_point=0; else mod_point=2; } else { glColor3f(0,1,0); glLogicOp(GL_COPY); mouse_motion = 0; if(button==GLUT_LEFT_BUTTON) mod_point=1; else mod_point=3; } bezier[mod_point*3] = fx; bezier[mod_point*3+1] = fy; glutPostRedisplay(); } void motion(int x, int y) { if( !mouse_motion ) return; y=win_height-y; glBegin(GL_LINES); { glVertex2f(bezier[mod_point*3], bezier[mod_point*3+1]); glVertex2f(old_x,old_y); old_x = x; old_y = y; glVertex2f(bezier[mod_point*3], bezier[mod_point*3+1]); glVertex2f(old_x,old_y); } glEnd(); glFlush(); } void myinit() { glClearColor (0.0, 0.0, 0.0, 1.0); glColor3f (1.0, 1.0, 1.0); glPointSize(5); glLineWidth(2); } void keys(unsigned char key, int x, int y) { if(key == 'q') exit(0); glutPostRedisplay(); } main(int argc, char *argv[]) { if(argc<2) { printf("usage: %s num-steps\nClick and drag left button to specify first two control points.\nClick and drag right button to specify last two control points.\n",argv[0]); exit(0); } steps=atoi(argv[1]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(win_width, win_height); glutCreateWindow("Bezier"); myinit(); glutKeyboardFunc(keys); glutMouseFunc(mouse); glutMotionFunc(motion); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMainLoop(); }