home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible / OpenGL_Superbible_Waite_Group_Press_1996.iso / book / chapt10 / tank / microsoft / glutils.c < prev    next >
C/C++ Source or Header  |  1996-07-07  |  8KB  |  241 lines

  1. // glutils.c
  2. // General purpose OpenGL Utility functions
  3.  
  4. #include <windows.h>
  5. #include <math.h>                // Include for sqrt()
  6. #include <gl\gl.h>              // OpenGL
  7. #include <gl\glu.h>             // GLU library
  8. #include "glutils.h"            // OpenGL support functions
  9. #include "externs.h"
  10.  
  11. // Reduces a normal vector specified as a set of three coordinates,
  12. // to a unit normal vector of length one.
  13. void ReduceToUnit(float vector[3])
  14.     {
  15.     float length;
  16.     
  17.     // Calculate the length of the vector        
  18.     length = (float)sqrt((vector[0]*vector[0]) + 
  19.                         (vector[1]*vector[1]) +
  20.                         (vector[2]*vector[2]));
  21.  
  22.     // Keep the program from blowing up by providing an exceptable
  23.     // value for vectors that may calculated too close to zero.
  24.     if(length == 0.0f)
  25.         length = 1.0f;
  26.  
  27.     // Dividing each element by the length will result in a
  28.     // unit normal vector.
  29.     vector[0] /= length;
  30.     vector[1] /= length;
  31.     vector[2] /= length;
  32.     }
  33.  
  34.  
  35. // Points p1, p2, & p3 specified in counter clock-wise order
  36. void calcNormal(float v[3][3], float out[3])
  37.     {
  38.     float v1[3],v2[3];
  39.     static const int x = 0;
  40.     static const int y = 1;
  41.     static const int z = 2;
  42.  
  43.     // Calculate two vectors from the three points
  44.     v1[x] = v[0][x] - v[1][x];
  45.     v1[y] = v[0][y] - v[1][y];
  46.     v1[z] = v[0][z] - v[1][z];
  47.  
  48.     v2[x] = v[1][x] - v[2][x];
  49.     v2[y] = v[1][y] - v[2][y];
  50.     v2[z] = v[1][z] - v[2][z];
  51.  
  52.     // Take the cross product of the two vectors to get
  53.     // the normal vector which will be stored in out
  54.     out[x] = v1[y]*v2[z] - v1[z]*v2[y];
  55.     out[y] = v1[z]*v2[x] - v1[x]*v2[z];
  56.     out[z] = v1[x]*v2[y] - v1[y]*v2[x];
  57.  
  58.     // Normalize the vector (shorten length to one)
  59.     ReduceToUnit(out);
  60.     }
  61.  
  62.  
  63. /////////////////////////////////////////////////////////////////////////
  64. /////////////////////////////////////////////////////////////////////////
  65. // Windows specific utilities
  66. /////////////////////////////////////////////////////////////////////////
  67.  
  68.  
  69. // If necessary, creates a 3-3-2 palette for the device context listed.
  70. // Returns NULL if non-palettized device
  71. HPALETTE GetOpenGLPalette(HDC hDC)
  72.     {
  73.     HPALETTE hRetPal = NULL;    // Handle to palette to be created
  74.     PIXELFORMATDESCRIPTOR pfd;    // Pixel Format Descriptor
  75.     LOGPALETTE *pPal;            // Pointer to memory for logical palette
  76.     int nPixelFormat;            // Pixel format index
  77.     int nColors;                // Number of entries in palette
  78.     int i;                        // Counting variable
  79.     BYTE RedRange,GreenRange,BlueRange;
  80.                                 // Range for each color entry (7,7,and 3)
  81.  
  82.  
  83.     // Get the pixel format index and retrieve the pixel format description
  84.     nPixelFormat = GetPixelFormat(hDC);
  85.     DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  86.  
  87.     // Does this pixel format require a palette?  If not, do not create a
  88.     // palette and just return NULL
  89.     if(!(pfd.dwFlags & PFD_NEED_PALETTE))
  90.         return NULL;
  91.  
  92.     // Number of entries in palette.  8 bits yeilds 256 entries
  93.     nColors = 1 << pfd.cColorBits;    
  94.  
  95.     // Allocate space for a logical palette structure plus all the palette entries
  96.     pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
  97.  
  98.     // Fill in palette header 
  99.     pPal->palVersion = 0x300;        // Windows 3.0
  100.     pPal->palNumEntries = nColors; // table size
  101.  
  102.     // Build mask of all 1's.  This creates a number represented by having
  103.     // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
  104.     // pfd.cBlueBits.  
  105.     RedRange = (1 << pfd.cRedBits) -1;
  106.     GreenRange = (1 << pfd.cGreenBits) - 1;
  107.     BlueRange = (1 << pfd.cBlueBits) -1;
  108.  
  109.     // Loop through all the palette entries
  110.     for(i = 0; i < nColors; i++)
  111.         {
  112.         // Fill in the 8-bit equivalents for each component
  113.         pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
  114.         pPal->palPalEntry[i].peRed = (unsigned char)(
  115.             (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
  116.  
  117.         pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
  118.         pPal->palPalEntry[i].peGreen = (unsigned char)(
  119.             (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
  120.  
  121.         pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
  122.         pPal->palPalEntry[i].peBlue = (unsigned char)(
  123.             (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
  124.  
  125.         pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
  126.         }
  127.         
  128.  
  129.     // Create the palette
  130.     hRetPal = CreatePalette(pPal);
  131.  
  132.     // Go ahead and select and realize the palette for this device context
  133.     SelectPalette(hDC,hRetPal,FALSE);
  134.     RealizePalette(hDC);
  135.  
  136.     // Free the memory used for the logical palette structure
  137.     free(pPal);
  138.  
  139.     // Return the handle to the new palette
  140.     return hRetPal;
  141.     }
  142.  
  143.  
  144. // Select the pixel format for a given device context
  145. void SetDCPixelFormat(HDC hDC)
  146.     {
  147.     int nPixelFormat;
  148.  
  149.     static PIXELFORMATDESCRIPTOR pfd = {
  150.         sizeof(PIXELFORMATDESCRIPTOR),  // Size of this structure
  151.         1,                                                              // Version of this structure    
  152.         PFD_DRAW_TO_WINDOW |                    // Draw to Window (not to bitmap)
  153.         PFD_SUPPORT_OPENGL |                    // Support OpenGL calls in window
  154.         PFD_DOUBLEBUFFER,                       // Double buffered
  155.         PFD_TYPE_RGBA,                          // RGBA Color mode
  156.         24,                                     // Want 24bit color 
  157.         0,0,0,0,0,0,                            // Not used to select mode
  158.         0,0,                                    // Not used to select mode
  159.         0,0,0,0,0,                              // Not used to select mode
  160.         // Try to get away with smaller depth buffer to take advantage
  161.         // of low end PC accelerator cards
  162.         0,                                     // Size of depth buffer
  163.         0,                                      // Not used to select mode
  164.         0,                                      // Not used to select mode
  165.         PFD_MAIN_PLANE,                         // Draw in main plane
  166.         0,                                      // Not used to select mode
  167.         0,0,0 };                                // Not used to select mode
  168.  
  169.     // Choose a pixel format that best matches that described in pfd
  170.     nPixelFormat = ChoosePixelFormat(hDC, &pfd);
  171.  
  172.     // Set the pixel format for the device context
  173.     SetPixelFormat(hDC, nPixelFormat, &pfd);
  174.     }
  175.  
  176.  
  177.  
  178.  
  179.  
  180. // Select the pixel format for a given device context. This function is identical
  181. // to the above, but also supplies a depth buffer
  182. void SetDCDepthPixelFormat(HDC hDC)
  183.     {
  184.     int nPixelFormat;
  185.  
  186.     static PIXELFORMATDESCRIPTOR pfd = {
  187.         sizeof(PIXELFORMATDESCRIPTOR),  // Size of this structure
  188.         1,                                                              // Version of this structure    
  189.         PFD_DRAW_TO_WINDOW |                    // Draw to Window (not to bitmap)
  190.         PFD_SUPPORT_OPENGL |                    // Support OpenGL calls in window
  191.         PFD_DOUBLEBUFFER,                       // Double buffered
  192.         PFD_TYPE_RGBA,                          // RGBA Color mode
  193.         24,                                     // Want 24bit color 
  194.         0,0,0,0,0,0,                            // Not used to select mode
  195.         0,0,                                    // Not used to select mode
  196.         0,0,0,0,0,                              // Not used to select mode
  197.         // Try to get away with smaller depth buffer to take advantage
  198.         // of low end PC accelerator cards
  199.         32,                                     // Size of depth buffer
  200.         0,                                      // Not used to select mode
  201.         0,                                      // Not used to select mode
  202.         PFD_MAIN_PLANE,                         // Draw in main plane
  203.         0,                                      // Not used to select mode
  204.         0,0,0 };                                // Not used to select mode
  205.  
  206.     // Choose a pixel format that best matches that described in pfd
  207.     nPixelFormat = ChoosePixelFormat(hDC, &pfd);
  208.  
  209.     // Set the pixel format for the device context
  210.     SetPixelFormat(hDC, nPixelFormat, &pfd);
  211.     }
  212.  
  213.  
  214.  
  215.  
  216. // Moves the tank or robot forwards or backwards
  217. void MoveViewer(GLdouble dStep)
  218.     {
  219.     GLdouble xDelta,zDelta;
  220.  
  221.     xDelta = dStep*cos(pObject->radsFromEast);
  222.     zDelta = -dStep*sin(pObject->radsFromEast);
  223.  
  224.     pObject->xPos += (float)xDelta;
  225.     pObject->zPos += (float)zDelta;
  226.  
  227.     if(pObject->xPos > 1000.0f)
  228.         pObject->xPos = 1000.0f;
  229.  
  230.     if(pObject->xPos < -1000.0f)
  231.         pObject->xPos = -1000.0f;
  232.  
  233.     
  234.     if(pObject->zPos > 1000.0f)
  235.         pObject->zPos = 1000.0f;
  236.  
  237.     if(pObject->zPos < -1000.0f)
  238.         pObject->zPos = -1000.0f;
  239.  
  240.     }
  241.