/* * bezier_curve.cpp, based on bezcurve.c from OpenGL Red Book. * This program uses evaluators to draw a cubic Bezier curve. * Draws the curve by evaluating individual vertex coordinates * or by evaluating a uniform one-dimensional grid. */ #include #include GLfloat ctrlpoints[4][3] = { { -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0}, {2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}}; int coord; void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); coord = 1; } void display(void) { int i; int num_steps = 30; // number of steps to generate curve glClear(GL_COLOR_BUFFER_BIT); // generate individual vertex coords to draw curve if(coord){ glColor3f(1.0, 1.0, 1.0); glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]); glEnable(GL_MAP1_VERTEX_3); glBegin(GL_LINE_STRIP); // step uniformly along u for (i = 0; i <= num_steps; i++) glEvalCoord1f((GLfloat) i/ (float) num_steps); glEnd(); } // or (equivalently) generate uniform grid to draw curve else { glColor3f(1.0, 0.0, 0.0); glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]); glEnable(GL_MAP1_VERTEX_3); glMapGrid1f(num_steps, 0.0, 1.0); glEvalMesh1(GL_LINE, 0, num_steps); // replace GL_LINE with GL_POINT // to see evaluated grid points } /* The following code displays the control points as dots. */ glPointSize(5.0); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) glVertex3fv(&ctrlpoints[i][0]); glEnd(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0); else glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { if (key == 'q' || key == 'Q') exit(0); else if (key == 'c'){ // vertex coords coord = 1; glutPostRedisplay(); } else if (key == 'g'){ // uniform grid coord = 0; glutPostRedisplay(); } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; }