X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffg_geometry.c;h=622633766e2fcf3ed4ef80dbaedbc4f66fb0b039;hb=945f4f58d76cf41fc073f2dd65eaa66a3a316407;hp=2ecf63c96b90aa2bd9ff2c2255114305be4260de;hpb=fae58eb47e5976cda391bd022fef7214ff05e11d;p=freeglut diff --git a/src/fg_geometry.c b/src/fg_geometry.c index 2ecf63c..6226337 100644 --- a/src/fg_geometry.c +++ b/src/fg_geometry.c @@ -61,14 +61,13 @@ */ -/* - * General function for drawing geometry. As for all geometry we have no +/* General function for drawing geometry. As for all geometry we have no * redundancy (or hardly any in the case of cones and cylinders) in terms * of the vertex/normal combinations, we just use glDrawArrays. * useWireMode controls the drawing of solids (false) or wire frame * versions (TRUE) of the geometry you pass */ -static void fghDrawGeometry(GLenum vertexMode, double* vertices, double* normals, GLsizei numVertices, GLboolean useWireMode) +static void fghDrawGeometry(GLenum vertexMode, GLdouble* vertices, GLdouble* normals, GLsizei numVertices, GLboolean useWireMode) { if (useWireMode) { @@ -76,15 +75,31 @@ static void fghDrawGeometry(GLenum vertexMode, double* vertices, double* normals glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + if (1) + { + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_DOUBLE, 0, vertices); - glNormalPointer(GL_DOUBLE, 0, normals); - glDrawArrays(vertexMode,0,numVertices); + glVertexPointer(3, GL_DOUBLE, 0, vertices); + glNormalPointer(GL_DOUBLE, 0, normals); + glDrawArrays(vertexMode, 0, numVertices); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + } + else + { + int i; + glBegin(vertexMode); + for(i=0; i 0 ) { GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */ - unsigned int stride = ipow(4,--numLevels)*TETR_VERT_ELEM_PER_TETR; + unsigned int stride = ipow(4,--numLevels)*TETRAHEDRON_VERT_ELEM_PER_OBJ; scale /= 2.0 ; - for ( i = 0 ; i < TETR_NUM_FACES ; i++ ) + for ( i = 0 ; i < TETRAHEDRON_NUM_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]; + int idx = i*3; + local_offset[0] = offset[0] + scale * tetrahedron_v[idx ]; + local_offset[1] = offset[1] + scale * tetrahedron_v[idx+1]; + local_offset[2] = offset[2] + scale * tetrahedron_v[idx+2]; fghSierpinskiSpongeGenerate ( numLevels, local_offset, scale, vertices+i*stride, normals+i*stride ); } } @@ -256,27 +464,55 @@ static void fghCircleTable(double **sint,double **cost,const int n) /* -- INTERNAL DRAWING functions to avoid code duplication ------------- */ +#define DECLARE_INTERNAL_DRAW(name,nameICaps,nameCaps)\ + static void fgh##nameICaps( GLboolean useWireMode )\ + {\ + if (!name##Cached)\ + {\ + fgh##nameICaps##Generate();\ + name##Cached = TRUE;\ + }\ + fghDrawGeometry(GL_TRIANGLES,name##_verts,name##_norms,nameCaps##_VERT_PER_OBJ,useWireMode);\ + } -static void fghTetrahedron( GLboolean useWireMode ) +static void fghCube( GLdouble dSize, GLboolean useWireMode ) { - if (!tetrCached) - fghTetrahedronGenerate(); + if (!cubeCached) + { + fghCubeGenerate(); + cubeCached = TRUE; + } + + if (dSize!=1.) + { + int i; - fghDrawGeometry(GL_TRIANGLES,tetr_verts,tetr_norms,TETR_VERT_PER_TETR,useWireMode); + /* Need to build new vertex list containing vertices for cube of different size */ + GLdouble *vertices = malloc(CUBE_VERT_ELEM_PER_OBJ * sizeof(GLdouble)); + for (i=0; i - */ -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... */ - 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(); - 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(); - -# undef V -# undef N -} - -/* - * Draws a solid cube. Code contributed by Andreas Umbach - */ -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... */ - 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(-,+,+); - N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); - N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); - N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); - N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); - glEnd(); - -# undef V -# undef N -} - /* * Draws a solid sphere @@ -1044,135 +1230,6 @@ 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, 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, 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 ); - glEnd(); -#undef RADIUS -} - -/* - * - */ -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, 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, 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 ); - glEnd(); -#undef RADIUS -} - -/* - * - */ -static double icos_r[12][3] = { - { 1.0, 0.0, 0.0 }, - { 0.447213595500, 0.894427191000, 0.0 }, - { 0.447213595500, 0.276393202252, 0.850650808354 }, - { 0.447213595500, -0.723606797748, 0.525731112119 }, - { 0.447213595500, -0.723606797748, -0.525731112119 }, - { 0.447213595500, 0.276393202252, -0.850650808354 }, - { -0.447213595500, -0.894427191000, 0.0 }, - { -0.447213595500, -0.276393202252, 0.850650808354 }, - { -0.447213595500, 0.723606797748, 0.525731112119 }, - { -0.447213595500, 0.723606797748, -0.525731112119 }, - { -0.447213595500, -0.276393202252, -0.850650808354 }, - { -1.0, 0.0, 0.0 } -}; - -static int icos_v [20][3] = { - { 0, 1, 2 }, - { 0, 2, 3 }, - { 0, 3, 4 }, - { 0, 4, 5 }, - { 0, 5, 1 }, - { 1, 8, 2 }, - { 2, 7, 3 }, - { 3, 6, 4 }, - { 4, 10, 5 }, - { 5, 9, 1 }, - { 1, 9, 8 }, - { 2, 8, 7 }, - { 3, 7, 6 }, - { 4, 6, 10 }, - { 5, 10, 9 }, - { 11, 9, 10 }, - { 11, 8, 9 }, - { 11, 7, 8 }, - { 11, 6, 7 }, - { 11, 10, 6 } -}; - -void FGAPIENTRY glutWireIcosahedron( void ) -{ - int i ; - - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireIcosahedron" ); - - for ( i = 0; i < 20; i++ ) - { - double normal[3] ; - normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ; - normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ; - normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ; - glBegin ( GL_LINE_LOOP ) ; - glNormal3dv ( normal ) ; - glVertex3dv ( icos_r[icos_v[i][0]] ) ; - glVertex3dv ( icos_r[icos_v[i][1]] ) ; - glVertex3dv ( icos_r[icos_v[i][2]] ) ; - glEnd () ; - } -} - -/* - * - */ -void FGAPIENTRY glutSolidIcosahedron( void ) -{ - int i ; - - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidIcosahedron" ); - - glBegin ( GL_TRIANGLES ) ; - for ( i = 0; i < 20; i++ ) - { - double normal[3] ; - normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ; - normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ; - normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ; - glNormal3dv ( normal ) ; - glVertex3dv ( icos_r[icos_v[i][0]] ) ; - glVertex3dv ( icos_r[icos_v[i][1]] ) ; - glVertex3dv ( icos_r[icos_v[i][2]] ) ; - } - - glEnd () ; -} - -/* - * - */ static double rdod_r[14][3] = { { 0.0, 0.0, 1.0 }, { 0.707106781187, 0.000000000000, 0.5 }, @@ -1263,19 +1320,33 @@ void FGAPIENTRY glutSolidRhombicDodecahedron( void ) /* -- INTERFACE FUNCTIONS -------------------------------------------------- */ +/* Macro to generate interface functions */ +#define DECLARE_SHAPE_INTERFACE(nameICaps)\ + void FGAPIENTRY glutWire##nameICaps( void )\ + {\ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWire"#nameICaps );\ + fgh##nameICaps( TRUE );\ + }\ + void FGAPIENTRY glutSolid##nameICaps( void )\ + {\ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolid"#nameICaps );\ + fgh##nameICaps( FALSE );\ + } - -void FGAPIENTRY glutWireTetrahedron( void ) +void FGAPIENTRY glutWireCube( GLdouble dSize ) { - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTetrahedron" ); - fghTetrahedron( TRUE ); + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCube" ); + fghCube( dSize, TRUE ); } -void FGAPIENTRY glutSolidTetrahedron( void ) +void FGAPIENTRY glutSolidCube( GLdouble dSize ) { - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTetrahedron" ); - fghTetrahedron( FALSE ); + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCube" ); + fghCube( dSize, FALSE ); } +DECLARE_SHAPE_INTERFACE(Icosahedron); +DECLARE_SHAPE_INTERFACE(Octahedron); + void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) { FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSierpinskiSponge" ); @@ -1287,5 +1358,7 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], fghSierpinskiSponge ( num_levels, offset, scale, FALSE ); } +DECLARE_SHAPE_INTERFACE(Tetrahedron); + /*** END OF FILE ***/