/* A 2D Bezier surface, with 2x3 control points. 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 Texturep = false; /* ================================================================================ Some control-point arrays for Bezier patches. All of them are flat (all Z components are zero), and symmetrical across both X and Y. The corners form an 2x2 square. U varies fastest, then V. */ GLfloat control_points2x3[2*3*3] = { // V=0 row of 2 points along U -1, -1, 0, // SE point 0, -1, 0, // S // V=1 row of 2 points along U -1, 0, 0, // W +1, 0, 0, // E // V=2 row of 2 points along U 0, +1, 0, // N +1, +1,0, // NE }; // These are the *same* points, but rearranged to be 3x2 GLfloat control_points3x2[3*2*3] = { // V=0 row of 3 points along U -1, -1, 0, // SE 0, -1, 0, // S +1, 0, 0, // E // V=1 row of 3 points along U -1, 0, 0, // W 0, +1, 0, // N +1, +1, 0, // NE }; /* This function assumes that the elements are all triples */ void drawExamplePatch(int u_order, int u_steps, int v_order, int v_steps, GLfloat* cp) { } void display(void) { twError(); twDisplayInit(); twCamera(); const int small_steps = 1; const int elt_stride = 3; int u_order, u_stride, u_steps, v_order, v_stride, v_steps; // Draw the one on the left, which is 2x3 and cyan u_order =2; u_stride =elt_stride; u_steps = 1; v_order =3; v_stride =u_order*u_stride; v_steps =4; glPushMatrix(); glTranslatef(-DeltaX,0,0); glColor3f(0,1,1); // cyan patch if(ShowControlPointsp) { drawBezierSurfaceControlPoints(u_order,u_stride,v_order,v_stride,control_points2x3); } drawBezierSurface(Wirep ? GL_LINE : GL_FILL, u_order, u_steps, v_order, v_steps, control_points2x3); glPopMatrix(); // Draw the one on the right, which is 3x2 and magenta u_order =3; u_stride =elt_stride; u_steps = 4; v_order =2; v_stride =u_order*u_stride; v_steps =1; glPushMatrix(); glTranslatef(DeltaX,0,0); glColor3f(1,0,1); // magenta patch if(ShowControlPointsp) { drawBezierSurfaceControlPoints(u_order,u_stride,v_order,v_stride,control_points3x2); } drawBezierSurface(Wirep ? GL_LINE : GL_FILL, u_order, u_steps, v_order, v_steps, control_points3x2); glPopMatrix(); 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 '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(); twBoundingBox(-1,+1, -1,+1, -1,1); twMainInit(); twKeyCallback('w',toggles,"toggle wireframe"); twKeyCallback('c',toggles,"toggle showing control points"); twKeyCallback('t',toggles,"toggle texturing"); twKeyCallback('o',toggles,"toggle overlap"); printBezierSurfaceControlPoints(2,3,3,3*2,control_points2x3); printBezierSurfaceControlPoints(3,3,2,3*3,control_points3x2); glutMainLoop(); return 0; }