/* * Adapted from http://www.opengl.org/resources/code/samples/redbook/surface.c * * Wu Shin - Ting (9/03/10) * */ /* * curve.c * This program draws a NURBS curve equivalent to a Bezier * curve. * The 'c' keyboard key allows you to * toggle the visibility of the control points themselves. */ #include #include #include #ifndef CALLBACK #define CALLBACK #endif GLfloat ctlpoints[4][3] = { { -4.0, -4.0, 0.0}, { 1.0, 4.5, 0.0}, {-1.0, 4.5, 0.0}, {4.0, -4.0, 0.0}}; GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; int showPoints = 1; GLUnurbsObj *theNurb; void CALLBACK nurbsError(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); fprintf (stderr, "Nurbs Error: %s\n", estring); exit (0); } /* Initialize */ void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_METHOD, GLU_PATH_LENGTH); gluNurbsProperty(theNurb, GLU_PARAMETRIC_TOLERANCE, 0.1); gluNurbsCallback(theNurb, GLU_ERROR, nurbsError); } void display(void) { int i, j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLineWidth(3.0); glColor3f(1.0, 1.0, 1.0); gluBeginCurve(theNurb); gluNurbsCurve(theNurb, 8, knots, 3, &ctlpoints[0][0], 4, GL_MAP1_VERTEX_3); gluEndCurve(theNurb); if (showPoints) { glPointSize(5.0); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) { glVertex3f(ctlpoints[i][0], ctlpoints[i][1], ctlpoints[i][2]); } glEnd(); glLineWidth(1.0); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_STRIP); for (i = 0; i < 4; i++) { glVertex3f(ctlpoints[i][0], ctlpoints[i][1], ctlpoints[i][2]); } 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) { switch (key) { case 'c': case 'C': showPoints = !showPoints; glutPostRedisplay(); break; case 27: exit(0); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow(argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; }