Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

sheet06.cpp

Go to the documentation of this file.
00001 #include <GL/glut.h>
00002 #include <GL/glu.h>
00003 
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <math.h>
00007 
00008 #include "config.h"
00009 #include "torus.h"
00010 #include "texture.h"
00011 #include "math.h"
00012 #include "heightfield.h"
00013 
00014 
00015 
00016 // Example of the projective texturing technique. 
00017 // The grass texture is being projected on the sphere and
00018 //  two walls.
00019 
00020 // Items in popup menu
00021 enum {
00022   MENU_LIGHTING = 1,
00023   MENU_POLYMODE,
00024   MENU_TEXTURING,
00025   MENU_FRAMERATE,
00026   MENU_EXIT
00027 };
00028 
00029 // Time of last call to display timer
00030 static int g_nLastTime = 0;
00031 // Frames per second
00032 static float g_fFPS = 0;
00033 
00034 // Camera data
00035 static float g_nearPlane = 1;
00036 static float g_farPlane = 10;
00037 
00038 static const double VIEWING_DISTANCE_MIN = 1;
00039 float g_fViewDistance = 5*VIEWING_DISTANCE_MIN;
00040 
00041 
00042 // Viewport parameters
00043 static int g_Width = 256;                          // Initial window width
00044 static int g_Height = 256;                         // Initial window height
00045 
00046 // Flags for drawing state
00047 static bool g_bFillPolygons = true;
00048 
00049 
00050 // Rotation
00051 static bool g_bRotateLeft = false;
00052 static bool g_bRotateRight = false;
00053 static bool g_bRotateDown = false;
00054 static bool g_bRotateUp = false;
00055 
00056 // Camera movement
00057 static bool g_bCameraUp = false;
00058 static bool g_bCameraDown = false;
00059 static bool g_bCameraLeft = false;
00060 static bool g_bCameraRight = false;
00061 static float g_fCameraX = 0;
00062 static float g_fCameraY = 0;
00063 
00064 // Current camera position
00065 static float g_eyePoint[4];
00066 
00067 
00068 
00069 /**********************************************
00070  **********************************************
00071    HELPER FUNCTIONS
00072  **********************************************
00073  *********************************************/
00074 
00075 void glutString( char *pstr )
00076 {
00077   while (*pstr!=char(0)) {
00078     glutBitmapCharacter( GLUT_BITMAP_8_BY_13, int( *pstr ));
00079     pstr++;
00080   }
00081 }
00082 
00083 
00084 
00085 
00086 // Just for your reference: This function computes eye position
00087 // in world coordinates (not used after all)
00088 // It has to be called after the complete camera transformation has been set up.
00089 void computeCameraPosition( float *eyePoint )
00090 {
00091   // Projected eye position:
00092   //   In the projection step (gluProject(), the eye position is mapped from (0,0,0) to
00093   //   (0,0, - (n*f) / (f-n)), where n and f are near and far plane.
00094   float eyeProject[4];
00095   eyeProject[0] = 0;
00096   eyeProject[1] = 0;
00097   eyeProject[2] = - (g_nearPlane * g_farPlane) / (g_farPlane - g_nearPlane);
00098   eyeProject[3] = 0;
00099 
00100   // Multiply projected eye position with inverse projection to get
00101   // eye point of the camera in world coordinates
00102   float modelviewT[16];
00103   glGetFloatv( GL_TRANSPOSE_MODELVIEW_MATRIX, modelviewT );
00104   float projectionT[16];
00105   glGetFloatv( GL_TRANSPOSE_PROJECTION_MATRIX, projectionT );
00106 
00107   // Compute inverse matrices
00108   float inverse_projection[16];
00109   float inverse_modelview[16];
00110   Invert<float> (projectionT, inverse_projection);
00111   Invert<float> (modelviewT, inverse_modelview);
00112 
00113   float eyeCamera[4];
00114   Multiply<float> (inverse_projection, eyeProject, eyeCamera );
00115   Multiply<float> (inverse_modelview,  eyeCamera, eyePoint );
00116 }
00117 
00118 
00119 
00120 // This function transforms the (light source) positions into eye coordinates,
00121 // to be called right after setup of camera transformation modelview
00122 void computeLightPosition( const float *lightPosWorld, float *lightPosEye )
00123 {
00124   // Now that the camera transformation is set up, the current modelview
00125   // matrix transforms world coordinates to eye coordinates, and is
00126   // the correct transformation matrix for the light sources
00127   float projection[16];
00128   glGetFloatv( GL_TRANSPOSE_MODELVIEW_MATRIX, projection );
00129   Multiply<float> (projection, lightPosWorld, lightPosEye );
00130 }
00131 
00132 
00133 
00134 /**********************************************
00135  **********************************************
00136    GL INITIALISATION / WINDOW REDRAWING
00137  **********************************************
00138  *********************************************/
00139 
00140 void setupCamera()
00141 {
00142   // Setup projection with field of view of 65 degrees
00143   glMatrixMode(GL_PROJECTION);
00144   glLoadIdentity();
00145   gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
00146 
00147   // Initializa modelview
00148   glMatrixMode(GL_MODELVIEW);
00149   glLoadIdentity();
00150 
00151   // Set up viewing transformation, looking down -Z axis
00152   gluLookAt(0, 0, -g_fViewDistance, 0, 0, -1, 0, 1, 0);
00153 
00154   // Free camera mode
00155   glRotatef( g_fCameraX, 1,0,0 );
00156   glRotatef( g_fCameraY, 0,1,0 );
00157 
00158   // Compute the position of the light source in eye coordinates
00159   computeLightPosition( g_lightPos, g_lightPosEye );
00160 }
00161 
00162 
00163 
00164 void renderScene()
00165 {
00166   if (g_bLighting) {
00167     glEnable(GL_LIGHTING);
00168   }
00169   else {
00170     glDisable(GL_LIGHTING);
00171   }
00172 
00173   // Draw torus
00174   glPushMatrix();
00175 //  glRotatef( g_fTorusX, 0,1,0 );
00176 //  glRotatef( g_fTorusY, 1,0,0 );
00177   drawTorus( g_eyePoint );
00178   glPopMatrix();
00179 
00180 
00181 
00182   // Draw ground
00183   glPushMatrix();
00184   glTranslatef( 0,-5,0 );
00185   glRotatef( -90, 1,0,0 );
00186   drawHeightField( 0,0, (int)g_farPlane, (int)g_farPlane );
00187   glPopMatrix();
00188 }
00189 
00190 
00191 void display()
00192 {
00193   // Clear frame buffer and depth buffer
00194   glClearColor( colorSky[0], colorSky[1], colorSky[2], colorSky[3] );
00195   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00196   
00197   // Setup camera and initialize modelview matrix stack
00198   setupCamera();
00199 glGetFloatv(GL_MODELVIEW_MATRIX, ModelViewMatrix);
00200   
00201   glViewport(0, 0, g_Width, g_Height);
00202   
00203   // Set up the stationary light (after camera transform)
00204   glLightfv(GL_LIGHT0, GL_POSITION, g_lightPos);
00205   glLightfv(GL_LIGHT0, GL_DIFFUSE, colorWhite );
00206   glLightfv(GL_LIGHT0, GL_AMBIENT, colorDarkGrey );
00207   glLightfv(GL_LIGHT0, GL_SPECULAR, colorWhite );
00208   
00209   // Fog from 0.6*visibility to visibility range
00210   glFogi( GL_FOG_MODE, GL_LINEAR );
00211   glFogf( GL_FOG_START, g_farPlane * 0.6f );
00212   glFogf( GL_FOG_END, g_farPlane );
00213   glFogfv( GL_FOG_COLOR, colorSky );
00214   glEnable( GL_FOG );
00215 
00216   // Render the scene
00217   renderScene();
00218 
00219 
00220   // Display framerate
00221   if (g_bFrameRate) {
00222     char buf[100];
00223     sprintf( buf, "%0.2f fps", g_fFPS );
00224     glMatrixMode( GL_PROJECTION );
00225     glLoadIdentity();
00226     glMatrixMode( GL_MODELVIEW );
00227     glLoadIdentity();
00228     glDisable( GL_DEPTH_TEST );
00229     glDisable( GL_LIGHTING );
00230     glColor3f( 1.0f, 1.0f, 1.0f );
00231     glRasterPos2f( -1,-1 );
00232     glutString( buf );
00233     glEnable( GL_DEPTH_TEST );
00234   }
00235 
00236   // Make sure changes appear onscreen
00237   glutSwapBuffers();
00238 }
00239 
00240 
00241 // Function which is called when the window size changes
00242 void reshape(GLint width, GLint height)
00243 {
00244   g_Width = width;
00245   g_Height = height;
00246 }
00247 
00248 
00249 // Function which is called once to initialize the GL
00250 void initGL()
00251 {
00252   glEnable(GL_DEPTH_TEST);
00253   glDepthFunc(GL_LESS);
00254   glShadeModel(GL_SMOOTH);
00255   glEnable(GL_LIGHTING);
00256   glEnable(GL_LIGHT0);
00257   glEnable( GL_CULL_FACE );
00258   glCullFace( GL_BACK );
00259   glEnable( GL_NORMALIZE );
00260 
00261   // Init Cg
00262   initTorus();
00263   // Load the textures
00264   initTextures();
00265 
00266   // Load the height field
00267   printf( "Loading height field %s, size %i x %i ... ",
00268           g_strHeightFieldFile, g_hfW, g_hfH );
00269   initHeightField();
00270   printf( "success.\n" );
00271 }
00272 
00273 
00274 
00275 
00276 
00277 /**********************************************
00278  **********************************************
00279    TIMER AND ANIMATION
00280  **********************************************
00281  *********************************************/
00282 
00283 static void timerCallback(int)
00284 {
00285   // Get time in seconds after last call to the timer
00286   int nc = glutGet(GLUT_ELAPSED_TIME);
00287   float fSec = float(nc-g_nLastTime) / 1000.0f;
00288   // Compute average frame rate from the last twenty frames
00289   g_fFPS = (19.0f*g_fFPS + 1.0f / fSec) / 20.0f;
00290   g_nLastTime = nc;
00291 
00292   // Perform all animations
00293   // Camera movement at 1/2 rounds per second
00294 /*  float fCamArc = fSec * 180.0f;
00295   if (g_bCameraUp && g_fCameraX < 90) g_fCameraX += fCamArc;
00296   if (g_bCameraDown && g_fCameraX > -90) g_fCameraX -= fCamArc;
00297   if (g_bCameraLeft) g_fCameraY += fCamArc;
00298   if (g_bCameraRight) g_fCameraY -= fCamArc;
00299 */
00300   // Plane rotation
00301   if (g_bRotateLeft) {
00302     g_fTorusX += fSec * 360.0f / 5.0f;
00303   }
00304   else if (g_bRotateRight) {
00305     g_fTorusX -= fSec * 360.0f / 5.0f;
00306   }
00307   if (g_bRotateUp) {
00308     g_fTorusY += fSec * 360.0f / 5.0f;
00309   }
00310   else if (g_bRotateDown) {
00311     g_fTorusY -= fSec * 360.0f / 5.0f;
00312   }
00313 
00314 
00315   // Redraw and restart timer
00316   glutPostRedisplay();
00317   glutTimerFunc( g_nTimerDelay, timerCallback, 0);
00318 }
00319 
00320 
00321 
00322 
00323 
00324 /**********************************************
00325  **********************************************
00326    MENU AND KEYBOARD HANDLING
00327  **********************************************
00328  *********************************************/
00329 
00330 
00331 // Just to illustrate how menus are used
00332 // This callback is called when a menu item was selected
00333 void selectFromMenu(int idCommand)
00334 {
00335   switch (idCommand) {
00336   case MENU_LIGHTING:
00337     g_bLighting = !g_bLighting;
00338     break;
00339   case MENU_FRAMERATE:
00340     g_bFrameRate = !g_bFrameRate;
00341     break;
00342   case MENU_POLYMODE:
00343     g_bFillPolygons = !g_bFillPolygons;
00344     glPolygonMode (GL_FRONT_AND_BACK, g_bFillPolygons ? GL_FILL : GL_LINE);
00345     break;      
00346   case MENU_EXIT:
00347     printf( "Exiting.\n" );
00348     glutSetKeyRepeat( GLUT_KEY_REPEAT_ON );
00349     exit (0);
00350     break;
00351   }
00352 
00353   // Almost any menu selection requires a redraw
00354   glutPostRedisplay();
00355 }
00356 
00357 
00358 float sExpFunc( int n )
00359 {
00360   return float(n*n) / 2.0f + 0.01f;
00361 }
00362 
00363 
00364 // Callback function called when a key was pressed
00365 void keyboard(unsigned char key, int, int )
00366 {
00367   switch (key) {
00368   case 27:             // ESCAPE key
00369     exit (0);
00370     break;
00371   case 'l':
00372     selectFromMenu(MENU_LIGHTING);
00373     break;
00374   case 'f':
00375     selectFromMenu(MENU_FRAMERATE);
00376     break;
00377   case 'p':
00378     selectFromMenu(MENU_POLYMODE);
00379     break;
00380   case '1':
00381     g_specularExponent = sExpFunc( 1 );
00382     break;
00383   case '2':
00384     g_specularExponent = sExpFunc( 2 );
00385     break;
00386   case '3':
00387     g_specularExponent = sExpFunc( 3 );
00388     break;
00389   case '4':
00390     g_specularExponent = sExpFunc( 4 );
00391     break;
00392   case '5':
00393     g_specularExponent = sExpFunc( 5 );
00394     break;
00395   case '6':
00396     g_specularExponent = sExpFunc( 6 );
00397     break;
00398   case '7':
00399     g_specularExponent = sExpFunc( 7 );
00400     break;
00401   case '8':
00402     g_specularExponent = sExpFunc( 8 );
00403     break;
00404   case '9':
00405     g_specularExponent = sExpFunc( 9 );
00406     break;
00407   case '0':
00408     g_specularExponent = sExpFunc( 0 );
00409     break;
00410   case 'a':
00411     g_bRotateLeft = true;
00412     break;
00413   case 'd':
00414     g_bRotateRight = true;
00415     break;
00416   case 's':
00417     g_bRotateUp = true;
00418     break;
00419   case 'w':
00420     g_bRotateDown = true;
00421     break;
00422   }
00423 }
00424 
00425 void keyboardUp(unsigned char key, int,int)
00426 {
00427   switch( key ) {
00428   case 'a':
00429     g_bRotateLeft = false;
00430     break;
00431   case 'd':
00432     g_bRotateRight = false;
00433     break;
00434   case 's':
00435     g_bRotateUp = false;
00436     break;
00437   case 'w':
00438     g_bRotateDown = false;
00439     break;
00440   }
00441 }
00442 
00443 void special( int key, int,int )
00444 {
00445   switch( key ) {
00446   case GLUT_KEY_F1:
00447     g_bPerPixelLighting = true;
00448     break;
00449   case GLUT_KEY_F2:
00450     g_bPerPixelLighting = false;
00451     break;
00452   case GLUT_KEY_F3:
00453     g_bBlinnPhong = true;
00454     break;
00455   case GLUT_KEY_F4:
00456     g_bBlinnPhong = false;
00457     break;
00458   case GLUT_KEY_UP:
00459     g_bCameraUp = true;
00460     break;
00461   case GLUT_KEY_DOWN:
00462     g_bCameraDown = true;
00463     break;
00464   case GLUT_KEY_LEFT:
00465     g_bCameraLeft = true;
00466     break;
00467   case GLUT_KEY_RIGHT:
00468     g_bCameraRight = true;
00469     break;
00470   }
00471 }
00472 
00473 
00474 void specialUp( int key, int,int )
00475 {
00476   switch( key ) {
00477   case GLUT_KEY_UP:
00478     g_bCameraUp = false;
00479     break;
00480   case GLUT_KEY_DOWN:
00481     g_bCameraDown = false;
00482     break;
00483   case GLUT_KEY_LEFT:
00484     g_bCameraLeft = false;
00485     break;
00486   case GLUT_KEY_RIGHT:
00487     g_bCameraRight = false;
00488     break;
00489   }
00490 }
00491 
00492 
00493 
00494 
00495 
00496 // This function initializes the popup menu
00497 int buildPopupMenu()
00498 {
00499   printf( "Keys:\n" );
00500 
00501 //  printf( "  F1 - Per Pixel Lighting ON\n" );
00502 //  printf( "  F2 - Per Pixel Lighting OFF\n" );
00503 
00504 //  printf( "  F3 - Specular Term ON\n" );
00505 //  printf( "  F4 - Specular Tern OFF\n\n" );
00506 
00507 //  printf( "  0-9 - Set specular exponent to n^2/4\n\n" );
00508 
00509 //  printf( "  Cursor keys - rotate camera\n" );
00510 //  printf( "  A,S,D,W     - rotate Torus\n\n" );
00511 
00512   printf( "  p - Toggle polygon fill\n" );
00513   printf( "  f   - Display frame rate\n" );
00514   printf( "  ESC - Exit demo\n" );
00515 
00516 
00517   int menu = glutCreateMenu (selectFromMenu);
00518   glutAddMenuEntry ("Toggle polygon fill\tp", MENU_POLYMODE);
00519   glutAddMenuEntry ("Display frame rate\tf", MENU_FRAMERATE);
00520   glutAddMenuEntry ("Exit demo\tEsc", MENU_EXIT);
00521   return menu;
00522 }
00523 
00524 
00525 
00526 
00527 
00528 /**********************************************
00529  **********************************************
00530    MAIN FUNCTION
00531  **********************************************
00532  *********************************************/
00533 
00534 int main(int argc, char** argv)
00535 {
00536   // GLUT Window Initialization:
00537   glutInit(&argc, argv);
00538   glutInitWindowSize(g_Width, g_Height);
00539   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
00540   glutCreateWindow("CG-I GLUT example");
00541 
00542   glutSetKeyRepeat( GLUT_KEY_REPEAT_ON );
00543   glutIgnoreKeyRepeat(0);
00544 
00545   // Initialize OpenGL graphics state
00546   initGL();
00547 
00548   // Register callbacks:
00549   glutDisplayFunc(display);
00550   glutReshapeFunc(reshape);
00551   glutKeyboardFunc(keyboard);
00552   glutKeyboardUpFunc(keyboardUp);
00553   glutSpecialFunc(special);
00554   glutSpecialUpFunc(specialUp);
00555 
00556 
00557   // Create popup menu
00558   buildPopupMenu();
00559   glutAttachMenu(GLUT_RIGHT_BUTTON);
00560 
00561   // Start display timer
00562   g_nLastTime = glutGet( GLUT_ELAPSED_TIME );
00563   glutTimerFunc( g_nTimerDelay, timerCallback, 0);
00564 
00565   // Turn the flow of control over to GLUT
00566   glutMainLoop();
00567   return 0;
00568 }

Generated on Thu Jan 20 02:47:13 2005 for Projective_Texture_Effect_Demo by doxygen 1.3.6