home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vrml2gl.zip
/
LIB
/
GLOBJ.C
next >
Wrap
C/C++ Source or Header
|
1997-02-25
|
35KB
|
745 lines
#include "glObjects.h"
/*===========================================================================*/
/* This function will draw a cude centered at the origin give width, height */
/* and depth. */
/* parts = TEXTURE_ON */
/*===========================================================================*/
void glObjCube( float width, float height, float depth, int parts )
{
static float vertex[8][3];
width /= 2.0;
height /= 2.0;
depth /= 2.0;
vertex[0][0] = -width; vertex[1][0] = width; vertex[2][0] = width; vertex[3][0] = -width;
vertex[0][1] = height; vertex[1][1] = height; vertex[2][1] = height; vertex[3][1] = height;
vertex[0][2] = depth; vertex[1][2] = depth; vertex[2][2] = -depth; vertex[3][2] = -depth;
vertex[4][0] = -width; vertex[5][0] = width; vertex[6][0] = width; vertex[7][0] = -width;
vertex[4][1] = -height; vertex[5][1] = -height; vertex[6][1] = -height; vertex[7][1] = -height;
vertex[4][2] = depth; vertex[5][2] = depth; vertex[6][2] = -depth; vertex[7][2] = -depth;
/* Enable texture mapping if requested. */
if ( parts == TEXTURE_ON )
glEnable( GL_TEXTURE_2D );
glPushMatrix();
glBegin( GL_QUADS );
/* Top Face. */
glNormal3f( 0.0, 1.0, 0.0 );
glTexCoord2f( 0.0, 0.0 ); /* Top left. */
glVertex3fv( vertex[0] );
glTexCoord2f( 1.0, 0.0 ); /* Top right. */
glVertex3fv( vertex[1] );
glTexCoord2f( 1.0, 1.0 ); /* Bottom right. */
glVertex3fv( vertex[2] );
glTexCoord2f( 0.0, 1.0 ); /* Bottom left. */
glVertex3fv( vertex[3] );
/* Back Face. */
glNormal3f( 0.0, 0.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); /* Top left. */
glVertex3fv( vertex[2] );
glTexCoord2f( 0.0, 0.0 ); /* Bottom left. */
glVertex3fv( vertex[6] );
glTexCoord2f( 1.0, 0.0 ); /* Bottom right. */
glVertex3fv( vertex[7] );
glTexCoord2f( 1.0, 1.0 ); /* Top right. */
glVertex3fv( vertex[3] );
/* Bottom Face. */
glNormal3f( 0.0, -1.0, 0.0 );
glTexCoord2f( 1.0, 0.0 ); /* Top right. */
glVertex3fv( vertex[4] );
glTexCoord2f( 1.0, 1.0 ); /* Bottom right. */
glVertex3fv( vertex[7] );
glTexCoord2f( 0.0, 1.0 ); /* Bottom left. */
glVertex3fv( vertex[6] );
glTexCoord2f( 0.0, 0.0 ); /* Top left. */
glVertex3fv( vertex[5] );
/* Front Face. */
glNormal3f( 0.0, 0.0, 1.0 );
glTexCoord2f( 0.0, 1.0 ); /* Top left. */
glVertex3fv( vertex[0] );
glTexCoord2f( 0.0, 0.0 ); /* Bottom left. */
glVertex3fv( vertex[4] );
glTexCoord2f( 1.0, 0.0 ); /* Bottom right. */
glVertex3fv( vertex[5] );
glTexCoord2f( 1.0, 1.0 ); /* Top right. */
glVertex3fv( vertex[1] );
/* Right Face. */
glNormal3f( 1.0, 0.0, 0.0 );
glTexCoord2f( 0.0, 1.0 ); /* Top left. */
glVertex3fv( vertex[1] );
glTexCoord2f( 0.0, 0.0 ); /* Bottom left. */
glVertex3fv( vertex[5] );
glTexCoord2f( 1.0, 0.0 ); /* Bottom right. */
glVertex3fv( vertex[6] );
glTexCoord2f( 1.0, 1.0 ); /* Top right. */
glVertex3fv( vertex[2] );
/* Left Face. */
glNormal3f( -1.0, 0.0, 0.0 );
glTexCoord2f( 0.0, 1.0 ); /* Top left. */
glVertex3fv( vertex[3] );
glTexCoord2f( 0.0, 0.0 ); /* Bottom left. */
glVertex3fv( vertex[7] );
glTexCoord2f( 1.0, 0.0 ); /* Bottom right. */
glVertex3fv( vertex[4] );
glTexCoord2f( 1.0, 1.0 ); /* Top right. */
glVertex3fv( vertex[0] );
glEnd();
glPopMatrix();
/* Disable texture mapping if it was used. */
if ( parts == TEXTURE_ON )
glDisable( GL_TEXTURE_2D );
}
/*===========================================================================*/
/* This function will draw a cylinder centered at the origin. The function */
/* takes a radius height and a bitmask. The first time called it will create */
/* a list of vertices that are unit length. Then only the radius needs to be */
/* multilplied instead of the radius and trig functions. */
/*-------------------------------------------------------------------------- */
/* #define NUM_CYLINDER_FACES 16 */
/* parts = (ALL | TOP | BOTTOM | SIDES | TEXTURE_ON) */
/*===========================================================================*/
void glObjCylinder ( float radius, float height, int parts )
{
static int index;
static float vertex[NUM_CYLINDER_FACES][2],
normal[NUM_CYLINDER_FACES][2];
static int isBuilt = GL_FALSE;
/* Build the vertices only once. */
if ( isBuilt == GL_FALSE )
{
/* Set all the vertices and normal for a unit length circle. */
for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
{
normal[index][0] = vertex[index][0] = sin(TWOPIE*index / (NUM_CYLINDER_FACES-1)) * -1.0;
normal[index][1] = vertex[index][1] = cos(TWOPIE*index / (NUM_CYLINDER_FACES-1)) * -1.0;
}
}
/*========================================================================*/
/* Draw the textured parts first then the non-textured. */
/*========================================================================*/
if ( parts & TEXTURE_ON )
glEnable( GL_TEXTURE_2D );
/* Draw the top of the cylinder if ALL or TOP is set. */
if ( (parts & ALL) || (parts & TOP) )
{
glPushMatrix();
glTranslatef( 0.0, (height/2.0), 0.0 );
glBegin( GL_TRIANGLE_FAN );
glNormal3f( 0.0, 1.0, 0.0 );
glTexCoord2f( 0.5, 0.5 );
glVertex3f( 0.0, 0.0, 0.0 );
for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
{
glTexCoord2f( (0.5+(vertex[index][0]/2.0)), (0.5+(vertex[index][1]/-2.0)) );
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
}
glTexCoord2f( (0.5+(vertex[0][0]/2.0)), (0.5+(vertex[0][1]/2.0)) );
glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
glEnd();
glPopMatrix();
}
/* Draw the bottom of the cylinder if ALL or BOTTOM is set. */
if ( (parts & ALL) || (parts & BOTTOM) )
{
glPushMatrix();
glFrontFace( GL_CW );
glTranslatef( 0.0, -(height/2.0), 0.0 );
glBegin( GL_TRIANGLE_FAN );
glNormal3f( 0.0, -1.0, 0.0 );
glTexCoord2f( 0.5, 0.5 );
glVertex3f( 0.0, 0.0, 0.0 );
for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
{
glTexCoord2f( (0.5+(vertex[index][0]/2.0)), (0.5+(vertex[index][1]/-2.0)) );
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
}
glTexCoord2f( (0.5+(vertex[0][0]/2.0)), (0.5+(vertex[0][1]/2.0)) );
glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
glEnd();
glFrontFace( GL_CCW );
glPopMatrix();
}
/* Draw the sides of the cylinder if ALL or SIDES is set. */
if ( (parts & ALL) || (parts & SIDES) )
{
glPushMatrix();
glTranslatef( 0.0, (height/2.0), 0.0 );
glBegin( GL_QUADS );
for ( index = 0; index < (NUM_CYLINDER_FACES-1); index++ )
{
glNormal3f( normal[index][0], 0.0, normal[index][1] );
glTexCoord2f( (index/(NUM_CYLINDER_FACES-2.0)), 1.0 );
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
glTexCoord2f( (index/(NUM_CYLINDER_FACES-2.0)), 0.0 );
glVertex3f( (vertex[index][0]*radius), -height, (vertex[index][1]*radius) );
glNormal3f( normal[(index+1)][0], 0.0, normal[(index+1)][1] );
glTexCoord2f( ((index+1)/(NUM_CYLINDER_FACES-2.0)), 0.0 );
glVertex3f( (vertex[(index+1)][0]*radius), -height, (vertex[(index+1)][1]*radius) );
glTexCoord2f( ((index+1)/(NUM_CYLINDER_FACES-2.0)), 1.0 );
glVertex3f( (vertex[(index+1)][0]*radius), 0.0, (vertex[(index+1)][1]*radius) );
}
glEnd();
glPopMatrix();
}
/*========================================================================*/
/* Disable texure mapping now that all textured parts are finished. */
/*========================================================================*/
if ( parts & TEXTURE_ON )
glDisable( GL_TEXTURE_2D );
/* Draw the inner side of the top of the cylinder if only TOP is set. */
if ( parts & TOP )
{
glPushMatrix();
glFrontFace( GL_CW );
glTranslatef( 0.0, (height/2.0), 0.0 );
glBegin( GL_TRIANGLE_FAN );
glNormal3f( 0.0, -1.0, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
glEnd();
glFrontFace( GL_CCW );
glPopMatrix();
}
/* Draw the inner side of the bottom of the cylinder if only BOTTOM is set. */
if ( parts & BOTTOM )
{
glPushMatrix();
glTranslatef( 0.0, -(height/2.0), 0.0 );
glBegin( GL_TRIANGLE_FAN );
glNormal3f( 0.0, 1.0, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
for ( index = 0; index < NUM_CYLINDER_FACES; index++ )
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][1]*radius) );
glEnd();
glPopMatrix();
}
/* Draw the inner side of the sides of the cylinder if only SIDES is set. */
if ( parts & SIDES )
{
glPushMatrix();
glFrontFace( GL_CW );
glTranslatef( 0.0, (height/2.0), 0.0 );
glBegin( GL_QUADS );
for ( index = 0; index < (NUM_CYLINDER_FACES-1); index++ )
{
glNormal3f( -normal[index][0], 0.0, -normal[index][1] );
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][1]*radius) );
glVertex3f( (vertex[index][0]*radius), -height, (vertex[index][1]*radius) );
glNormal3f( -normal[(index+1)][0], 0.0, -normal[(index+1)][1] );
glVertex3f( (vertex[(index+1)][0]*radius), -height, (vertex[(index+1)][1]*radius) );
glVertex3f( (vertex[(index+1)][0]*radius), 0.0, (vertex[(index+1)][1]*radius) );
}
glEnd();
glFrontFace( GL_CCW );
glPopMatrix();
}
}
/*===========================================================================*/
/* This function will draw a cone centered at the origin. The function takes*/
/* a radius height and a bitmask. The first time called it will create a list*/
/* of vertices that are unit length. Then only the radius needs to be */
/* multilplied instead of the radius and trig functions. */
/*-------------------------------------------------------------------------- */
/* parts = (ALL | BOTTOM | SIDES | TEXTURE_ON) */
/*===========================================================================*/
void glObjCone ( float radius, float height, int parts )
{
static int index;
static float topPoint[3],
tempNormal[3],
vertex[NUM_CONE_FACES][3];
static int isBuilt = GL_FALSE;
/* Build the vertices only once. */
if ( isBuilt == GL_FALSE )
{
/* Set all the vertices for a unit length circle. Thease will also */
/* be used as part of the normals. */
for ( index = 0; index < NUM_CONE_FACES; index++ )
{
vertex[index][0] = sin(TWOPIE*index / (NUM_CONE_FACES-1)) * -1.0;
vertex[index][1] = 0.0;
vertex[index][2] = cos(TWOPIE*index / (NUM_CONE_FACES-1)) * -1.0;
}
/* Mark the top point of the cone. */
topPoint[0] = 0.0;
topPoint[1] = height;
topPoint[2] = 0.0;
}
/*========================================================================*/
/* Draw the textured parts first then the non-textured. */
/*========================================================================*/
if ( parts & TEXTURE_ON )
glEnable( GL_TEXTURE_2D );
/* Draw the bottom of the cone if ALL or BOTTOM is set. */
if ( (parts & ALL) || (parts & BOTTOM) )
{
glPushMatrix();
glFrontFace( GL_CW );
glTranslatef( 0.0, -(height/2.0), 0.0 );
glBegin( GL_TRIANGLE_FAN );
glNormal3f( 0.0, -1.0, 0.0 );
glTexCoord2f( 0.5, 0.5 );
glVertex3f( 0.0, 0.0, 0.0 );
for ( index = 0; index < NUM_CONE_FACES; index++ )
{
glTexCoord2f( (0.5+(vertex[index][0]/2.0)), (0.5+(vertex[index][2]/-2.0)) );
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][2]*radius) );
}
glTexCoord2f( (0.5+(vertex[0][0]/2.0)), (0.5+(vertex[0][2]/2.0)) );
glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][2]*radius) );
glEnd();
glFrontFace( GL_CCW );
glPopMatrix();
}
/* Draw the sides of the cone if ALL or SIDES are set. */
if ( (parts & ALL) || (parts & SIDES) )
{
glPushMatrix();
glTranslatef( 0.0, -(height/2.0), 0.0 );
glBegin( GL_TRIANGLES );
for ( index = 0; index < (NUM_CONE_FACES-1); index++ )
{
/* Calculate the face normal and use it only for the tip. */
glMathGetNormalfv3f( vertex[(index+1)], topPoint, vertex[index], tempNormal );
glNormal3fv( tempNormal );
glTexCoord2f( (index/(NUM_CONE_FACES-1.0)), 1.0 );
glVertex3fv( topPoint );
/* Use the vertex's x,z for the normal along with y component from the face's normal . */
glNormal3f( vertex[index][0], tempNormal[1], vertex[index][2] );
glTexCoord2f( (index/(NUM_CONE_FACES-1.0)), 0.0 );
glVertex3f( (vertex[index][0]*radius), (vertex[index][1]*radius), (vertex[index][2]*radius) );
/* Use the vertex's x,z for the normal along with y component from the face's normal . */
glNormal3f( vertex[(index+1)][0], tempNormal[1], vertex[(index+1)][2] );
glTexCoord2f( ((index+1)/(NUM_CONE_FACES-1.0)), 0.0 );
glVertex3f( (vertex[(index+1)][0]*radius), (vertex[(index+1)][1]*radius), (vertex[(index+1)][2]*radius) );
}
glEnd();
glPopMatrix();
}
/*========================================================================*/
/* Disable texure mapping now that all textured parts are finished. */
/*========================================================================*/
if ( parts & TEXTURE_ON )
glDisable( GL_TEXTURE_2D );
/* Draw the inner side of the bottom of the cone if only BOTTOM is set. */
if ( (parts & ALL) || (parts & BOTTOM) )
{
glPushMatrix();
glTranslatef( 0.0, -(height/2.0), 0.0 );
glBegin( GL_TRIANGLE_FAN );
glNormal3f( 0.0, 1.0, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
for ( index = 0; index < NUM_CONE_FACES; index++ )
glVertex3f( (vertex[index][0]*radius), 0.0, (vertex[index][2]*radius) );
glVertex3f( (vertex[0][0]*radius), 0.0, (vertex[0][2]*radius) );
glEnd();
glPopMatrix();
}
/* Draw the inner part of the sides of the cone if only SIDES is set. */
if ( parts & SIDES )
{
glPushMatrix();
glTranslatef( 0.0, -(height/2.0), 0.0 );
glBegin( GL_TRIANGLES );
for ( index = 0; index < (NUM_CONE_FACES-1); index++ )
{
/* Calculate the face normal and use it only for the tip. */
glMathGetNormalfv3f( vertex[(index+1)], topPoint, vertex[index], tempNormal );
/* Use the vertex's x,z for the normal along with y component from the face's normal . */
glNormal3f( -vertex[(index+1)][0], -tempNormal[1], -vertex[(index+1)][2] );
glVertex3f( (vertex[(index+1)][0]*radius), (vertex[(index+1)][1]*radius), (vertex[(index+1)][2]*radius) );
/* Use the vertex's x,z for the normal along with y component from the face's normal . */
glNormal3f( -vertex[index][0], -tempNormal[1], -vertex[index][2] );
glVertex3f( (vertex[index][0]*radius), (vertex[index][1]*radius), (vertex[index][2]*radius) );
/* Use the face's normal for the top point. */
glNormal3f( -tempNormal[0], -tempNormal[1], -tempNormal[2] );
glVertex3fv( topPoint );
}
glEnd();
glPopMatrix();
}
}
/*===========================================================================*/
/* This function will draw a sphere centered at the origin. The function */
/* takes radius. */
/*---------------------------------------------------------------------------*/
/* parts = (TEXTURE_ON | INSIDE | OUTSIDE | ALL) */
/*===========================================================================*/
void glObjSphere ( float radius, int parts )
{
static int sliceIndex,
stackIndex;
static float theta,
phi;
static float vertex[(SLICES+1)][(STACKS-1)][3];
static int isBuilt = GL_FALSE;
/* Build the vertices only once. The vertices will also be used as the */
/* normals for smooth shading. I also multiply by -1 to get the texture */
/* orientation right. */
if ( isBuilt == GL_FALSE)
{
for ( sliceIndex = 0; sliceIndex < (SLICES+1); sliceIndex++)
{
theta = (TWOPIE / (float)SLICES) * (float)sliceIndex;
for ( stackIndex = 1; stackIndex < STACKS; stackIndex++)
{
phi = (PIE / (float)STACKS) * (float)stackIndex;
vertex[sliceIndex][(stackIndex-1)][0] = sin(phi) * sin(theta) * -1.0;
vertex[sliceIndex][(stackIndex-1)][1] = cos(phi);
vertex[sliceIndex][(stackIndex-1)][2] = sin(phi) * cos(theta) * -1.0;
}
}
isBuilt = GL_TRUE;
}
/*========================================================================*/
/* Draw the outside of the surface only. Check for texture mapping also. */
/*========================================================================*/
if ( parts & TEXTURE_ON )
glEnable( GL_TEXTURE_2D );
if ( (parts & OUTSIDE) || (parts & ALL) )
{
/* Draw the SLICES of the sphere starting from the -Z axis to the */
/* -X axis back to the -Z axis. */
glPushMatrix();
for ( sliceIndex = 0; sliceIndex < SLICES; sliceIndex++)
{
/* Draw the special case which is the top triangle. */
glBegin( GL_TRIANGLES );
glNormal3f( 0.0, 1.0, 0.0 );
glTexCoord2f( (sliceIndex / (float)SLICES), 1.0 );
glVertex3f( 0.0, radius, 0.0 );
glNormal3fv( vertex[sliceIndex][0] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][0][0] * radius),
(vertex[sliceIndex][0][1] * radius),
(vertex[sliceIndex][0][2] * radius) );
glNormal3fv( vertex[(sliceIndex+1)][0] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][0][0] * radius),
(vertex[(sliceIndex+1)][0][1] * radius),
(vertex[(sliceIndex+1)][0][2] * radius) );
glEnd();
/* Draw each slice. */
glBegin( GL_QUADS );
for ( stackIndex = 0; stackIndex < (STACKS-3); stackIndex++)
{
glNormal3fv( vertex[sliceIndex][stackIndex] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius),
(vertex[sliceIndex][stackIndex][1] * radius),
(vertex[sliceIndex][stackIndex][2] * radius) );
glNormal3fv( vertex[sliceIndex][(stackIndex+1)] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][(stackIndex+1)][0] * radius),
(vertex[sliceIndex][(stackIndex+1)][1] * radius),
(vertex[sliceIndex][(stackIndex+1)][2] * radius) );
glNormal3fv( vertex[(sliceIndex+1)][(stackIndex+1)] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][(stackIndex+1)][0] * radius),
(vertex[(sliceIndex+1)][(stackIndex+1)][1] * radius),
(vertex[(sliceIndex+1)][(stackIndex+1)][2] * radius) );
glNormal3fv( vertex[(sliceIndex+1)][stackIndex] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius),
(vertex[(sliceIndex+1)][stackIndex][1] * radius),
(vertex[(sliceIndex+1)][stackIndex][2] * radius) );
}
glEnd();
/* Draw the special case which is the bottom triangle. */
glBegin( GL_TRIANGLES );
glNormal3fv( vertex[sliceIndex][stackIndex] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius),
(vertex[sliceIndex][stackIndex][1] * radius),
(vertex[sliceIndex][stackIndex][2] * radius) );
glNormal3f( 0.0, -1.0, 0.0 );
glTexCoord2f( (sliceIndex / (float)SLICES), 0.0 );
glVertex3f( 0.0, -radius, 0.0 );
glNormal3fv( vertex[(sliceIndex+1)][stackIndex] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius),
(vertex[(sliceIndex+1)][stackIndex][1] * radius),
(vertex[(sliceIndex+1)][stackIndex][2] * radius) );
glEnd();
}
glPopMatrix();
}
/*========================================================================*/
/* Draw the inside surface only. Also check for texture mapping. I use */
/* chose to use the vertices as normals again by flipping each one. */
/*========================================================================*/
if ( (parts & INSIDE) || (parts & ALL) )
{
/* Draw the SLICES of the sphere. */
glPushMatrix();
for ( sliceIndex = 0; sliceIndex < SLICES; sliceIndex++)
{
/* Draw the special case which is the top triangle. */
glBegin( GL_TRIANGLES );
glNormal3f( 0.0, -1.0, 0.0 );
glTexCoord2f( (sliceIndex / (float)SLICES), 1.0 );
glVertex3f( 0.0, radius, 0.0 );
glNormal3f( -vertex[(sliceIndex+1)][0][0],
-vertex[(sliceIndex+1)][0][1],
-vertex[(sliceIndex+1)][0][2] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][0][0] * radius),
(vertex[(sliceIndex+1)][0][1] * radius),
(vertex[(sliceIndex+1)][0][2] * radius) );
glNormal3f( -vertex[sliceIndex][0][0],
-vertex[sliceIndex][0][1],
-vertex[sliceIndex][0][2] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - (1.0 / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][0][0] * radius),
(vertex[sliceIndex][0][1] * radius),
(vertex[sliceIndex][0][2] * radius) );
glEnd();
/* Draw each slice. */
glBegin( GL_QUADS );
for ( stackIndex = 0; stackIndex < (STACKS-3); stackIndex++)
{
glNormal3f( -vertex[sliceIndex][stackIndex][0],
-vertex[sliceIndex][stackIndex][1],
-vertex[sliceIndex][stackIndex][2] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius),
(vertex[sliceIndex][stackIndex][1] * radius),
(vertex[sliceIndex][stackIndex][2] * radius) );
glNormal3f( -vertex[(sliceIndex+1)][stackIndex][0],
-vertex[(sliceIndex+1)][stackIndex][1],
-vertex[(sliceIndex+1)][stackIndex][2] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius),
(vertex[(sliceIndex+1)][stackIndex][1] * radius),
(vertex[(sliceIndex+1)][stackIndex][2] * radius) );
glNormal3f( -vertex[(sliceIndex+1)][(stackIndex+1)][0],
-vertex[(sliceIndex+1)][(stackIndex+1)][1],
-vertex[(sliceIndex+1)][(stackIndex+1)][2] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][(stackIndex+1)][0] * radius),
(vertex[(sliceIndex+1)][(stackIndex+1)][1] * radius),
(vertex[(sliceIndex+1)][(stackIndex+1)][2] * radius) );
glNormal3f( -vertex[sliceIndex][(stackIndex+1)][0],
-vertex[sliceIndex][(stackIndex+1)][1],
-vertex[sliceIndex][(stackIndex+1)][2] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+2) / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][(stackIndex+1)][0] * radius),
(vertex[sliceIndex][(stackIndex+1)][1] * radius),
(vertex[sliceIndex][(stackIndex+1)][2] * radius) );
}
glEnd();
/* Draw the special case which is the bottom triangle. */
glBegin( GL_TRIANGLES );
glNormal3f( -vertex[sliceIndex][stackIndex][0],
-vertex[sliceIndex][stackIndex][1],
-vertex[sliceIndex][stackIndex][2] );
glTexCoord2f( (sliceIndex / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[sliceIndex][stackIndex][0] * radius),
(vertex[sliceIndex][stackIndex][1] * radius),
(vertex[sliceIndex][stackIndex][2] * radius) );
glNormal3f( -vertex[(sliceIndex+1)][stackIndex][0],
-vertex[(sliceIndex+1)][stackIndex][1],
-vertex[(sliceIndex+1)][stackIndex][2] );
glTexCoord2f( ((sliceIndex+1) / (float)SLICES), (1.0 - ((stackIndex+1) / (float)STACKS)) );
glVertex3f( (vertex[(sliceIndex+1)][stackIndex][0] * radius),
(vertex[(sliceIndex+1)][stackIndex][1] * radius),
(vertex[(sliceIndex+1)][stackIndex][2] * radius) );
glNormal3f( 0.0, 1.0, 0.0 );
glTexCoord2f( (sliceIndex / (float)SLICES), 0.0 );
glVertex3f( 0.0, -radius, 0.0 );
glEnd();
}
glPopMatrix();
}
/*========================================================================*/
/* Disable texure mapping now that all textured parts are finished. */
/*========================================================================*/
if ( parts & TEXTURE_ON )
glDisable( GL_TEXTURE_2D );
}
/*===========================================================================*/
/* This routine will draw two planes (zy & xy) using a wire grid. All three */
/* axis will be draw as cylinders. The grid and axis will be a total length */
/* of 'gridSize' and the grids themselves will measure 'gridGap' wide. */
/*-------------------------------------------------------------------------- */
/* flags = (GRID_ON | AXIS_ON) */
/*===========================================================================*/
void glObjGrids ( float gridSize, float gridGap, float radius, int flags )
{
float matRed[] = { 1.0, 0.0, 0.0, 1.0 };
float matYellow[] = { 1.0, 1.0, 0.0, 1.0 };
float matWhite[] = { 1.0, 1.0, 1.0, 1.0 };
float matBlue[] = { 0.0, 0.0, 1.0, 1.0 };
float matGreen[] = { 0.0, 1.0, 0.0, 1.0 };
int index;
/* Disable lighting because thease objects need not be realistic. */
glDisable( GL_LIGHTING );
/* If the flag is set to GRID_ON then draw the grids. */
if ( (flags & GRID_ON) )
{
glPushMatrix();
glBegin( GL_LINES );
for ( index = -gridSize; index <= gridSize; index += gridGap )
{
/* Draw the x/z plane with its own color. */
glColor3fv( matWhite );
glVertex3f( index, 0.0, gridSize );
glVertex3f( index, 0.0, -gridSize );
glVertex3f( gridSize, 0.0, index );
glVertex3f( -gridSize, 0.0, index );
/* Draw the y/z plane with its own color. */
glColor3fv( matYellow );
glVertex3f( 0.0, index, gridSize );
glVertex3f( 0.0, index, -gridSize );
glVertex3f( 0.0, gridSize, index );
glVertex3f( 0.0, -gridSize, index );
}
glEnd();
glPopMatrix();
}
/* If the flag is set to AXIS_ON then draw the axis. */
if ( (flags & AXIS_ON) )
{
/* Draw the X-axis. */
glPushMatrix();
glColor3fv( matRed );
glRotatef( 90, 0.0, 0.0, 1.0 );
glObjCylinder( radius, (gridSize*2.0), SIDES );
glPopMatrix();
/* Draw the Y-axis. */
glPushMatrix();
glColor3fv( matGreen );
glObjCylinder( radius, (gridSize*2.0), SIDES );
glPopMatrix();
/* Draw the Z-axis. */
glPushMatrix();
glColor3fv( matBlue );
glRotatef( 90, 1.0, 0.0, 0.0 );
glObjCylinder( radius, (gridSize*2.0), SIDES );
glPopMatrix();
}
/* Enable lighting again. Note the makes the assumption lighting was on. */
glEnable( GL_LIGHTING );
}
/*===========================================================================*/
/* This routine will position a light given the light number and it will */
/* draw a sphere at the same position if 'show' is true. The size if the */
/* light is bigger the further the light is away from the origin. If the */
/* light is directional then x, y, z are degrees of rotation around thier */
/* axis using the default direction (0.0, 0.0, -1.0). */
/*-------------------------------------------------------------------------- */
/* lightNumber = 0 to 8 (maybe more if current version supports more). */
/* show = (GL_TRUE | GL_FALSE) */
/* positional = (GL_TRUE | GL_FALSE) */
/*===========================================================================*/
void glObjSetLight ( int lightNumber, int show, int positional, float x, float y, float z )
{
static float light_position[] = { 0.0, 0.0, 0.0, 1.0 };
static float light_directional[] = { 0.0, 0.0, -1.0, 0.0 };
static float distance = -1.0;
/* Set light0's position. */
glPushMatrix();
if ( positional == GL_TRUE )
{
glTranslatef( x, y, z );
glLightfv( (GL_LIGHT0+lightNumber), GL_POSITION, light_position );
}
else
{
glRotatef( x, 1.0, 0.0, 0.0 );
glRotatef( y, 0.0, 1.0, 0.0 );
glRotatef( z, 0.0, 0.0, 1.0 );
glLightfv( (GL_LIGHT0+lightNumber), GL_POSITION, light_directional );
}
/* Draw a sphere where the light is if requested. */
if ( show == GL_TRUE )
{
/* Calculate the distance only once. */
if ( distance < 0.0 )
distance = sqrt( (x*x) + (y*y) + (z*z) );
glDisable( GL_LIGHTING );
glColor3f( 1.0, 1.0, 0.0 );
glObjSphere( (distance/20.0), 0 );
glEnable( GL_LIGHTING );
}
glPopMatrix();
}