/* A 2D Bezier surfaces, showing lighting and normal generation. The cull_face stuff still doesn't work as I'd like, so ignore that. The quad is culled correctly (it's facing forward), but the bezier surfaces are all being culled because, apparently, they face backward. Can we change this by modifying the order of the vertices? I don't know. Written by Scott D. Anderson scott.anderson@acm.org Fall 2007 */ #include #include // for atoi and exit #include #include "bezier-utils.h" float DeltaX = 1.1; bool Overlap = false; bool Wirep = true; bool ShowControlPointsp = true; bool cullfacep = false; bool Texturep = false; /* ================================================================================ Some control-point arrays for Bezier patches. U varies fastest, then V. */ GLfloat control_pointsA[2*2*3] = { // V=0 row of 2 points along U -1, -1, 0, // SW point +1, -1, 0, // SE // V=2 row of 2 points along U -1, +1, 0, // NW +1, +1, 0, // NE }; GLfloat control_pointsB[3*3*3] = { // V=0 row of 2 points along U -1, -1, 0, // SW point 0, -1, 1, // S +1, -1, 0, // SE // V=1 row of 2 points along U -1, 0, 1, // W 0, 0, 2, // middle, pulled forward +1, 0, 1, // E // V=2 row of 2 points along U -1, +1, 0, // NW 0, +1, 1, // N +1, +1, 0, // NE }; void display(void) { twError(); twDisplayInit(); twCamera(); if(cullfacep) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); GLfloat lightpos[4] = { 1, 1, 1, 0 }; twGrayLight(GL_LIGHT0,lightpos, 0.1, 0.8, 0.5 ); // All surfaces are the same color twTriple cyan = { 0, 1, 1 }; twColor(cyan,0.7,1); twError(); // ================================ the central sphere glutSolidSphere(0.5,16,16); // ================================ upper right is just a normal quad glPushMatrix(); glTranslatef(DeltaX,DeltaX,0); // Counter-clockwise from SW glBegin(GL_QUADS); { glNormal3f(0,0,1); glVertex3fv(control_pointsA); // SW glVertex3fv(control_pointsA+3); // SE glVertex3fv(control_pointsA+9); // NE glVertex3fv(control_pointsA+6); // NE } glEnd(); twError(); glPopMatrix(); // ================================ upper left is a linear bezier glPushMatrix(); glTranslatef(-DeltaX,DeltaX,0); if(ShowControlPointsp) { drawBezierSurfaceControlPoints(2,3,2,2*3,control_pointsA); } glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); drawBezierSurface(Wirep ? GL_LINE : GL_FILL, 2, 1, 2, 1, control_pointsA); glPopMatrix(); // ================================ lower left is a quadratic bezier glPushMatrix(); glTranslatef(-DeltaX,-DeltaX,0); if(ShowControlPointsp) { drawBezierSurfaceControlPoints(3,3,3,3*3,control_pointsB); } glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); drawBezierSurface(Wirep ? GL_LINE : GL_FILL, 3, 8, 3, 8, control_pointsB); glPopMatrix(); // ================================ lower right is a textured linear bezier glPushMatrix(); glTranslatef(+DeltaX,-DeltaX,0); if(ShowControlPointsp) { drawBezierSurfaceControlPoints(2,3,2,2*3,control_pointsA); } glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glEnable(GL_TEXTURE_2D); GLfloat tcp[2*2*2] = { 0, 1, // SW 1, 1, // SE 0, 0, // NW 1, 0 }; // NE glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); // drawBezierSurface(GL_FILL, 2, 1, 2, 1, control_pointsA); drawBezierSurfaceTextured(GL_FILL, 2, 4, 2, 4, control_pointsA, tcp); glDisable(GL_TEXTURE_2D); glPopMatrix(); // ================================ done glFlush(); glutSwapBuffers(); } float animationSpeed = 0.01; void decreaseDelta() { DeltaX -= animationSpeed; if(DeltaX <= 0) { DeltaX = 0; glutIdleFunc(NULL); } glutPostRedisplay(); } void increaseDelta() { DeltaX += animationSpeed; if(DeltaX >= 1.1) { DeltaX = 1.1; glutIdleFunc(NULL); } glutPostRedisplay(); } void toggles(unsigned char key, int x, int y) { switch(key) { case 'w': Wirep = !Wirep; break; case 'c': ShowControlPointsp = !ShowControlPointsp; break; case 'f': cullfacep = !cullfacep; break; case 't': Texturep = !Texturep; break; case 'o': Overlap = !Overlap; if(Overlap) { glutIdleFunc(decreaseDelta); } else { glutIdleFunc(increaseDelta); } } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500,500); glutCreateWindow(argv[0]); twError(); glutDisplayFunc(display); twError(); twUSflag(); const int BB = 2; twBoundingBox(-BB,+BB, -BB,+BB, -BB,BB); twMainInit(); twKeyCallback('w',toggles,"toggle wireframe"); twKeyCallback('c',toggles,"toggle showing control points"); twKeyCallback('t',toggles,"toggle texturing"); twKeyCallback('o',toggles,"toggle overlap"); twKeyCallback('f',toggles,"toggle cull_face"); printBezierSurfaceControlPoints(2,3,2,3*2,control_pointsA); glutMainLoop(); return 0; }