home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Silicon Graphics, Inc. 1996 */
-
- /*
- * fly.c
- * This program allows the user to "fly" through a simple virtual world.
- *
- * Your challenge - make an even cooler fly!
- *
- * Utility routines are located in flyutil.c
- *
- * MODIFYING THE PROGRAM
- * ---------------------
- * New shapes should be added to the world in the routine drawShapes().
- *
- * If new shapes are to be on the path of the autopilot, they must be
- * near a circle centered at the world origin with a radius of 10.0,
- * parallel to and raised above the 'floor,' the X-Z plane.
- *
- * As a starting point, here are some good places to center your objects:
- * ( 0.0, 1.0, 10.0 )
- * ( 7.0, 1.0, 7.0 )
- * ( 10.0, 1.0, 0.0 )
- * ( 7.0, 1.0, -7.0 )
- * ( 0.0, 1.0, -10.0)
- * ( -7.0, 1.0, -7.0)
- * ( -10.0, 1.0, 0.0)
- * ( -7.0, 1.0, 7.0 )
- *
- * INPUT CONTROLS:
- *
- * <?> key - help, prints this info
- * <a> key - <a>utopilot start/stop
- * <b> key - <b>lend, alpha blending
- * <d> key - toggle <d>ebugging printfs
- * <g> key - show floor <g>rid
- * <n> key - <n>ormals drawing toggle
- * <r> key - <r>eset eye position
- * SPACE key - cycle wireframe/flat shaded/smooth
- * LEFT Mouse - control moving the eye forward
- * MIDDLE Mouse - control moving the eye backward
- * Mouse pointer - change direction: pull back to go up, forward to dive
- * Escape key - exit the program
- *
- * Copyright 1991, 1992, 1993, 1994, 1995, 1996, Silicon Graphics, Inc.
- * Technical Education Development
- */
-
-
- /* fly.h contains function prototypes, and defines constants */
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glut.h>
-
- #include "fly.h"
-
- /* Global Variables */
-
- static enum shapes { FLOOR, TETRA, CUBE, OCTA, DODECA, ICOSA, CONE, FLAG,
- CYLINDER, SPHERE, TORUS, QUAD, FONT };
- static enum drawModes { WIREFRAME, SOLID, SIMPLE };
-
- enum drawStyles { LIT_SMOOTH, LIT_FLAT, WIRE };
-
- extern GLboolean debugFlag; /* print eye position info? */
- extern GLboolean lighting;
- extern GLboolean showGridFlag;
- extern GLboolean blendFlag;
-
- extern GLint drawStyle;
- extern GLfloat ex, ey, ez; /* eye position */
- extern GLfloat yaw; /* eye rotation about y axis in degrees */
- extern GLfloat pitch; /* eye rotation about x axis in degrees */
- extern GLfloat velocity; /* eye velocity */
-
- extern GLdouble znear, zfar; /* z distance to near and far planes */
-
- static GLuint outlineFont, filledFont;
-
- #define STRING1 "Welcome to OpenGL"
- #define STRING2 "Programming 2!"
-
- GLvoid
- main( int argc, char *argv[] )
- {
- GLdouble aspect;
- GLsizei width, height;
-
- glutInit( &argc, argv );
-
- width = glutGet(GLUT_SCREEN_WIDTH);
- height = glutGet(GLUT_SCREEN_HEIGHT);
- glutInitWindowPosition( width / 4, height / 4 );
- glutInitWindowSize( width / 2, height / 2 );
- glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
- glutCreateWindow( argv[0] );
-
- initgfx();
-
- glutIdleFunc( animate );
- glutVisibilityFunc( visibility );
- glutKeyboardFunc( keyboard );
- glutSpecialFunc( specialkeys );
- glutMouseFunc( mouse );
- glutMotionFunc( motion );
- glutReshapeFunc( reshape );
- glutDisplayFunc( drawScene );
-
- printHelp( argv[0] );
-
- glutMainLoop();
- }
-
- GLvoid
- printHelp( char *progname )
- {
-
- fprintf(stdout, "\n%s - fly through a simple virtual world.\n",
- progname );
-
- printControls();
- }
-
- GLvoid
- printControls( GLvoid )
- {
- fprintf(stdout, "\n\n"
- "<?> key - help, prints this info \n"
- "<a> key - <a>utopilot start/stop \n"
- "<b> key - <b>lend, alpha blending \n"
- "<d> key - <d>ebug mode, prints coords \n"
- "<g> key - show floor <g>rid \n"
- "<n> key - <n>ormals drawing toggle \n"
- "<r> key - <r>eset eye position \n"
- "SPACE key - cycle wireframe/flat shaded/smooth \n"
- "LEFT Mouse - control moving the eye forward \n"
- "MIDDLE Mouse - control moving the eye backward \n"
- "Mouse pointer - change direction: pull back to go up, forward to dive\n"
- "Escape key - exit the program \n" );
- }
-
- /* Initialize material property, light source, and lighting model,
- */
- GLvoid
- initLighting( GLvoid )
- {
- GLfloat mat_ambient[] = { 0.25, 0.05, 0.4, 1.0 };
- GLfloat mat_diffuse[] = { 0.5, 0.1, 0.8, 1.0 };
-
- /* mat_specular and mat_shininess are NOT default values */
- GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
- GLfloat mat_shininess[] = { 10.0 };
-
- /* light_position is NOT default value */
- GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
-
- /* add code to set the ambient, specular and shininess
- * material properties */
-
-
- glLightfv(GL_LIGHT0, GL_POSITION, light_position);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- }
-
- GLvoid
- initgfx( GLvoid )
- {
- glClearColor( 0.0, 0.0, 0.0, 1.0 );
- glClearDepth( 1.0 );
-
- glClear( GL_COLOR_BUFFER_BIT );
- glutSwapBuffers();
-
- glEnable( GL_DEPTH_TEST );
-
- initLighting();
-
- resetEye();
-
- outlineFont = createOutlineFont();
- filledFont = createFilledFont();
-
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- }
-
- GLvoid
- animate( GLvoid )
- {
- moveEye();
-
- /* Tell GLUT to redraw the scene */
- glutPostRedisplay();
- }
-
- GLvoid
- visibility( int state )
- {
- if (state == GLUT_VISIBLE) {
- glutIdleFunc( animate );
- } else {
- glutIdleFunc( NULL );
- }
- }
-
- /* Initialize the various input functions */
- GLvoid
- keyboard( GLubyte key, GLint x, GLint y )
- {
- /* all of the following routines are in flyutil.c */
- switch (key) {
- case ' ':
- setDrawStyle();
- break;
- case 'a':
- setAutopilot();
- break;
- case 'b':
- toggleBlend();
- break;
- case 'd':
- setDebug();
- break;
- case 'g':
- toggleShowGrid();
- break;
- case 'n':
- toggleDrawNormals();
- break;
- case 'r':
- resetEye();
- break;
- case '?':
- case '/':
- printControls();
- break;
- case KEY_ESC:
- exit(0);
- }
-
- glutPostRedisplay();
- }
-
- GLvoid
- specialkeys( GLint key, GLint x, GLint y )
- {
- switch (key) {
- case GLUT_KEY_UP:
- break;
- case GLUT_KEY_DOWN:
- break;
- }
- glutPostRedisplay();
- }
-
- GLvoid
- mouse( GLint button, GLint state, GLint x, GLint y )
- {
- switch (button) {
- case GLUT_LEFT_BUTTON:
- case GLUT_MIDDLE_BUTTON:
- if (state == GLUT_DOWN)
- startMove(button, x, y);
- else
- stopMove();
- glutPostRedisplay();
- break;
-
- case GLUT_RIGHT_BUTTON:
- break;
- }
- }
-
- GLvoid
- motion( GLint x, GLint y )
- {
- updatePosition( x, y );
- glutPostRedisplay();
- }
-
- GLvoid
- drawScene( GLvoid )
- {
- GLdouble planeABCD[4] = {0.0, -1.0, 0.0, 1.5};
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- glPushMatrix();
-
- /* accomplish a viewing transformation by moving
- * the world relative to the eye
- */
- glRotatef( pitch, 1.0, 0.0, 0.0 );
- glRotatef( yaw, 0.0, 1.0, 0.0 );
- glTranslatef(-ex,-ey,-ez);
-
- if (lighting)
- glEnable(GL_LIGHTING);
- else
- glColor4f( 0.5, 0.5, 0.0, 1.0 );
-
- glPushMatrix();
- computeFloor(); /* function in flyutil.c */
- drawFloor();
- glPopMatrix();
-
- if (!lighting)
- glColor4f(0.5, 0.1, 0.8, 0.3);
-
- drawShapes();
-
- if (lighting)
- glDisable(GL_LIGHTING);
-
- /* draw some 3D text */
- glPushMatrix();
- glTranslatef(-10.1, -2.5, 10.1);
- glScalef(0.1, 0.1, 0.1);
- glColor4f(1.0, 0.7, 0.0, 1.0);
- renderString( filledFont, STRING1 );
- glPopMatrix();
-
- glPushMatrix();
- glRotatef(90, 0, 1, 0);
- glTranslatef(-9.9, -2.5, 10.1);
- glScalef(0.1, 0.1, 0.1);
- glColor4f(0.6, 1, 0.8, 0.6);
- renderString( outlineFont, STRING2 );
- glPopMatrix();
- glPopMatrix();
-
- glutSwapBuffers();
-
- checkError("drawScene");
- }
-
- GLvoid
- drawShapes( GLvoid )
- {
- /* add code to change the diffuse property of
- * one or more shapes; make some of the objects
- * transparent. Use glColorMaterial to make the changes fast.
- */
-
- if ( blendFlag )
- disableBlending();
-
- drawMovedShape( TETRA, -5.0, 1.0, 8.7 );
- drawMovedShape( CUBE, -8.7, 1.0, 0.5 );
- drawMovedShape( OCTA, 5.0, 1.0, 8.7 );
- drawMovedShape( DODECA, -8.7, 1.0, -5.0 );
- drawMovedShape( ICOSA, -5.0,1.0,-8.7 );
- drawMovedShape( CONE, 8.7,1.0,5.0 );
-
- if ( blendFlag && drawStyle != WIRE )
- enableBlending();
-
- drawMovedShape( CYLINDER, 10.0,1.5,0.0 );
- drawMovedShape( SPHERE, 7.0, 2.0, -7.0 );
- drawMovedShape( TORUS, 0.0, 2.0, -10.0 );
-
- if ( blendFlag && drawStyle != WIRE )
- disableBlending();
- }
-
- GLvoid
- drawMovedShape( GLint currentShape, GLfloat x, GLfloat y, GLfloat z )
- {
- glPushMatrix();
- glTranslatef(x, y, z);
- if (drawStyle == WIRE)
- {
- drawShape( currentShape, WIREFRAME );
- }
- else
- {
- drawShape( currentShape, SOLID );
- }
- glPopMatrix();
- }
-
- GLvoid
- drawShape( GLint currentShape, GLint drawMode )
- {
- switch( currentShape )
- {
- case TETRA:
- drawTetra( drawMode );
- break;
- case CUBE:
- drawCube( drawMode );
- break;
- case OCTA:
- drawOcta( drawMode );
- break;
- case DODECA:
- drawDodeca( drawMode );
- break;
- case ICOSA:
- drawIcosa( drawMode );
- break;
- case CONE:
- drawCone( drawMode );
- break;
- case CYLINDER:
- drawCylinder( drawMode );
- break;
- case SPHERE:
- drawSphere( drawMode );
- break;
- case TORUS:
- drawTorus( drawMode );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawTetra( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireTetrahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidTetrahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawCube( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireCube( 1.0 );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidCube( 1.0 );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawOcta( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireOctahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidOctahedron( );
- break;
- default:
- break;
- }
- }
-
-
- GLvoid
- drawDodeca( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireDodecahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidDodecahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawIcosa( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireIcosahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidIcosahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawCone( GLint drawMode )
- {
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireCone( 1.0, 2.0, 8, 15 );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidCone( 1.0, 2.0, 8, 15 );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawCylinder( GLint drawMode )
- {
- glRotatef(90.0, 1.0, 0.0, 0.0);
- switch( drawMode )
- {
- case WIREFRAME:
- WireCylinder( 1.0, 2.0 );
- break;
- case SOLID:
- case SIMPLE:
- SolidCylinder( 1.0, 2.0 );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawSphere( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireSphere( 1.0, 15, 31 );
- break;
- case SOLID:
- glutSolidSphere( 1.0, 15, 31 );
- break;
- case SIMPLE:
- glutSolidIcosahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawTorus( GLint drawMode )
- {
- static GLint spinTorus = 0;
-
- glRotatef( (GLfloat)spinTorus, 0.0, 1.0, 0.0 );
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireTorus( 0.25, 0.75, 15, 31 );
- break;
- case SOLID:
- glutSolidTorus( 0.25, 0.75, 15, 31 );
- break;
- case SIMPLE:
- SolidBox ( 2.0, 2.0, 0.5 );
- break;
- default:
- break;
- }
- spinTorus = ( spinTorus + (int)(20*velocity) ) % 360;
- }
-
- GLvoid
- drawFloor( GLvoid )
- {
- GLfloat gridDiffuse[] = { 0.5, 0.5, 0.0, 1.0 };
- GLfloat surfaceDiffuse[] = { 0.05, 0.15, 1.0, 1.0 };
-
- static GLboolean first_time = GL_TRUE;
- static GLint floor_mat[2];
-
- if ( first_time ) {
- floor_mat[0] = glGenLists(1);
-
- glNewList(floor_mat[0], GL_COMPILE);
- glMaterialfv(GL_FRONT, GL_AMBIENT, surfaceDiffuse);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, surfaceDiffuse);
- glEndList();
-
- floor_mat[1] = glGenLists(1);
-
- glNewList(floor_mat[1], GL_COMPILE);
- glMaterialfv(GL_FRONT, GL_AMBIENT, gridDiffuse);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, gridDiffuse);
- glEndList();
-
- first_time = GL_FALSE;
- }
-
- if ( drawStyle != WIRE ) {
- glCallList(floor_mat[0]);
- drawFloorFilled();
- }
-
- if ( drawStyle == WIRE || showGridFlag == GL_TRUE ) {
- glCallList(floor_mat[1]);
- drawFloorWire();
- }
- }
-
- GLvoid resetEye( GLvoid )
- {
- register int i;
-
- initEye();
- }
-
-