#include #include #include /* * nonuniform rational B-spline surface * * 4/7/03 pjf * */ GLfloat p[4][4][3]; #define NKNOTS 8 GLfloat knots[8] = { 0, 0, 0, 0, 1, 1, 1, 1 }; // open spline aka Bezier curve #define ORDER 4 #define USTRIDE (4*3) #define VSTRIDE 3 GLUnurbsObj *nurb; void init_surface(void) { // define a "hill" approacing z=3 in the middle, z=-3 at the edges int u,v; for(u=0;u<4;u++) for(v=0;v<4;v++) { p[u][v][0] = 2.0*(u-1.5); p[u][v][1] = 2.0*(v-1.5); if (((u==1) | (u==2)) && ((v==1)||(v==2))) p[u][v][2] = 3.0; else p[u][v][2] = -3.0; } } void CALLBACK nurbsError(GLenum errorCode) { const GLubyte *s = gluErrorString(errorCode); fprintf(stderr,"NURBS error: %s\n",s); exit(-1); } /* display callback */ void display() { int i,j; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(330,1,0,0); glScalef(.5,.5,.5); gluBeginSurface(nurb); gluNurbsSurface(nurb,NKNOTS,knots, // u knots NKNOTS,knots, // v knots USTRIDE, //u VSTRIDE, //v &p[0][0][0], ORDER, ORDER, GL_MAP2_VERTEX_3); gluEndSurface(nurb); // display the control points glPointSize(5); glDisable(GL_LIGHTING); glColor3f(1,1,0); glBegin(GL_POINTS); for(i=0;i<4;i++) for(j=0;j<4;j++) glVertex3f(p[i][j][0],p[i][j][1],p[i][j][2]); glEnd(); glEnable(GL_LIGHTING); glPopMatrix(); glFlush(); } void reshape(int w, int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,(GLdouble)w/(GLdouble)h,3.0,8.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0,0,-5); } void init(void) { GLfloat diffuse[] = { .7, .7, .7, 1 }, specular[] = { 1, 1, 1, 1 }, shine[] = { 100 }; glClearColor(0,0,0,0); glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,specular); glMaterialfv(GL_FRONT,GL_SHININESS,shine); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); init_surface(); nurb = gluNewNurbsRenderer(); gluNurbsProperty(nurb,GLU_SAMPLING_TOLERANCE,25); gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON); gluNurbsCallback(nurb,GLU_ERROR,nurbsError); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); glutReshapeFunc(reshape); glutDisplayFunc(display); init(); glutMainLoop(); return 0; }