/* Simple demo of a 2D surface in a 3D world, where the surface is defined by Bezier curves. This gives a wire-frame look at a flag on a flagpole. Scott D. Anderson Fall 2000 original version Fall 2003 adapted to use TW */ #include GLfloat flag[16][3] = { {0.0, 0.0, 0.0}, /* ll corner */ {0.1, 0.2, 0.0}, /* ll edge */ {0.1, 0.8, 0.0}, /* ul edge */ {0.0, 1.0, 0.0}, /* ul corner */ {0.2, 0.1, 0.2}, /* ll edge, curving forward */ {0.2, 0.2, 0.2}, /* ll interior corner */ {0.2, 0.8, 0.1}, /* ul interior corner */ {0.2, 0.9, 0.1}, /* top left edge */ {0.8, 0.2, -0.2}, /* lr edge, curving forward from behind */ {0.8, 0.2, -0.1}, /* lr interior corner */ {0.7, 0.8, -0.1}, /* ur interior corner */ {0.7, 0.9, 0.0}, /* ur edge */ {0.9, 0.3, 0.0}, /* lr corner */ {0.8, 0.4, -0.1}, /* lr edge */ {0.8, 0.8, 0.0}, /* ur edge */ {0.9, 0.9, -0.1} /* ur corner */ }; bool wire=true; /* whether to use wire or fill */ // This draws the whole surface, using a mesh with `nsteps' in each direction void draw_bezier_surface(int nsteps, GLfloat* control_points) { glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, control_points); glEnable(GL_MAP2_VERTEX_3); // set up grid and generate the desired surface glMapGrid2f(nsteps, 0.0, 1.0, nsteps, 0.0, 1.0); if(wire) glEvalMesh2(GL_LINE, 0, nsteps, 0, nsteps); else glEvalMesh2(GL_FILL, 0, nsteps, 0, nsteps); } // Draws a flagpole of height 10 at the origin, using the current color void draw_flag() { int nsteps=8; // draw flagpole glLineWidth(5); /* pole is this many pixels wide */ glBegin(GL_LINES); { glVertex3f(0,0,0); glVertex3f(0,10,0); } glEnd(); // draw flag glLineWidth(1); /* flag lines are 1 pixel wide */ glPushMatrix(); glTranslatef(0,5,0); glScalef(5,5,5); draw_bezier_surface(8,flag[0]); glPopMatrix(); // knob at the top. The radius of this is a guess. Should correspond // to 5 pixels. glPushMatrix(); glTranslatef(0,10,0); glutSolidSphere(0.4,10,10); glPopMatrix(); } void toggleWire(unsigned char k, int x, int y) { wire = !wire; glutPostRedisplay(); } void display() { twDisplayInit(); twCamera(); glPushAttrib(GL_ALL_ATTRIB_BITS); glColor3f(1,1,1); /* draw in white */ draw_flag(); glPopAttrib(); glFlush(); glutSwapBuffers(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); glutDisplayFunc(display); twBoundingBox(0,5,0,10,-1,1); twMainInit(); twKeyCallback('w',toggleWire,"toggle wireframe flag"); glutMainLoop(); }