// Peter Bui // CSE 40166 Computer Graphics (Fall 2010) // Example 14: geometric object demo #include #include #include #ifdef __APPLE__ #include #else #include #endif using namespace std; // Constants ------------------------------------------------------------------- #define WHEEL_UP 3 #define WHEEL_DOWN 4 #define CAMERA_DISTANCE_MIN 1.0 #define CAMERA_DISTANCE_MAX 100.0 enum { GEO_SPHERE, GEO_CUBE, GEO_CONE, GEO_TORUS, /* GEO_DODECAHEDRON, GEO_OCTAHEDRON, GEO_TETRAHEDRON, GEO_ICOSAHEDRON, GEO_TEAPOT, */ GEO_CYLINDER, GEO_DISK, GEO_PARTIAL_DISK, GEO_MAX }; // Global variables ------------------------------------------------------------ static size_t WindowWidth = 640; static size_t WindowHeight = 480; static GLint MouseX = 0; static GLint MouseY = 0; static double CameraLatitude = 45.0; static double CameraLongitude = 25.0; static double CameraDistance = 50.0; static double EyeX = -100.0; static double EyeY = 50.0; static double EyeZ = 100.0; static int GeoMode = GEO_SPHERE; static double GeoScale = 1.0; static double GeoOrientation = 0.0; static bool GeoWired = false; static GLUquadric *GeoQuadric = NULL; // Update camera --------------------------------------------------------------- void update_camera_location() { double L = CameraDistance * cos(M_PI*CameraLongitude/180.0); EyeX = L * -sin(M_PI*CameraLatitude/180.0); EyeY = CameraDistance * sin(M_PI*CameraLongitude/180.0); EyeZ = L * cos(M_PI*CameraLatitude/180.0); glutPostRedisplay(); } // Initialize scene ------------------------------------------------------------ void init_scene() { glEnable(GL_DEPTH_TEST); glViewport(0, 0, WindowWidth, WindowHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLdouble)WindowWidth/(GLdouble)WindowHeight, 1.0, 750.0); glMatrixMode(GL_MODELVIEW); GLfloat diffuse0[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat ambient0[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat specular0[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat position0[] = { 100.0, 100.0, 100.0, 1.0 }; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0); glLightfv(GL_LIGHT0, GL_SPECULAR, specular0); glLightfv(GL_LIGHT0, GL_POSITION, position0); glEnable(GL_COLOR_MATERIAL) ; glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_NORMALIZE); glEnable(GL_SMOOTH); if (!GeoQuadric) { GeoQuadric = gluNewQuadric(); gluQuadricOrientation(GeoQuadric, GLU_OUTSIDE); gluQuadricNormals(GeoQuadric, GLU_SMOOTH); } update_camera_location(); } // Draw grid ------------------------------------------------------------------- void draw_grid() { glPushMatrix(); glPushAttrib(GL_LIGHTING_BIT); { glDisable(GL_LIGHTING); glColor3f(1.0, 1.0, 1.0); glScalef(5.0, 5.0, 5.0); for(int k = 0; k < 2; k++) { for(int i = -5; i < 6; i++) { glBegin(GL_LINE_STRIP); { for(int j = -5; j < 6; j++) glVertex3f(k == 0 ? i : j, 0, k == 0 ? j : i); } glEnd(); } } } glPopAttrib(); glPopMatrix(); } // Display callback ------------------------------------------------------------ void display() { //GLfloat position0[] = { EyeX, EyeY, EyeZ, 1.0 }; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(EyeX, EyeY, EyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); draw_grid(); glPushMatrix(); glRotatef(GeoOrientation, 0.0, 1.0, 0.0); glScalef(GeoScale, GeoScale, GeoScale); glColor3f(1.0, 0.0, 0.0); gluQuadricDrawStyle(GeoQuadric, (GeoWired ? GLU_LINE : GLU_FILL)); switch (GeoMode) { case GEO_SPHERE: if (GeoWired) glutWireSphere(1.0, 24, 24); else glutSolidSphere(1.0, 24, 24); break; case GEO_CUBE: if (GeoWired) glutWireCube(2.0); else glutSolidCube(2.0); break; case GEO_CONE: if (GeoWired) glutWireCone(1.0, 1.0, 24, 24); else glutSolidCone(1.0, 1.0, 24, 24); break; case GEO_TORUS: if (GeoWired) glutWireTorus(0.5, 1.0, 24, 24); else glutSolidTorus(0.5, 1.0, 24, 24); break; case GEO_CYLINDER: gluCylinder(GeoQuadric, 1.0, 1.0, 2.0, 24, 24); break; case GEO_DISK: gluDisk(GeoQuadric, 0.5, 1.0, 24, 24); break; case GEO_PARTIAL_DISK: gluPartialDisk(GeoQuadric, 0.5, 1.0, 24, 24, 0.0, 180.0); break; } glPopMatrix(); glutSwapBuffers(); } // Reshape callback ------------------------------------------------------------ void reshape(GLsizei nw, GLsizei nh) { WindowWidth = nw; WindowHeight = nh; init_scene(); } // Keyboard callback ----------------------------------------------------------- void keyboard(unsigned char key, int x, int y) { switch (key) { case 'q': case 'Q': exit(EXIT_SUCCESS); break; case 'w': GeoWired = !GeoWired; break; } glutPostRedisplay(); } // Special callback ----------------------------------------------------------- void special(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: GeoOrientation -= 1.0; break; case GLUT_KEY_RIGHT: GeoOrientation += 1.0; break; case GLUT_KEY_UP: GeoScale += 1.0; break; case GLUT_KEY_DOWN: GeoScale -= 1.0; break; case GLUT_KEY_F1: GeoMode = GEO_SPHERE; break; case GLUT_KEY_F2: GeoMode = GEO_CUBE; break; case GLUT_KEY_F3: GeoMode = GEO_CONE; break; case GLUT_KEY_F4: GeoMode = GEO_TORUS; break; case GLUT_KEY_F5: GeoMode = GEO_CYLINDER; break; case GLUT_KEY_F6: GeoMode = GEO_DISK; break; case GLUT_KEY_F7: GeoMode = GEO_PARTIAL_DISK; break; } glutPostRedisplay(); } // Mouse callback -------------------------------------------------------------- void mouse(int button, int state, int x, int y) { MouseX = x; MouseY = y; switch (button) { case WHEEL_UP: CameraDistance = (CameraDistance > CAMERA_DISTANCE_MIN ? CameraDistance - 1.0 : CAMERA_DISTANCE_MIN); break; case WHEEL_DOWN: CameraDistance = (CameraDistance < CAMERA_DISTANCE_MAX ? CameraDistance + 1.0 : CAMERA_DISTANCE_MAX); break; } update_camera_location(); } // Motion callback ------------------------------------------------------------- void motion(int x, int y) { CameraLatitude += 180.0*(double)(x - MouseX)/WindowWidth; CameraLongitude += 180.0*(double)(y - MouseY)/WindowHeight; update_camera_location(); MouseX = x; MouseY = y; } // Main execution -------------------------------------------------------------- int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow("geodemo"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutMouseFunc(mouse); glutMotionFunc(motion); init_scene(); glutMainLoop(); return (EXIT_SUCCESS); } // vim: sts=4 sw=4 ts=8 ft=cpp