home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vrml2gl.zip / LIB / GLOBJ.C next >
C/C++ Source or Header  |  1997-02-25  |  35KB  |  745 lines

  1. #include "glObjects.h"
  2. /*===========================================================================*/
  3. /*  This function will draw a cude centered at the origin give width, height */
  4. /* and depth.                                                                */
  5. /* parts = TEXTURE_ON                                                        */
  6. /*===========================================================================*/
  7. void  glObjCube( float width, float height, float depth, int parts )
  8. {
  9.    static   float vertex[8][3];
  10.  
  11.    width /= 2.0;
  12.    height /= 2.0;
  13.    depth /= 2.0;
  14.  
  15.    vertex[0][0] = -width;  vertex[1][0] = width;   vertex[2][0] = width;   vertex[3][0] = -width;
  16.    vertex[0][1] = height;  vertex[1][1] = height;  vertex[2][1] = height;  vertex[3][1] = height;
  17.    vertex[0][2] = depth;   vertex[1][2] = depth;   vertex[2][2] = -depth;  vertex[3][2] = -depth;
  18.  
  19.    vertex[4][0] = -width;  vertex[5][0] = width;   vertex[6][0] = width;   vertex[7][0] = -width;
  20.    vertex[4][1] = -height; vertex[5][1] = -height; vertex[6][1] = -height; vertex[7][1] = -height;
  21.    vertex[4][2] = depth;   vertex[5][2] = depth;   vertex[6][2] = -depth;  vertex[7][2] = -depth;
  22.  
  23.    /* Enable texture mapping if requested. */
  24.    if ( parts == TEXTURE_ON )
  25.       glEnable( GL_TEXTURE_2D );
  26.  
  27.    glPushMatrix();
  28.       glBegin( GL_QUADS );
  29.          /* Top Face. */
  30.          glNormal3f( 0.0, 1.0, 0.0 );
  31.          glTexCoord2f( 0.0, 0.0 );  /* Top left. */
  32.          glVertex3fv( vertex[0] );
  33.          glTexCoord2f( 1.0, 0.0 );  /* Top right. */
  34.          glVertex3fv( vertex[1] );
  35.          glTexCoord2f( 1.0, 1.0 );  /* Bottom right. */
  36.          glVertex3fv( vertex[2] );
  37.          glTexCoord2f( 0.0, 1.0 );  /* Bottom left. */
  38.          glVertex3fv( vertex[3] );
  39.  
  40.          /* Back Face. */
  41.          glNormal3f( 0.0, 0.0, -1.0 );
  42.          glTexCoord2f( 0.0, 1.0 );  /* Top left. */
  43.          glVertex3fv( vertex[2] );
  44.          glTexCoord2f( 0.0, 0.0 );  /* Bottom left. */
  45.          glVertex3fv( vertex[6] );
  46.          glTexCoord2f( 1.0, 0.0 );  /* Bottom right. */
  47.          glVertex3fv( vertex[7] );
  48.          glTexCoord2f( 1.0, 1.0 );  /* Top right. */
  49.          glVertex3fv( vertex[3] );
  50.  
  51.          /* Bottom Face. */
  52.          glNormal3f( 0.0, -1.0, 0.0 );
  53.          glTexCoord2f( 1.0, 0.0 );  /* Top right. */
  54.          glVertex3fv( vertex[4] );
  55.          glTexCoord2f( 1.0, 1.0 );  /* Bottom right. */
  56.          glVertex3fv( vertex[7] );
  57.          glTexCoord2f( 0.0, 1.0 );  /* Bottom left. */
  58.          glVertex3fv( vertex[6] );
  59.          glTexCoord2f( 0.0, 0.0 );  /* Top left. */
  60.          glVertex3fv( vertex[5] );
  61.  
  62.          /* Front Face. */
  63.          glNormal3f( 0.0, 0.0, 1.0 );
  64.          glTexCoord2f( 0.0, 1.0 );  /* Top left. */
  65.          glVertex3fv( vertex[0] );
  66.          glTexCoord2f( 0.0, 0.0 );  /* Bottom left. */
  67.          glVertex3fv( vertex[4] );
  68.          glTexCoord2f( 1.0, 0.0 );  /* Bottom right. */
  69.          glVertex3fv( vertex[5] );
  70.          glTexCoord2f( 1.0, 1.0 );  /* Top right. */
  71.          glVertex3fv( vertex[1] );
  72.  
  73.          /* Right Face. */
  74.          glNormal3f( 1.0, 0.0, 0.0 );
  75.          glTexCoord2f( 0.0, 1.0 );  /* Top left. */
  76.          glVertex3fv( vertex[1] );
  77.          glTexCoord2f( 0.0, 0.0 );  /* Bottom left. */
  78.          glVertex3fv( vertex[5] );
  79.          glTexCoord2f( 1.0, 0.0 );  /* Bottom right. */
  80.          glVertex3fv( vertex[6] );
  81.          glTexCoord2f( 1.0, 1.0 );  /* Top right. */
  82.          glVertex3fv( vertex[2] );
  83.  
  84.          /* Left Face. */
  85.          glNormal3f( -1.0, 0.0, 0.0 );
  86.          glTexCoord2f( 0.0, 1.0 );  /* Top left. */
  87.          glVertex3fv( vertex[3] );
  88.          glTexCoord2f( 0.0, 0.0 );  /* Bottom left. */
  89.          glVertex3fv( vertex[7] );
  90.          glTexCoord2f( 1.0, 0.0 );  /* Bottom right. */
  91.          glVertex3fv( vertex[4] );
  92.          glTexCoord2f( 1.0, 1.0 );  /* Top right. */
  93.          glVertex3fv( vertex[0] );
  94.       glEnd();
  95.    glPopMatrix();
  96.  
  97.    /* Disable texture mapping if it was used. */
  98.    if ( parts == TEXTURE_ON )
  99.       glDisable( GL_TEXTURE_2D );
  100. }
  101.  
  102. /*===========================================================================*/
  103. /*  This function will draw a cylinder centered at the origin. The function  */
  104. /* takes a radius height and a bitmask. The first time called it will create */
  105. /* a list of vertices that are unit length. Then only the radius needs to be */
  106. /* multilplied instead of the radius and trig functions.                     */
  107. /*-------------------------------------------------------------------------- */
  108. /* #define NUM_CYLINDER_FACES   16                                           */
  109. /* parts = (ALL | TOP | BOTTOM | SIDES | TEXTURE_ON)                         */
  110. /*===========================================================================*/
  111. void  glObjCylinder  ( float radius, float height, int parts )
  112. {
  113.    static   int   index;
  114.    static   float vertex[NUM_CYLINDER_FACES][2],
  115.                   normal[NUM_CYLINDER_FACES][2];
  116.    static   int   isBuilt = GL_FALSE;
  117.  
  118.    /* Build the vertices only once. */
  119.    if ( isBuilt == GL_FALSE )
  120.    {
  121.       /* Set all the vertices and normal for a unit length circle. */
  122.       for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
  123.       {
  124.          normal[index][0] = vertex[index][0] = sin(TWOPIE*index / (NUM_CYLINDER_FACES-1)) * -1.0;
  125.          normal[index][1] = vertex[index][1] = cos(TWOPIE*index / (NUM_CYLINDER_FACES-1)) * -1.0;
  126.       }
  127.    }
  128.    
  129.    /*========================================================================*/
  130.    /* Draw the textured parts first then the non-textured.                   */
  131.    /*========================================================================*/
  132.    if ( parts & TEXTURE_ON )
  133.       glEnable( GL_TEXTURE_2D );
  134.  
  135.    /* Draw the top of the cylinder if ALL or TOP is set. */
  136.    if ( (parts & ALL) || (parts & TOP) )
  137.    {
  138.       glPushMatrix();
  139.          glTranslatef( 0.0, (height/2.0), 0.0 );
  140.          glBegin( GL_TRIANGLE_FAN );
  141.             glNormal3f( 0.0, 1.0, 0.0 );
  142.             glTexCoord2f( 0.5, 0.5 );  
  143.             glVertex3f( 0.0, 0.0, 0.0 );
  144.             for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
  145.             {
  146.                glTexCoord2f( (0.5+(vertex[index][0]/2.0)), (0.5+(vertex[index][1]/-2.0)) );  
  147.                glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
  148.             }
  149.             glTexCoord2f( (0.5+(vertex[0][0]/2.0)), (0.5+(vertex[0][1]/2.0)) );  
  150.             glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
  151.          glEnd();
  152.       glPopMatrix();
  153.    }
  154.  
  155.    /* Draw the bottom of the cylinder if ALL or BOTTOM is set. */
  156.    if ( (parts & ALL) || (parts & BOTTOM) )
  157.    {
  158.       glPushMatrix();
  159.          glFrontFace( GL_CW );
  160.          glTranslatef( 0.0, -(height/2.0), 0.0 );
  161.          glBegin( GL_TRIANGLE_FAN );
  162.             glNormal3f( 0.0, -1.0, 0.0 );
  163.             glTexCoord2f( 0.5, 0.5 );  
  164.             glVertex3f( 0.0, 0.0, 0.0 );
  165.             for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
  166.             {
  167.                glTexCoord2f( (0.5+(vertex[index][0]/2.0)), (0.5+(vertex[index][1]/-2.0)) );  
  168.                glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
  169.             }
  170.             glTexCoord2f( (0.5+(vertex[0][0]/2.0)), (0.5+(vertex[0][1]/2.0)) );  
  171.             glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
  172.          glEnd();
  173.          glFrontFace( GL_CCW );
  174.       glPopMatrix();
  175.    }
  176.  
  177.    /* Draw the sides of the cylinder if ALL or SIDES is set. */
  178.    if ( (parts & ALL) || (parts & SIDES) )
  179.    {
  180.       glPushMatrix();
  181.          glTranslatef( 0.0, (height/2.0), 0.0 );
  182.          glBegin( GL_QUADS );
  183.             for ( index = 0; index < (NUM_CYLINDER_FACES-1); index++ )
  184.             {
  185.                glNormal3f( normal[index][0],  0.0,    normal[index][1] );
  186.                glTexCoord2f( (index/(NUM_CYLINDER_FACES-2.0)), 1.0 );  
  187.                glVertex3f( (vertex[index][0]*radius),  0.0,    (vertex[index][1]*radius) );
  188.                glTexCoord2f( (index/(NUM_CYLINDER_FACES-2.0)), 0.0 );  
  189.                glVertex3f( (vertex[index][0]*radius), -height, (vertex[index][1]*radius) );
  190.  
  191.                glNormal3f( normal[(index+1)][0],  0.0,    normal[(index+1)][1] );
  192.                glTexCoord2f( ((index+1)/(NUM_CYLINDER_FACES-2.0)), 0.0 ); 
  193.                glVertex3f( (vertex[(index+1)][0]*radius), -height, (vertex[(index+1)][1]*radius) );
  194.                glTexCoord2f( ((index+1)/(NUM_CYLINDER_FACES-2.0)), 1.0 ); 
  195.                glVertex3f( (vertex[(index+1)][0]*radius),  0.0,    (vertex[(index+1)][1]*radius) );
  196.             }
  197.          glEnd();
  198.       glPopMatrix();
  199.    } 
  200.  
  201.    /*========================================================================*/
  202.    /* Disable texure mapping now that all textured parts are finished.       */
  203.    /*========================================================================*/
  204.    if ( parts & TEXTURE_ON )
  205.       glDisable( GL_TEXTURE_2D );
  206.  
  207.    /* Draw the inner side of the top of the cylinder if only TOP is set. */
  208.    if ( parts & TOP )
  209.    {
  210.       glPushMatrix();
  211.       glFrontFace( GL_CW );
  212.          glTranslatef( 0.0, (height/2.0), 0.0 );
  213.          glBegin( GL_TRIANGLE_FAN );
  214.             glNormal3f( 0.0, -1.0, 0.0 );
  215.             glVertex3f( 0.0, 0.0, 0.0 );
  216.             for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
  217.                glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
  218.             glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
  219.          glEnd();
  220.       glFrontFace( GL_CCW );
  221.       glPopMatrix();
  222.    }
  223.  
  224.    /* Draw the inner side of the bottom of the cylinder if only BOTTOM is set. */
  225.    if ( parts & BOTTOM )
  226.    {
  227.       glPushMatrix();
  228.          glTranslatef( 0.0, -(height/2.0), 0.0 );
  229.          glBegin( GL_TRIANGLE_FAN );
  230.             glNormal3f( 0.0, 1.0, 0.0 );
  231.             glVertex3f( 0.0, 0.0, 0.0 );
  232.             for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
  233.                glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
  234.             glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
  235.          glEnd();
  236.       glPopMatrix();
  237.    }
  238.  
  239.    /* Draw the inner side of the sides of the cylinder if only SIDES is set. */
  240.    if ( parts & SIDES )
  241.    {
  242.       glPushMatrix();
  243.       glFrontFace( GL_CW );
  244.          glTranslatef( 0.0, (height/2.0), 0.0 );
  245.          glBegin( GL_QUADS );
  246.             for ( index = 0; index < (NUM_CYLINDER_FACES-1); index++ )
  247.             {
  248.                glNormal3f( -normal[index][0],  0.0,   -normal[index][1] );
  249.                glVertex3f( (vertex[index][0]*radius),  0.0,    (vertex[index][1]*radius) );
  250.                glVertex3f( (vertex[index][0]*radius), -height, (vertex[index][1]*radius) );
  251.  
  252.                glNormal3f( -normal[(index+1)][0],  0.0,   -normal[(index+1)][1] );
  253.                glVertex3f( (vertex[(index+1)][0]*radius), -height, (vertex[(index+1)][1]*radius) );
  254.                glVertex3f( (vertex[(index+1)][0]*radius),  0.0,    (vertex[(index+1)][1]*radius) );
  255.             }           
  256.          glEnd();
  257.       glFrontFace( GL_CCW );
  258.       glPopMatrix();
  259.    }   
  260.  
  261. }
  262.  
  263. /*===========================================================================*/
  264. /*  This function will draw a cone centered at the origin. The function takes*/
  265. /* a radius height and a bitmask. The first time called it will create a list*/
  266. /* of vertices that are unit length. Then only the radius needs to be        */
  267. /* multilplied instead of the radius and trig functions.                     */
  268. /*-------------------------------------------------------------------------- */
  269. /* parts = (ALL | BOTTOM | SIDES | TEXTURE_ON)                               */
  270. /*===========================================================================*/
  271. void  glObjCone   ( float radius, float height, int parts )
  272. {
  273.    static   int   index;
  274.    static   float topPoint[3],
  275.                   tempNormal[3],
  276.                   vertex[NUM_CONE_FACES][3];
  277.    static   int   isBuilt = GL_FALSE;
  278.  
  279.    /* Build the vertices only once. */
  280.    if ( isBuilt == GL_FALSE )
  281.    {
  282.       /*  Set all the vertices for a unit length circle. Thease will also */
  283.       /* be used as part of the normals.                                 */
  284.       for ( index = 0; index < NUM_CONE_FACES; index++ )
  285.       {
  286.          vertex[index][0] = sin(TWOPIE*index / (NUM_CONE_FACES-1)) * -1.0;
  287.          vertex[index][1] = 0.0;
  288.          vertex[index][2] = cos(TWOPIE*index / (NUM_CONE_FACES-1)) * -1.0;
  289.       }
  290.  
  291.       /* Mark the top point of the cone. */
  292.       topPoint[0] = 0.0;
  293.       topPoint[1] = height;
  294.       topPoint[2] = 0.0;
  295.    }
  296.  
  297.    /*========================================================================*/
  298.    /* Draw the textured parts first then the non-textured.                   */
  299.    /*========================================================================*/
  300.    if ( parts & TEXTURE_ON )
  301.       glEnable( GL_TEXTURE_2D );
  302.  
  303.    /* Draw the bottom of the cone if ALL or BOTTOM is set. */
  304.    if ( (parts & ALL) || (parts & BOTTOM) )
  305.    {
  306.       glPushMatrix();
  307.          glFrontFace( GL_CW );
  308.          glTranslatef( 0.0, -(height/2.0), 0.0 );
  309.          glBegin( GL_TRIANGLE_FAN );
  310.             glNormal3f( 0.0, -1.0, 0.0 );
  311.             glTexCoord2f( 0.5, 0.5 );  
  312.             glVertex3f( 0.0, 0.0, 0.0 );
  313.             for ( index = 0; index < NUM_CONE_FACES; index++ )
  314.             {
  315.                glTexCoord2f( (0.5+(vertex[index][0]/2.0)), (0.5+(vertex[index][2]/-2.0)) );  
  316.                glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][2]*radius) );
  317.             }
  318.             glTexCoord2f( (0.5+(vertex[0][0]/2.0)), (0.5+(vertex[0][2]/2.0)) );  
  319.             glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][2]*radius) );
  320.          glEnd();
  321.          glFrontFace( GL_CCW );
  322.       glPopMatrix();
  323.    }
  324.  
  325.    /* Draw the sides of the cone if ALL or SIDES are set. */
  326.    if ( (parts & ALL) || (parts & SIDES) )
  327.    {
  328.       glPushMatrix();
  329.          glTranslatef( 0.0, -(height/2.0), 0.0 );
  330.          glBegin( GL_TRIANGLES );
  331.             for ( index = 0; index < (NUM_CONE_FACES-1); index++ )
  332.             {
  333.                /* Calculate the face normal and use it only for the tip. */
  334.                glMathGetNormalfv3f( vertex[(index+1)], topPoint, vertex[index], tempNormal );
  335.                glNormal3fv( tempNormal );
  336.                glTexCoord2f( (index/(NUM_CONE_FACES-1.0)), 1.0 );  
  337.                glVertex3fv( topPoint );
  338.  
  339.                /* Use the vertex's x,z for the normal along with y component from the face's normal . */
  340.                glNormal3f( vertex[index][0], tempNormal[1], vertex[index][2] );
  341.                glTexCoord2f( (index/(NUM_CONE_FACES-1.0)), 0.0 );  
  342.                glVertex3f( (vertex[index][0]*radius), (vertex[index][1]*radius), (vertex[index][2]*radius) );
  343.                
  344.                /* Use the vertex's x,z for the normal along with y component from the face's normal . */
  345.                glNormal3f( vertex[(index+1)][0], tempNormal[1], vertex[(index+1)][2] );
  346.                glTexCoord2f( ((index+1)/(NUM_CONE_FACES-1.0)), 0.0 );  
  347.                glVertex3f( (vertex[(index+1)][0]*radius), (vertex[(index+1)][1]*radius), (vertex[(index+1)][2]*radius) );
  348.             }
  349.          glEnd();
  350.       glPopMatrix();
  351.    }
  352.  
  353.    /*========================================================================*/
  354.    /* Disable texure mapping now that all textured parts are finished.       */
  355.    /*========================================================================*/
  356.    if ( parts & TEXTURE_ON )
  357.       glDisable( GL_TEXTURE_2D );
  358.  
  359.    /* Draw the inner side of the bottom of the cone if only BOTTOM is set. */
  360.    if ( (parts & ALL) || (parts & BOTTOM) )
  361.    {
  362.       glPushMatrix();
  363.          glTranslatef( 0.0, -(height/2.0), 0.0 );
  364.          glBegin( GL_TRIANGLE_FAN );
  365.             glNormal3f( 0.0, 1.0, 0.0 );
  366.             glVertex3f( 0.0, 0.0, 0.0 );
  367.             for ( index = 0; index < NUM_CONE_FACES; index++ )
  368.                glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][2]*radius) );
  369.             glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][2]*radius) );
  370.          glEnd();
  371.       glPopMatrix();
  372.    }
  373.  
  374.    /* Draw the inner part of the sides of the cone if only SIDES is set. */
  375.    if ( parts & SIDES )
  376.    {
  377.       glPushMatrix();
  378.          glTranslatef( 0.0, -(height/2.0), 0.0 );
  379.          glBegin( GL_TRIANGLES );
  380.             for ( index = 0; index < (NUM_CONE_FACES-1); index++ )
  381.             {
  382.                /* Calculate the face normal and use it only for the tip. */
  383.                glMathGetNormalfv3f( vertex[(index+1)], topPoint, vertex[index], tempNormal );
  384.  
  385.                /* Use the vertex's x,z for the normal along with y component from the face's normal . */
  386.                glNormal3f( -vertex[(index+1)][0], -tempNormal[1], -vertex[(index+1)][2] );
  387.                glVertex3f( (vertex[(index+1)][0]*radius), (vertex[(index+1)][1]*radius), (vertex[(index+1)][2]*radius) );
  388.  
  389.                /* Use the vertex's x,z for the normal along with y component from the face's normal . */
  390.                glNormal3f( -vertex[index][0], -tempNormal[1], -vertex[index][2] );
  391.                glVertex3f( (vertex[index][0]*radius), (vertex[index][1]*radius), (vertex[index][2]*radius) );
  392.  
  393.                /* Use the face's normal for the top point. */               
  394.                glNormal3f( -tempNormal[0], -tempNormal[1], -tempNormal[2] );
  395.                glVertex3fv( topPoint );
  396.             }
  397.          glEnd();
  398.       glPopMatrix();
  399.    }   
  400. }
  401.  
  402. /*===========================================================================*/
  403. /*  This function will draw a sphere centered at the origin. The function    */
  404. /* takes radius.                                                             */
  405. /*---------------------------------------------------------------------------*/
  406. /* parts = (TEXTURE_ON | INSIDE | OUTSIDE | ALL)                             */
  407. /*===========================================================================*/
  408. void  glObjSphere   ( float radius, int parts )
  409. {
  410.    static   int   sliceIndex,
  411.                   stackIndex;
  412.    static   float theta,
  413.                   phi;
  414.    static   float vertex[(SLICES+1)][(STACKS-1)][3];
  415.    static   int   isBuilt = GL_FALSE;
  416.  
  417.    /*  Build the vertices only once. The vertices will also be used as the */
  418.    /* normals for smooth shading. I also multiply by -1 to get the texture */
  419.    /* orientation right.                                                   */
  420.    if ( isBuilt == GL_FALSE)
  421.    {
  422.       for ( sliceIndex = 0; sliceIndex < (SLICES+1); sliceIndex++)
  423.       {            
  424.          theta = (TWOPIE / (float)SLICES) * (float)sliceIndex;
  425.          for ( stackIndex = 1; stackIndex < STACKS; stackIndex++)
  426.          {
  427.             phi = (PIE / (float)STACKS) * (float)stackIndex;
  428.  
  429.             vertex[sliceIndex][(stackIndex-1)][0] = sin(phi) * sin(theta) * -1.0;
  430.             vertex[sliceIndex][(stackIndex-1)][1] = cos(phi);
  431.             vertex[sliceIndex][(stackIndex-1)][2] = sin(phi) * cos(theta) * -1.0;
  432.          }
  433.       }
  434.       isBuilt = GL_TRUE;
  435.    }
  436.  
  437.    /*========================================================================*/
  438.    /* Draw the outside of the surface only. Check for texture mapping also.  */
  439.    /*========================================================================*/
  440.    if ( parts & TEXTURE_ON )
  441.       glEnable( GL_TEXTURE_2D );
  442.  
  443.    if ( (parts & OUTSIDE) || (parts & ALL) )
  444.    {
  445.       /*  Draw the SLICES of the sphere starting from the -Z axis to the */
  446.       /* -X axis back to the -Z axis.                                    */
  447.       glPushMatrix();
  448.          for ( sliceIndex = 0; sliceIndex < SLICES; sliceIndex++)
  449.          {            
  450.             /* Draw the special case which is the top triangle. */
  451.             glBegin( GL_TRIANGLES );
  452.                glNormal3f( 0.0, 1.0, 0.0 );
  453.                glTexCoord2f( (sliceIndex / (float)SLICES), 1.0 );  
  454.                glVertex3f( 0.0, radius, 0.0 );
  455.  
  456.                glNormal3fv( vertex[sliceIndex][0] ); 
  457.                glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
  458.                glVertex3f( (vertex[sliceIndex][0][0] * radius), 
  459.                            (vertex[sliceIndex][0][1] * radius),
  460.                            (vertex[sliceIndex][0][2] * radius) );
  461.  
  462.                glNormal3fv( vertex[(sliceIndex+1)][0] ); 
  463.                glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
  464.                glVertex3f( (vertex[(sliceIndex+1)][0][0] * radius),
  465.                            (vertex[(sliceIndex+1)][0][1] * radius),
  466.                            (vertex[(sliceIndex+1)][0][2] * radius) );
  467.             glEnd();
  468.  
  469.             /* Draw each slice. */
  470.             glBegin( GL_QUADS );
  471.                for ( stackIndex = 0; stackIndex < (STACKS-3); stackIndex++)
  472.                {
  473.                   glNormal3fv( vertex[sliceIndex][stackIndex] ); 
  474.                   glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  475.                   glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius), 
  476.                               (vertex[sliceIndex][stackIndex][1] * radius),
  477.                               (vertex[sliceIndex][stackIndex][2] * radius) );
  478.             
  479.                   glNormal3fv( vertex[sliceIndex][(stackIndex+1)] ); 
  480.                   glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
  481.                   glVertex3f( (vertex[sliceIndex][(stackIndex+1)][0] * radius), 
  482.                               (vertex[sliceIndex][(stackIndex+1)][1] * radius),
  483.                               (vertex[sliceIndex][(stackIndex+1)][2] * radius) );
  484.                   
  485.                   glNormal3fv( vertex[(sliceIndex+1)][(stackIndex+1)] ); 
  486.                   glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
  487.                   glVertex3f( (vertex[(sliceIndex+1)][(stackIndex+1)][0] * radius), 
  488.                               (vertex[(sliceIndex+1)][(stackIndex+1)][1] * radius),
  489.                               (vertex[(sliceIndex+1)][(stackIndex+1)][2] * radius) );
  490.                   
  491.                   glNormal3fv( vertex[(sliceIndex+1)][stackIndex] ); 
  492.                   glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  493.                   glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius), 
  494.                               (vertex[(sliceIndex+1)][stackIndex][1] * radius),
  495.                               (vertex[(sliceIndex+1)][stackIndex][2] * radius) );
  496.                }     
  497.             glEnd();
  498.  
  499.             /* Draw the special case which is the bottom triangle. */
  500.             glBegin( GL_TRIANGLES );
  501.                glNormal3fv( vertex[sliceIndex][stackIndex] ); 
  502.                glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  503.                glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius), 
  504.                            (vertex[sliceIndex][stackIndex][1] * radius),
  505.                            (vertex[sliceIndex][stackIndex][2] * radius) );
  506.  
  507.                glNormal3f( 0.0, -1.0, 0.0 );
  508.                glTexCoord2f( (sliceIndex / (float)SLICES), 0.0 );  
  509.                glVertex3f( 0.0, -radius, 0.0 );
  510.  
  511.                glNormal3fv( vertex[(sliceIndex+1)][stackIndex] ); 
  512.                glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  513.                glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius), 
  514.                            (vertex[(sliceIndex+1)][stackIndex][1] * radius),
  515.                            (vertex[(sliceIndex+1)][stackIndex][2] * radius) );
  516.             glEnd();
  517.          }
  518.       glPopMatrix();
  519.    }
  520.  
  521.    /*========================================================================*/
  522.    /*  Draw the inside surface only. Also check for texture mapping. I use   */
  523.    /* chose to use the vertices as normals again by flipping each one.       */
  524.    /*========================================================================*/
  525.    if ( (parts & INSIDE) || (parts & ALL) )
  526.    {
  527.       /* Draw the SLICES of the sphere. */
  528.       glPushMatrix();
  529.          for ( sliceIndex = 0; sliceIndex < SLICES; sliceIndex++)
  530.          {            
  531.             /* Draw the special case which is the top triangle. */
  532.             glBegin( GL_TRIANGLES );
  533.                glNormal3f( 0.0, -1.0, 0.0 );
  534.                glTexCoord2f( (sliceIndex / (float)SLICES), 1.0 );  
  535.                glVertex3f( 0.0, radius, 0.0 );
  536.  
  537.                glNormal3f( -vertex[(sliceIndex+1)][0][0], 
  538.                            -vertex[(sliceIndex+1)][0][1], 
  539.                            -vertex[(sliceIndex+1)][0][2] ); 
  540.                glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
  541.                glVertex3f( (vertex[(sliceIndex+1)][0][0] * radius),
  542.                            (vertex[(sliceIndex+1)][0][1] * radius),
  543.                            (vertex[(sliceIndex+1)][0][2] * radius) );
  544.  
  545.                glNormal3f( -vertex[sliceIndex][0][0],
  546.                            -vertex[sliceIndex][0][1],
  547.                            -vertex[sliceIndex][0][2] ); 
  548.                glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
  549.                glVertex3f( (vertex[sliceIndex][0][0] * radius), 
  550.                            (vertex[sliceIndex][0][1] * radius),
  551.                            (vertex[sliceIndex][0][2] * radius) );
  552.             glEnd();
  553.  
  554.             /* Draw each slice. */
  555.             glBegin( GL_QUADS );
  556.                for ( stackIndex = 0; stackIndex < (STACKS-3); stackIndex++)
  557.                {
  558.                   glNormal3f( -vertex[sliceIndex][stackIndex][0], 
  559.                               -vertex[sliceIndex][stackIndex][1], 
  560.                               -vertex[sliceIndex][stackIndex][2] ); 
  561.                   glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  562.                   glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius), 
  563.                               (vertex[sliceIndex][stackIndex][1] * radius),
  564.                               (vertex[sliceIndex][stackIndex][2] * radius) );
  565.             
  566.                   glNormal3f( -vertex[(sliceIndex+1)][stackIndex][0], 
  567.                               -vertex[(sliceIndex+1)][stackIndex][1], 
  568.                               -vertex[(sliceIndex+1)][stackIndex][2] ); 
  569.                   glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  570.                   glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius), 
  571.                               (vertex[(sliceIndex+1)][stackIndex][1] * radius),
  572.                               (vertex[(sliceIndex+1)][stackIndex][2] * radius) );
  573.  
  574.                   glNormal3f( -vertex[(sliceIndex+1)][(stackIndex+1)][0], 
  575.                               -vertex[(sliceIndex+1)][(stackIndex+1)][1], 
  576.                               -vertex[(sliceIndex+1)][(stackIndex+1)][2] ); 
  577.                   glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
  578.                   glVertex3f( (vertex[(sliceIndex+1)][(stackIndex+1)][0] * radius), 
  579.                               (vertex[(sliceIndex+1)][(stackIndex+1)][1] * radius),
  580.                               (vertex[(sliceIndex+1)][(stackIndex+1)][2] * radius) );
  581.                   
  582.                   glNormal3f( -vertex[sliceIndex][(stackIndex+1)][0], 
  583.                               -vertex[sliceIndex][(stackIndex+1)][1], 
  584.                               -vertex[sliceIndex][(stackIndex+1)][2] ); 
  585.                   glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
  586.                   glVertex3f( (vertex[sliceIndex][(stackIndex+1)][0] * radius), 
  587.                               (vertex[sliceIndex][(stackIndex+1)][1] * radius),
  588.                               (vertex[sliceIndex][(stackIndex+1)][2] * radius) );
  589.                }     
  590.             glEnd();
  591.  
  592.             /* Draw the special case which is the bottom triangle. */
  593.             glBegin( GL_TRIANGLES );
  594.                glNormal3f( -vertex[sliceIndex][stackIndex][0],
  595.                            -vertex[sliceIndex][stackIndex][1],
  596.                            -vertex[sliceIndex][stackIndex][2] ); 
  597.                glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  598.                glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius), 
  599.                            (vertex[sliceIndex][stackIndex][1] * radius),
  600.                            (vertex[sliceIndex][stackIndex][2] * radius) );
  601.  
  602.                glNormal3f( -vertex[(sliceIndex+1)][stackIndex][0],
  603.                            -vertex[(sliceIndex+1)][stackIndex][1],
  604.                            -vertex[(sliceIndex+1)][stackIndex][2] ); 
  605.                glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
  606.                glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius), 
  607.                            (vertex[(sliceIndex+1)][stackIndex][1] * radius),
  608.                            (vertex[(sliceIndex+1)][stackIndex][2] * radius) );
  609.  
  610.                glNormal3f( 0.0, 1.0, 0.0 );
  611.                glTexCoord2f( (sliceIndex / (float)SLICES), 0.0 );  
  612.                glVertex3f( 0.0, -radius, 0.0 );
  613.             glEnd();
  614.          }
  615.       glPopMatrix();
  616.    }
  617.  
  618.    /*========================================================================*/
  619.    /* Disable texure mapping now that all textured parts are finished.       */
  620.    /*========================================================================*/
  621.    if ( parts & TEXTURE_ON )
  622.       glDisable( GL_TEXTURE_2D );
  623. }
  624.  
  625. /*===========================================================================*/
  626. /*  This routine will draw two planes (zy & xy) using a wire grid. All three */
  627. /* axis will be draw as cylinders. The grid and axis will be a total length  */
  628. /* of 'gridSize' and the grids themselves will measure 'gridGap' wide.       */
  629. /*-------------------------------------------------------------------------- */
  630. /* flags = (GRID_ON | AXIS_ON)                                               */
  631. /*===========================================================================*/
  632. void   glObjGrids ( float gridSize, float gridGap, float radius, int flags )
  633. {
  634.     float matRed[]    = { 1.0, 0.0, 0.0, 1.0 };
  635.     float matYellow[] = { 1.0, 1.0, 0.0, 1.0 };
  636.     float matWhite[]  = { 1.0, 1.0, 1.0, 1.0 };
  637.     float matBlue[]   = { 0.0, 0.0, 1.0, 1.0 };
  638.     float matGreen[]  = { 0.0, 1.0, 0.0, 1.0 };
  639.  
  640.    int   index;
  641.  
  642.    /* Disable lighting because thease objects need not be realistic. */
  643.    glDisable( GL_LIGHTING );
  644.  
  645.    /* If the flag is set to GRID_ON then draw the grids. */
  646.    if ( (flags & GRID_ON) )
  647.    {
  648.       glPushMatrix();
  649.          glBegin( GL_LINES );
  650.             for ( index = -gridSize; index <= gridSize; index += gridGap )
  651.             {
  652.                /* Draw the x/z plane with its own color. */         
  653.                 glColor3fv( matWhite );
  654.                glVertex3f( index, 0.0, gridSize );           
  655.                glVertex3f( index, 0.0, -gridSize );           
  656.                glVertex3f( gridSize, 0.0, index );           
  657.                glVertex3f( -gridSize, 0.0, index );           
  658.  
  659.                /* Draw the y/z plane with its own color. */         
  660.                 glColor3fv( matYellow );
  661.                glVertex3f( 0.0, index, gridSize );           
  662.                glVertex3f( 0.0, index, -gridSize );           
  663.                glVertex3f( 0.0, gridSize, index );           
  664.                glVertex3f( 0.0, -gridSize, index );           
  665.             }
  666.          glEnd();
  667.       glPopMatrix();
  668.    }
  669.  
  670.    /* If the flag is set to AXIS_ON then draw the axis. */
  671.    if ( (flags & AXIS_ON) )
  672.    {
  673.       /* Draw the X-axis. */
  674.       glPushMatrix();
  675.           glColor3fv( matRed );
  676.          glRotatef( 90, 0.0, 0.0, 1.0 );
  677.          glObjCylinder( radius, (gridSize*2.0), SIDES );
  678.       glPopMatrix();
  679.  
  680.       /* Draw the Y-axis. */
  681.       glPushMatrix();
  682.           glColor3fv( matGreen );
  683.          glObjCylinder( radius, (gridSize*2.0), SIDES );
  684.       glPopMatrix();
  685.  
  686.       /* Draw the Z-axis. */
  687.       glPushMatrix();
  688.           glColor3fv( matBlue );
  689.          glRotatef( 90, 1.0, 0.0, 0.0 );
  690.          glObjCylinder( radius, (gridSize*2.0), SIDES );
  691.       glPopMatrix();
  692.    }
  693.  
  694.    /* Enable lighting again. Note the makes the assumption lighting was on. */
  695.    glEnable( GL_LIGHTING );
  696. }
  697.  
  698. /*===========================================================================*/
  699. /*  This routine will position a light given the light number and it will    */
  700. /* draw a sphere at the same position if 'show' is true. The size if the     */
  701. /* light is bigger the further the light is away from the origin. If the     */
  702. /* light is directional then x, y, z are degrees of rotation around thier    */
  703. /* axis using the default direction (0.0, 0.0, -1.0).                        */
  704. /*-------------------------------------------------------------------------- */
  705. /* lightNumber = 0 to 8 (maybe more if current version supports more).       */
  706. /* show        = (GL_TRUE | GL_FALSE)                                        */
  707. /* positional  = (GL_TRUE | GL_FALSE)                                        */
  708. /*===========================================================================*/
  709. void   glObjSetLight  ( int lightNumber, int show, int positional, float x, float y, float z )
  710. {
  711.    static   float light_position[] = { 0.0, 0.0, 0.0, 1.0 };
  712.    static   float light_directional[] = { 0.0, 0.0, -1.0, 0.0 };
  713.    static   float distance = -1.0;
  714.  
  715.    /* Set light0's position. */
  716.    glPushMatrix();
  717.       if ( positional == GL_TRUE )
  718.       {
  719.          glTranslatef( x, y, z );
  720.          glLightfv( (GL_LIGHT0+lightNumber), GL_POSITION,  light_position );
  721.       }
  722.       else
  723.       {
  724.          glRotatef( x, 1.0, 0.0, 0.0 );
  725.          glRotatef( y, 0.0, 1.0, 0.0 );
  726.          glRotatef( z, 0.0, 0.0, 1.0 );
  727.          glLightfv( (GL_LIGHT0+lightNumber), GL_POSITION,  light_directional );
  728.       }
  729.  
  730.       /* Draw a sphere where the light is if requested. */
  731.       if ( show == GL_TRUE )
  732.       {
  733.          /* Calculate the distance only once. */
  734.          if ( distance < 0.0 )
  735.             distance = sqrt( (x*x) + (y*y) + (z*z) );
  736.  
  737.          glDisable( GL_LIGHTING );
  738.             glColor3f( 1.0, 1.0, 0.0 );
  739.             glObjSphere( (distance/20.0), 0 );            
  740.          glEnable( GL_LIGHTING );
  741.       }
  742.    glPopMatrix();
  743. }
  744.  
  745.