/* Example 2.5.cone: draw a cone by subdivision */ // by Jim X. Chen; September, 2000 #include #include #include #include #define ESC 27 #define SPACE 32 int Height=400, Width=400; int depth=5, circleRadius=200, cnt=1; static float vdata[4][3] = { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0} }; void normalize(float v[3]) { float d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); if (d == 0) { printf("zero length vector"); return; } v[0] /= d; v[1] /= d; v[2] /= d; } void drawtriangle(float *v1, float *v2, float *v3) { glBegin(GL_TRIANGLES); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); glEnd(); } void subdivideCone(float *v1, float *v2, int depth) { float v0[3] = {0, 0, 0}, v12[3]; int i; if (depth == 0) { glColor3f(v1[0]*v1[0], v1[1]*v1[1], v1[2]*v1[2]); drawtriangle(v1, v2, v0); // bottom cover of the cone v0[2] = 1; // height of the cone, the tip on z axis drawtriangle(v1, v2, v0); // side cover of the cone return; } for (i=0; i<3; i++) v12[i] = v1[i]+v2[i]; normalize(v12); subdivideCone(v1, v12, depth - 1); subdivideCone(v12, v2, depth - 1); } void drawCone(void) // draw a unit cone with center at the origin and bottom in xy plane { subdivideCone(vdata[0], vdata[1], depth); subdivideCone(vdata[1], vdata[2], depth); subdivideCone(vdata[2], vdata[3], depth); subdivideCone(vdata[3], vdata[0], depth); } void display(void) { if (circleRadius>Width/2 || circleRadius==1) { cnt=-cnt; depth++; depth = depth % 5; } circleRadius+=cnt; // clear both framebuffer and zbuffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glRotatef(1.1, 1, 0, 0); // rotate 1.1 degree alone x axis glPushMatrix(); glScaled(circleRadius, circleRadius, circleRadius); drawCone(); glPopMatrix(); glutSwapBuffers(); } static void Reshape(int w, int h) { glClearColor (0.0, 0.0, 0.0, 1.0); // enable zbuffer (depthbuffer) for hidden-surface removal glEnable(GL_DEPTH_TEST); Width = w; Height = h; glViewport (0, 0, Width, Height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); // make sure the cone is within the viewing volume glOrtho(-Width/2, Width/2, -Height/2, Height/2, -Width/2, Width/2); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); } static void Key(unsigned char key, int x, int y) { switch (key) { case ESC: exit(0); case SPACE: glutIdleFunc(NULL); display(); break; default: glutIdleFunc(display); } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(Width, Height); glutCreateWindow("Example 2.5.cone.c: press SPACE & another key"); glutKeyboardFunc(Key); glutReshapeFunc(Reshape); glutDisplayFunc(display); glutIdleFunc(display); glutMainLoop(); }