/* File: glutdemo3d.cpp Author: J.K. Johnstone Created: 5 January 2004 (from WEviewer.cpp) Last Modified: 5 January 2004 Purpose: A demo program for 3d OpenGL/GLUT. Input: None. History: */ #include #include #include #include #include #include #include #include using std::string; #include #define WINDOWS 0 static char *RoutineName; static void usage() { cout << "Usage is " << RoutineName << endl; cout << "\t[-x xrotation]" << endl; cout << "\t[-y yrotation]" << endl; cout << "\t[-z zrotation]" << endl; cout << "\t[-l] (laptop)" << endl; cout << "\t[-h] (this help message)" << endl; } static GLfloat transxob, transyob, rotxob, rotyob, rotzob, zoomob; static int panLeft=0, panRight=1; // control panning for 3d effect static GLboolean leftMouseDown=0; static GLboolean middleMouseDown=0; static GLboolean firstx=1,firsty=1; // first MOUSEX (MOUSEY) reading? static int oldx,oldy; // previous value of MOUSEX and MOUSEY static GLboolean ROTATEOB=0; // rotate mesh? static GLboolean PANOB=0; // rotate mesh back and forth for 3d effect? static GLboolean WIRE=0; // draw mesh in wireframe? static GLboolean LAPTOP=0; // display environment for laptop? double tetra[4][3] = {{0,0,0},{1,0,0},{0,1,0},{0,0,1}}; int win; // window identifier /******************************************************************************/ /******************************************************************************/ void gfxinit(void) { GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0}; GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; GLfloat position[] = {0.0, 3.0, 3.0, 0.0}; GLfloat lmodel_ambient[] = {0.2, 0.2, 0.2, 1.0}; GLfloat local_view[] = {0.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); glFrontFace(GL_CW); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClearColor (1.0, 1.0, 1.0, 1.0); glEnable (GL_POINT_SMOOTH); glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST); glPointSize (3.0); transxob = transyob = 0.0; zoomob = 1.8; } /******************************************************************************/ /******************************************************************************/ void reshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2.0*(GLfloat)w/(GLfloat)h, 2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0, -1000.,1000.); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /******************************************************************************/ /******************************************************************************/ void RotateOb (void) { rotzob += 1.0; if (rotzob > 360.0) rotzob -= 360.0; glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void PanOb (void) { if (panLeft) { rotzob += 1.0; if (rotzob > 360.0) rotzob -= 360.0; panLeft++; if (panLeft==30) { panLeft=0; panRight=1; } } else if (panRight) { rotzob -= 1.0; if (rotzob < 0.0) rotzob += 360.0; panRight++; if (panRight==30) { panRight=0; panLeft=1; } } glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void visibility (int status) { if (status != GLUT_VISIBLE) glutIdleFunc (NULL); else if (ROTATEOB) glutIdleFunc (RotateOb); else if (PANOB) glutIdleFunc (PanOb); } /******************************************************************************/ /******************************************************************************/ void mouse (int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: switch (state) { case GLUT_DOWN: leftMouseDown = firstx = firsty = 1; glutSetCursor (GLUT_CURSOR_UP_DOWN); break; case GLUT_UP: leftMouseDown = 0; glutSetCursor (GLUT_CURSOR_INHERIT); break; default: break; } break; case GLUT_MIDDLE_BUTTON: switch (state) { case GLUT_DOWN: middleMouseDown = firstx = firsty = 1; glutSetCursor (GLUT_CURSOR_CYCLE); break; case GLUT_UP: middleMouseDown = 0; glutSetCursor (GLUT_CURSOR_INHERIT); break; default: break; } break; default: break; } } /******************************************************************************/ /******************************************************************************/ void motionob (int x, int y) { if (WINDOWS || LAPTOP) { if (!leftMouseDown && middleMouseDown) { if (firstx) firstx=0; else zoomob -= (float).01*(x-oldx); if (zoomob < 0.0) zoomob = 0.0; } else if (leftMouseDown && middleMouseDown) { if (firstx) firstx=0; else transxob += .01*(x-oldx); /* TRANSLATION: X */ if (firsty) firsty=0; else transyob += .01*(y-oldy); /* TRANSLATION: Y */ } else if (leftMouseDown && !middleMouseDown) { if (firstx) firstx=0; else { rotyob += .5*(x-oldx); if (rotyob > 360.0) rotyob -= 360.0; } /* ORI: Y */ if (firsty) firsty=0; else { rotxob += .5*(y-oldy); if (rotxob > 360.0) rotxob -= 360.0; } /* ORI: X */ } } else { if (leftMouseDown && !middleMouseDown) { if (firstx) firstx=0; else zoomob -= (float).01*(x-oldx); if (zoomob < 0.0) zoomob = 0.0; } else if (leftMouseDown && middleMouseDown) { if (firstx) firstx=0; else transxob += .01*(x-oldx); /* TRANSLATION: X */ if (firsty) firsty=0; else transyob += .01*(y-oldy); /* TRANSLATION: Y */ } else if (middleMouseDown) { if (firstx) firstx=0; else { rotyob += .5*(x-oldx); if (rotyob > 360.0) rotyob -= 360.0; } /* ORI: Y */ if (firsty) firsty=0; else { rotxob += .5*(y-oldy); if (rotxob > 360.0) rotxob -= 360.0; } /* ORI: X */ } } oldx = x; oldy = y; glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void keyboard (unsigned char key, int x, int y) { switch (key) { case 27: exit(1); break; // ESCAPE case 'w': WIRE = !WIRE; break; // wireframe default: break; } glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void menuOb (int value) { switch (value) { case 0: WIRE = !WIRE; break; default: break; } glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void displayOb () { int i,j; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef (transxob, transyob, 0); glScalef (zoomob, zoomob, zoomob); glRotatef (rotxob, 1.0, 0.0, 0.0); glRotatef (rotyob, 0.0, 1.0, 0.0); glRotatef (rotzob, 0.0, 0.0, 1.0); if (WIRE) { glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glDisable (GL_LIGHTING); glColor3f (0,0,1); // blue glBegin (GL_TRIANGLES); glVertex3dv (tetra[0]); glVertex3dv (tetra[1]); glVertex3dv (tetra[2]); glVertex3dv (tetra[0]); glVertex3dv (tetra[2]); glVertex3dv (tetra[3]); glVertex3dv (tetra[0]); glVertex3dv (tetra[3]); glVertex3dv (tetra[1]); glEnd (); glEnable (GL_LIGHTING); } else { glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glBegin (GL_TRIANGLES); glNormal3f (0,0,-1); glVertex3dv (tetra[0]); glVertex3dv (tetra[1]); glVertex3dv (tetra[2]); glNormal3f (-1,0,0); glVertex3dv (tetra[0]); glVertex3dv (tetra[2]); glVertex3dv (tetra[3]); glNormal3f (0,-1,0); glVertex3dv (tetra[0]); glVertex3dv (tetra[3]); glVertex3dv (tetra[1]); glNormal3f (1/sqrt(3),1/sqrt(3),1/sqrt(3)); glVertex3dv (tetra[1]); glVertex3dv (tetra[2]); glVertex3dv (tetra[3]); glEnd (); glEnable (GL_LIGHTING); } glPopMatrix(); glutSwapBuffers (); } /****************************************************************************** ******************************************************************************/ void special (int key, int x, int y) { switch(key) { case (GLUT_KEY_UP): rotxob += 10; break; case (GLUT_KEY_DOWN): rotxob -= 10; break; case (GLUT_KEY_LEFT): rotyob += 10; break; case (GLUT_KEY_RIGHT): rotyob -= 10; break; default: break; } glutPostRedisplay(); } /****************************************************************************** ******************************************************************************/ int main (int argc, char **argv) { int ArgsParsed=0; RoutineName = argv[ArgsParsed++]; while (ArgsParsed < argc) { if ('-' == argv[ArgsParsed][0]) switch (argv[ArgsParsed++][1]) { case 'x': rotxob = atof(argv[ArgsParsed++]); break; case 'y': rotyob = atof(argv[ArgsParsed++]); break; case 'z': rotzob = atof(argv[ArgsParsed++]); break; case 'l': LAPTOP = 1; break; case 'h': default : usage(); exit(-1); break; } else ArgsParsed++; } /************************************************************/ glutInit (&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); int titleht; // top titlebar if (LAPTOP) titleht = 0; else titleht = 20; int xleft = 0; int xsize=600, ysize=600; glutInitWindowPosition (xleft,titleht); glutInitWindowSize (xsize,ysize); char titlebar[100]; strcpy (titlebar, "Demo 3d OpenGL/GLUT program"); win = glutCreateWindow (titlebar); glutDisplayFunc (displayOb); glutKeyboardFunc (keyboard); glutSpecialFunc (special); glutMouseFunc (mouse); glutMotionFunc (motionob); glutVisibilityFunc (visibility); glutReshapeFunc (reshape); gfxinit(); glutCreateMenu (menuOb); glutAddMenuEntry ("Shaded/wireframe [w]", 0); glutAttachMenu (GLUT_RIGHT_BUTTON); glutMainLoop(); return 0; }