X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_geometry.c;h=3c7a835a6ce02e9b999fdffc33dd99021d732bd6;hb=9807c5fdb2f20f098c7046786908a7f3ce1dc2d4;hp=5468551ceb70bf4e5a7910dca6a873febd75b6de;hpb=d6ccf7c81bdad11e6902a258e8e21fdbe6b9f968;p=freeglut diff --git a/src/freeglut_geometry.c b/src/freeglut_geometry.c index 5468551..3c7a835 100644 --- a/src/freeglut_geometry.c +++ b/src/freeglut_geometry.c @@ -25,10 +25,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include #include "freeglut_internal.h" @@ -72,12 +68,12 @@ void FGAPIENTRY glutWireCube( GLdouble dSize ) { double size = dSize * 0.5; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCube" ); + # define V(a,b,c) glVertex3d( a size, b size, c size ); # define N(a,b,c) glNormal3d( a, b, c ); - /* - * PWO: I dared to convert the code to use macros... - */ + /* PWO: I dared to convert the code to use macros... */ glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd(); glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd(); glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd(); @@ -96,12 +92,12 @@ void FGAPIENTRY glutSolidCube( GLdouble dSize ) { double size = dSize * 0.5; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCube" ); + # define V(a,b,c) glVertex3d( a size, b size, c size ); # define N(a,b,c) glNormal3d( a, b, c ); - /* - * PWO: Again, I dared to convert the code to use macros... - */ + /* PWO: Again, I dared to convert the code to use macros... */ glBegin( GL_QUADS ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); @@ -125,7 +121,7 @@ void FGAPIENTRY glutSolidCube( GLdouble dSize ) * The sign of n can be flipped to get the reverse loop */ -static void circleTable(double **sint,double **cost,const int n) +static void fghCircleTable(double **sint,double **cost,const int n) { int i; @@ -135,7 +131,7 @@ static void circleTable(double **sint,double **cost,const int n) /* Determine the angle between samples */ - const double angle = 2*M_PI/(double)n; + const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n ); /* Allocate memory for n samples, plus duplicate of first entry at the end */ @@ -148,12 +144,15 @@ static void circleTable(double **sint,double **cost,const int n) { free(*sint); free(*cost); - fgError("Failed to allocate memory in circleTable"); + fgError("Failed to allocate memory in fghCircleTable"); } /* Compute cos and sin around the circle */ - for (i=0; i0)?1:0]; r0 = 0.0; - r1 = sint2[1]; + r1 = sint2[(stacks>0)?1:0]; glBegin(GL_TRIANGLE_FAN); @@ -266,8 +268,11 @@ void FGAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks) double *sint1,*cost1; double *sint2,*cost2; - circleTable(&sint1,&cost1,-slices ); - circleTable(&sint2,&cost2, stacks*2); + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSphere" ); + + fghCircleTable(&sint1,&cost1,-slices ); + fghCircleTable(&sint2,&cost2, stacks*2); /* Draw a line loop for each stack */ @@ -329,8 +334,8 @@ void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLi double z0,z1; double r0,r1; - const double zStep = height/stacks; - const double rStep = base/stacks; + const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); + const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 ); /* Scaling factors for vertex normals */ @@ -340,7 +345,10 @@ void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLi /* Pre-computed circle */ double *sint,*cost; - circleTable(&sint,&cost,-slices); + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCone" ); + + fghCircleTable(&sint,&cost,-slices); /* Cover the circular base with a triangle fan... */ @@ -413,8 +421,8 @@ void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLin double z = 0.0; double r = base; - const double zStep = height/stacks; - const double rStep = base/stacks; + const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); + const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 ); /* Scaling factors for vertex normals */ @@ -424,7 +432,10 @@ void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLin /* Pre-computed circle */ double *sint,*cost; - circleTable(&sint,&cost,-slices); + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCone" ); + + fghCircleTable(&sint,&cost,-slices); /* Draw the stacks... */ @@ -475,13 +486,16 @@ void FGAPIENTRY glutSolidCylinder(GLdouble radius, GLdouble height, GLint slices /* Step in z and radius as stacks are drawn. */ - double z0,z1; - const double zStep = height/stacks; + double z0,z1; + const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); /* Pre-computed circle */ double *sint,*cost; - circleTable(&sint,&cost,-slices); + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCylinder" ); + + fghCircleTable(&sint,&cost,-slices); /* Cover the base and top */ @@ -537,12 +551,15 @@ void FGAPIENTRY glutWireCylinder(GLdouble radius, GLdouble height, GLint slices, /* Step in z and radius as stacks are drawn. */ double z = 0.0; - const double zStep = height/stacks; + const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); /* Pre-computed circle */ double *sint,*cost; - circleTable(&sint,&cost,-slices); + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCylinder" ); + + fghCircleTable(&sint,&cost,-slices); /* Draw the stacks... */ @@ -593,9 +610,12 @@ void FGAPIENTRY glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLi int i, j; double spsi, cpsi, sphi, cphi ; - /* - * Allocate the vertices array - */ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTorus" ); + + if ( nSides < 1 ) nSides = 1; + if ( nRings < 1 ) nRings = 1; + + /* Allocate the vertices array */ vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings ); normal = (double *)calloc( sizeof(double), 3 * nSides * nRings ); @@ -671,15 +691,16 @@ void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GL int i, j; double spsi, cpsi, sphi, cphi ; - /* - * Increment the number of sides and rings to allow for one more point than surface - */ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTorus" ); + + if ( nSides < 1 ) nSides = 1; + if ( nRings < 1 ) nRings = 1; + + /* Increment the number of sides and rings to allow for one more point than surface */ nSides ++ ; nRings ++ ; - /* - * Allocate the vertices array - */ + /* Allocate the vertices array */ vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings ); normal = (double *)calloc( sizeof(double), 3 * nSides * nRings ); @@ -741,10 +762,13 @@ void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GL */ void FGAPIENTRY glutWireDodecahedron( void ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireDodecahedron" ); + /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons to each face of * of a cube. The coordinates of the points are: * (+-x,0, z); (+-1, 1, 1); (0, z, x ) - * where x = 0.61803398875 and z = 1.61803398875. + * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2 or + * x = 0.61803398875 and z = 1.61803398875. */ glBegin ( GL_LINE_LOOP ) ; glNormal3d ( 0.0, 0.525731112119, 0.850650808354 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; @@ -791,10 +815,13 @@ void FGAPIENTRY glutWireDodecahedron( void ) */ void FGAPIENTRY glutSolidDodecahedron( void ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidDodecahedron" ); + /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons to each face of * of a cube. The coordinates of the points are: * (+-x,0, z); (+-1, 1, 1); (0, z, x ) - * where x = 0.61803398875 and z = 1.61803398875. + * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2 or + * x = 0.61803398875 and z = 1.61803398875. */ glBegin ( GL_POLYGON ) ; glNormal3d ( 0.0, 0.525731112119, 0.850650808354 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; @@ -841,16 +868,18 @@ void FGAPIENTRY glutSolidDodecahedron( void ) */ void FGAPIENTRY glutWireOctahedron( void ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireOctahedron" ); + #define RADIUS 1.0f glBegin( GL_LINE_LOOP ); glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); - glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); - glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); + glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); + glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); - glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); + glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); - glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); + glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); glEnd(); #undef RADIUS } @@ -860,45 +889,56 @@ void FGAPIENTRY glutWireOctahedron( void ) */ void FGAPIENTRY glutSolidOctahedron( void ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidOctahedron" ); + #define RADIUS 1.0f glBegin( GL_TRIANGLES ); glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); - glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); - glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); + glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); + glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); - glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); + glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); - glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); + glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); glEnd(); #undef RADIUS } +/* Magic Numbers: r0 = ( 1, 0, 0 ) + * r1 = ( -1/3, 2 sqrt(2) / 3, 0 ) + * r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 ) + * r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 ) + * |r0| = |r1| = |r2| = |r3| = 1 + * Distance between any two points is 2 sqrt(6) / 3 + * + * Normals: The unit normals are simply the negative of the coordinates of the point not on the surface. + */ + +#define NUM_TETR_FACES 4 + +static GLdouble tet_r[4][3] = { { 1.0, 0.0, 0.0 }, + { -0.333333333333, 0.942809041582, 0.0 }, + { -0.333333333333, -0.471404520791, 0.816496580928 }, + { -0.333333333333, -0.471404520791, -0.816496580928 } } ; + +static GLint tet_i[4][3] = /* Vertex indices */ +{ + { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 } +} ; + /* * */ void FGAPIENTRY glutWireTetrahedron( void ) { - /* Magic Numbers: r0 = ( 1, 0, 0 ) - * r1 = ( -1/3, 2 sqrt(2) / 3, 0 ) - * r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 ) - * r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 ) - * |r0| = |r1| = |r2| = |r3| = 1 - * Distance between any two points is 2 sqrt(6) / 3 - * - * Normals: The unit normals are simply the negative of the coordinates of the point not on the surface. - */ - - double r0[3] = { 1.0, 0.0, 0.0 } ; - double r1[3] = { -0.333333333333, 0.942809041582, 0.0 } ; - double r2[3] = { -0.333333333333, -0.471404520791, 0.816496580928 } ; - double r3[3] = { -0.333333333333, -0.471404520791, -0.816496580928 } ; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTetrahedron" ); glBegin( GL_LINE_LOOP ) ; - glNormal3d ( -1.0, 0.0, 0.0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r2 ) ; - glNormal3d ( 0.333333333333, -0.942809041582, 0.0 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r2 ) ; glVertex3dv ( r3 ) ; - glNormal3d ( 0.333333333333, 0.471404520791, -0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r1 ) ; - glNormal3d ( 0.333333333333, 0.471404520791, 0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r2 ) ; + glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ; + glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ; + glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ; + glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ; glEnd() ; } @@ -907,26 +947,13 @@ void FGAPIENTRY glutWireTetrahedron( void ) */ void FGAPIENTRY glutSolidTetrahedron( void ) { - /* Magic Numbers: r0 = ( 1, 0, 0 ) - * r1 = ( -1/3, 2 sqrt(2) / 3, 0 ) - * r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 ) - * r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 ) - * |r0| = |r1| = |r2| = |r3| = 1 - * Distance between any two points is 2 sqrt(6) / 3 - * - * Normals: The unit normals are simply the negative of the coordinates of the point not on the surface. - */ - - double r0[3] = { 1.0, 0.0, 0.0 } ; - double r1[3] = { -0.333333333333, 0.942809041582, 0.0 } ; - double r2[3] = { -0.333333333333, -0.471404520791, 0.816496580928 } ; - double r3[3] = { -0.333333333333, -0.471404520791, -0.816496580928 } ; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTetrahedron" ); glBegin( GL_TRIANGLES ) ; - glNormal3d ( -1.0, 0.0, 0.0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r2 ) ; - glNormal3d ( 0.333333333333, -0.942809041582, 0.0 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r2 ) ; glVertex3dv ( r3 ) ; - glNormal3d ( 0.333333333333, 0.471404520791, -0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r1 ) ; - glNormal3d ( 0.333333333333, 0.471404520791, 0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r2 ) ; + glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ; + glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ; + glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ; + glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ; glEnd() ; } @@ -945,6 +972,9 @@ int icos_v [20][3] = { { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 }, { 0, 4, 5 }, { 0, void FGAPIENTRY glutWireIcosahedron( void ) { int i ; + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireIcosahedron" ); + for ( i = 0; i < 20; i++ ) { double normal[3] ; @@ -967,6 +997,8 @@ void FGAPIENTRY glutSolidIcosahedron( void ) { int i ; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidIcosahedron" ); + glBegin ( GL_TRIANGLES ) ; for ( i = 0; i < 20; i++ ) { @@ -1003,6 +1035,9 @@ double rdod_n[12][3] = { void FGAPIENTRY glutWireRhombicDodecahedron( void ) { int i ; + + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireRhombicDodecahedron" ); + for ( i = 0; i < 12; i++ ) { glBegin ( GL_LINE_LOOP ) ; @@ -1022,6 +1057,8 @@ void FGAPIENTRY glutSolidRhombicDodecahedron( void ) { int i ; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidRhombicDodecahedron" ); + glBegin ( GL_QUADS ) ; for ( i = 0; i < 12; i++ ) { @@ -1035,45 +1072,24 @@ void FGAPIENTRY glutSolidRhombicDodecahedron( void ) glEnd () ; } -#define NUM_FACES 4 - -static GLdouble tetrahedron_v[4][3] = /* Vertices */ -{ - { -0.5, -0.288675134595, -0.144337567297 }, - { 0.5, -0.288675134595, -0.144337567297 }, - { 0.0, 0.577350269189, -0.144337567297 }, - { 0.0, 0.0, 0.672159013631 } -} ; - -static GLint tetrahedron_i[4][3] = /* Vertex indices */ -{ - { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 1, 3, 2 } -} ; - -static GLdouble tetrahedron_n[4][3] = /* Normals */ -{ - { 0.0, 0.0, -1.0 }, - { -0.816496580928, 0.471404520791, 0.333333333333 }, - { 0.0, -0.942809041582, 0.333333333333 }, - { 0.816496580928, 0.471404520791, 0.333333333333 } -} ; - void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) { int i, j ; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSierpinskiSponge" ); + if ( num_levels == 0 ) { - for ( i = 0 ; i < NUM_FACES ; i++ ) + for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) { glBegin ( GL_LINE_LOOP ) ; - glNormal3dv ( tetrahedron_n[i] ) ; + glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ; for ( j = 0; j < 3; j++ ) { - double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ; - double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ; - double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ; + double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ; + double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ; + double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ; glVertex3d ( x, y, z ) ; } @@ -1085,18 +1101,13 @@ void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], G GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */ num_levels -- ; scale /= 2.0 ; - local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ; - local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ; - local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ; - glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ; - local_offset[0] += scale ; - glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ; - local_offset[0] -= 0.5 * scale ; - local_offset[1] += 0.866025403784 * scale ; - glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ; - local_offset[1] -= 0.577350269189 * scale ; - local_offset[2] += 0.816496580928 * scale ; - glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ; + for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) + { + local_offset[0] = offset[0] + scale * tet_r[i][0] ; + local_offset[1] = offset[1] + scale * tet_r[i][1] ; + local_offset[2] = offset[2] + scale * tet_r[i][2] ; + glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ; + } } } @@ -1104,18 +1115,20 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], { int i, j ; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidSierpinskiSponge" ); + if ( num_levels == 0 ) { glBegin ( GL_TRIANGLES ) ; - for ( i = 0 ; i < NUM_FACES ; i++ ) + for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) { - glNormal3dv ( tetrahedron_n[i] ) ; + glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ; for ( j = 0; j < 3; j++ ) { - double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ; - double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ; - double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ; + double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ; + double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ; + double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ; glVertex3d ( x, y, z ) ; } } @@ -1127,21 +1140,14 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */ num_levels -- ; scale /= 2.0 ; - local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ; - local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ; - local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ; - glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ; - local_offset[0] += scale ; - glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ; - local_offset[0] -= 0.5 * scale ; - local_offset[1] += 0.866025403784 * scale ; - glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ; - local_offset[1] -= 0.577350269189 * scale ; - local_offset[2] += 0.816496580928 * scale ; - glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ; + for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) + { + local_offset[0] = offset[0] + scale * tet_r[i][0] ; + local_offset[1] = offset[1] + scale * tet_r[i][1] ; + local_offset[2] = offset[2] + scale * tet_r[i][2] ; + glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ; + } } } -#undef NUM_FACES - /*** END OF FILE ***/