/* Demonstrates lighting of Bezier surfaces, comparing a glut cylinder with a Bezier piece like the Coke bottle. Written by Scott D. Anderson scott.anderson@acm.org Fall 2004 */ #include #include #include GLfloat CurveCP[4][3] = { {1, 2.0, 0}, {1, 1.9, 0}, {1, 0.1, 0}, {1, 0.0, 0}}; GLfloat SurfaceCP[4][4][3]; void circular_slice(GLfloat surface_cp[4][4][3], GLfloat silhouette_cp[4][3]) { GLfloat radius, dist; int i,j; // i moves from one silhouette CP to another for(i=0; i<4; i++) { // j copies all the y values for these CPs, since they all have the same y for(j=0;j<4; j++) { surface_cp[i][j][1] = silhouette_cp[i][1]; } radius = silhouette_cp[i][0]; dist = radius*0.552; // distance of inner control points // circle CP0 is right on the silhouette, so x values are the same surface_cp[i][0][0] = radius; surface_cp[i][0][2] = 0.0; // CP1 is in front of the silhouette, at the same x, just 0.552 on the Z surface_cp[i][1][0] = radius; surface_cp[i][1][2] = dist; // CP2 is in front the silhouette, at the same Z as the CP3 surface_cp[i][2][0] = dist; surface_cp[i][2][2] = radius; // CP3 is at x=0, with Z being the X value of the silhouette CP surface_cp[i][3][0] = 0.0; surface_cp[i][3][2] = radius; } #if DEBUG for(i=0;i<4;i++) for(j=0;j<4;j++) printf("{%4.2f,%4.2f,%4.2f}\n", SurfaceCP[i][j][0], SurfaceCP[i][j][1], SurfaceCP[i][j][2]); #endif } void surfaceInit() { circular_slice(SurfaceCP,CurveCP); } void draw_bezier_surface(GLfloat* cp) { int hsteps = 8; // horizontal; 8 steps per quarter int vsteps = 1; // vertical glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, cp); glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glMapGrid2f(hsteps,0.0,1.0,vsteps,0.0,1.0); glEvalMesh2(GL_FILL,0,hsteps,0,vsteps); twError(); } void draw_circular_slice(GLfloat cp[4][4][3]) { int q=0; // q is the quadrant of the circular cross-section that we're drawing. glPushMatrix(); for(;;) { draw_bezier_surface(&cp[0][0][0]); if(q++>=4) break; glRotatef(90,0,1,0); } glPopMatrix(); } void display(void) { twDisplayInit(); twCamera(); GLfloat light0Pos[] = {0, 0, 1, 0}; twGrayLight(GL_LIGHT0,light0Pos,1,1,1); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glShadeModel(GL_SMOOTH); twAmbient(0.2); twTriple objColor = {0.2, 0.3, 0.4}; twColor(objColor,0.9,20); glPushMatrix(); glTranslatef(-1,0,0); glRotatef(-90,1,0,0); // z points up twCylinder(1,1,2,32,1); // left cylinder has 32 circumference steps glPopMatrix(); glPushMatrix(); glTranslatef(1,0,0); twError(); draw_circular_slice(SurfaceCP); twError(); glPopMatrix(); glFlush(); glutSwapBuffers(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500,500); glutCreateWindow(argv[0]); surfaceInit(); glutDisplayFunc(display); twBoundingBox(-2,2,0,2,-1,1); twMainInit(); glutMainLoop(); return 0; }