/** * A viewer for the polyhedral models defined in Polyhedron.java. * The user can select the model and can control some aspects of the * display. If a model does not already have colors for its faces, * then random colors are assigned. The user can drag the polyhedron * to rotate the view. * * This program must be linked to polyhedron.c and camera.c in addtion * to the OpenGL libraries GL, GLU, and glut and the math librarym. * For example, on Linux with the gcc compiler: * * gcc -o polyview ifs-polyhedron-viewer.c polyhedron.c camera.c -lGL -lglut -lGLU -lm */ #include #include #include #include "polyhedron.h" #include "camera.h" // ------------- drawing functions for this program ------------------------- Polyhedron currentModel; int orthographic = 0; int drawFaces = 1; int drawEdges = 1; int colored = 1; double* randomColorArray(length) { double* colors = malloc(3*length*sizeof(double)); int i; for (i = 0; i < length*3; i++) { colors[i] = (double)rand()/RAND_MAX; } return colors; } // ---------------------------------------------------------------------- void display() { // called when the display needs to be drawn glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (!currentModel.faceColors) { currentModel.faceColors = randomColorArray(currentModel.faceCount); } cameraSetOrthographic(orthographic); cameraApply(); glPushMatrix(); double scale = 1/currentModel.maxVertexLength; glScaled(scale,scale,scale); int i,j; if (drawFaces) { if (drawEdges) { glEnable(GL_POLYGON_OFFSET_FILL); } glColor3f(1,1,1); // in case colored is false j = 0; for (i = 0; i < currentModel.faceCount; i++) { if (colored) { glColor3dv( ¤tModel.faceColors[3*i] ); } glBegin(GL_TRIANGLE_FAN); while (currentModel.faces[j] != -1) { int vertexNum = currentModel.faces[j]; glVertex3dv( ¤tModel.vertices[vertexNum*3] ); j++; } j++; glEnd(); } glDisable(GL_POLYGON_OFFSET_FILL); } if (drawEdges) { if (drawFaces) { glColor3f(0,0,0); } else { glColor3f(1,1,1); } j = 0; for (i = 0; i < currentModel.faceCount; i++) { glBegin(GL_LINE_STRIP); while (currentModel.faces[j] != -1) { int vertexNum = currentModel.faces[j]; glVertex3dv( ¤tModel.vertices[vertexNum*3] ); j++; } j++; glEnd(); } } glPopMatrix(); glutSwapBuffers(); } void initGL() { // called by main() to do initialization for this program. glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 1); glLineWidth(2); glPolygonOffset(1,2); cameraLookAt(2,2,6, 0,0,0, 0,1,0); cameraSetScale(1.2); createPolyhedra(); currentModel = stellatedDodecahedron; srand(time(0)); } // ------------------------- Menu handling -------------------------- void doProjectionMenu(int id) { orthographic = id; glutPostRedisplay(); } void doRenderMenu(int id) { if (id == 0 || id == 2) { drawFaces = 1; } else { drawFaces = 0; } if (id == 1 || id == 2) { drawEdges = 1; } else { drawEdges = 0; } glutPostRedisplay(); } void doColoredMenu(int id) { colored = id; glutPostRedisplay(); } void doModelMenu(int id) { switch (id) { case 0: currentModel = house; break; case 1: currentModel = cube; break; case 2: currentModel = dodecahedron; break; case 3: currentModel = icosahedron; break; case 4: currentModel = octahedron; break; case 5: currentModel = rhombicDodecahedron; break; case 6: currentModel = socerBall; break; case 7: currentModel = stellatedDodecahedron; break; case 8: currentModel = stellatedIcosahedron; break; case 9: currentModel = stellatedOctahedron; break; case 10: currentModel = tetrahedron; break; case 11: currentModel = truncatedIcosahedron; break; case 12: currentModel = truncatedRhombicDodecahedron; break; } glutPostRedisplay(); } void createMenus() { int proj = glutCreateMenu(doProjectionMenu); glutAddMenuEntry("Perspective",0); glutAddMenuEntry("Orthographic",1); int rend = glutCreateMenu(doRenderMenu); glutAddMenuEntry("Show Faces",0); glutAddMenuEntry("Show Edges",1); glutAddMenuEntry("Show Both",2); int colr = glutCreateMenu(doColoredMenu); glutAddMenuEntry("Colored Faces",1); glutAddMenuEntry("White Faces",0); int menu = glutCreateMenu(doModelMenu); glutAddMenuEntry("House", 0); glutAddMenuEntry("Cube", 1); glutAddMenuEntry("Dodecahedron", 2); glutAddMenuEntry("Icosahedron", 3); glutAddMenuEntry("Octahedron", 4); glutAddMenuEntry("Rhombic Dodecahedron", 5); glutAddMenuEntry("Socer Ball", 6); glutAddMenuEntry("Stellated Dodecahedron", 7); glutAddMenuEntry("Stellated Icosahedron", 8); glutAddMenuEntry("Stellated Octahedron", 9); glutAddMenuEntry("Tetrahedron", 10); glutAddMenuEntry("Truncated Icosahedron", 11); glutAddMenuEntry("Truncated Rhombic Dodecahedron", 12); glutAddSubMenu("Rendering", rend); glutAddSubMenu("Face Color", colr); glutAddSubMenu("Projection", proj); glutAttachMenu(GLUT_RIGHT_BUTTON); } // ------------------------------------------------------------------ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(500,500); glutInitWindowPosition(100,100); glutCreateWindow("Rotate = LEFT MOUSE; Menu = RIGHT MOUSE"); initGL(); createMenus(); glutMouseFunc(trackballMouseFunction); glutMotionFunc(trackballMotionFunction); glutDisplayFunc(display); glutMainLoop(); return 0; }