X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffg_geometry.c;h=49164327b39dc66273b1c5c28a33f8bc55112033;hb=4bccc79f4b895ec88fec28c49471d04a025804fe;hp=2ecf63c96b90aa2bd9ff2c2255114305be4260de;hpb=fae58eb47e5976cda391bd022fef7214ff05e11d;p=freeglut diff --git a/src/fg_geometry.c b/src/fg_geometry.c index 2ecf63c..4916432 100644 --- a/src/fg_geometry.c +++ b/src/fg_geometry.c @@ -29,6 +29,9 @@ #include "fg_internal.h" /* + * + * Need more types of polyhedra? See CPolyhedron in MRPT + * * TODO BEFORE THE STABLE RELEASE: * * See fghTetrahedron @@ -61,14 +64,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, GLboolean *edgeFlags, GLsizei numVertices, GLboolean useWireMode) { if (useWireMode) { @@ -76,15 +78,38 @@ static void fghDrawGeometry(GLenum vertexMode, double* vertices, double* normals glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - glVertexPointer(3, GL_DOUBLE, 0, vertices); - glNormalPointer(GL_DOUBLE, 0, normals); - glDrawArrays(vertexMode,0,numVertices); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + if (1) + { + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + if (edgeFlags) + glEnableClientState(GL_EDGE_FLAG_ARRAY); + + glVertexPointer(3, GL_DOUBLE, 0, vertices); + glNormalPointer(GL_DOUBLE, 0, normals); + if (edgeFlags) + glEdgeFlagPointer(0,edgeFlags); + glDrawArrays(vertexMode, 0, numVertices); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + if (edgeFlags) + glDisableClientState(GL_EDGE_FLAG_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 ); } } @@ -255,34 +588,66 @@ static void fghCircleTable(double **sint,double **cost,const int n) } -/* -- INTERNAL DRAWING functions to avoid code duplication ------------- */ +/* -- INTERNAL DRAWING functions --------------------------------------- */ +#define _DECLARE_INTERNAL_DRAW_DO_DECLARE(name,nameICaps,nameCaps,edgeFlags)\ + static void fgh##nameICaps( GLboolean useWireMode )\ + {\ + if (!name##Cached)\ + {\ + fgh##nameICaps##Generate();\ + name##Cached = GL_TRUE;\ + }\ + fghDrawGeometry(GL_TRIANGLES,name##_verts,name##_norms,edgeFlags,nameCaps##_VERT_PER_OBJ_TRI,useWireMode);\ + } +#define DECLARE_INTERNAL_DRAW(name,nameICaps,nameCaps) _DECLARE_INTERNAL_DRAW_DO_DECLARE(name,nameICaps,nameCaps,NULL) +#define DECLARE_INTERNAL_DRAW_DECOMPOSED_TO_TRIANGLE(name,nameICaps,nameCaps) _DECLARE_INTERNAL_DRAW_DO_DECLARE(name,nameICaps,nameCaps,name##_edgeFlags) -static void fghTetrahedron( GLboolean useWireMode ) +static void fghCube( GLdouble dSize, GLboolean useWireMode ) { - if (!tetrCached) - fghTetrahedronGenerate(); + if (!cubeCached) + { + fghCubeGenerate(); + cubeCached = GL_TRUE; + } - fghDrawGeometry(GL_TRIANGLES,tetr_verts,tetr_norms,TETR_VERT_PER_TETR,useWireMode); + if (dSize!=1.) + { + int i; + + /* 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 @@ -1041,241 +1356,37 @@ void FGAPIENTRY glutSolidDodecahedron( void ) glEnd () ; } -/* - * - */ -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 }, - { 0.000000000000, 0.707106781187, 0.5 }, - { -0.707106781187, 0.000000000000, 0.5 }, - { 0.000000000000, -0.707106781187, 0.5 }, - { 0.707106781187, 0.707106781187, 0.0 }, - { -0.707106781187, 0.707106781187, 0.0 }, - { -0.707106781187, -0.707106781187, 0.0 }, - { 0.707106781187, -0.707106781187, 0.0 }, - { 0.707106781187, 0.000000000000, -0.5 }, - { 0.000000000000, 0.707106781187, -0.5 }, - { -0.707106781187, 0.000000000000, -0.5 }, - { 0.000000000000, -0.707106781187, -0.5 }, - { 0.0, 0.0, -1.0 } -} ; - -static int rdod_v [12][4] = { - { 0, 1, 5, 2 }, - { 0, 2, 6, 3 }, - { 0, 3, 7, 4 }, - { 0, 4, 8, 1 }, - { 5, 10, 6, 2 }, - { 6, 11, 7, 3 }, - { 7, 12, 8, 4 }, - { 8, 9, 5, 1 }, - { 5, 9, 13, 10 }, - { 6, 10, 13, 11 }, - { 7, 11, 13, 12 }, - { 8, 12, 13, 9 } -}; - -static double rdod_n[12][3] = { - { 0.353553390594, 0.353553390594, 0.5 }, - { -0.353553390594, 0.353553390594, 0.5 }, - { -0.353553390594, -0.353553390594, 0.5 }, - { 0.353553390594, -0.353553390594, 0.5 }, - { 0.000000000000, 1.000000000000, 0.0 }, - { -1.000000000000, 0.000000000000, 0.0 }, - { 0.000000000000, -1.000000000000, 0.0 }, - { 1.000000000000, 0.000000000000, 0.0 }, - { 0.353553390594, 0.353553390594, -0.5 }, - { -0.353553390594, 0.353553390594, -0.5 }, - { -0.353553390594, -0.353553390594, -0.5 }, - { 0.353553390594, -0.353553390594, -0.5 } -}; - -void FGAPIENTRY glutWireRhombicDodecahedron( void ) -{ - int i ; - - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireRhombicDodecahedron" ); - - for ( i = 0; i < 12; i++ ) - { - glBegin ( GL_LINE_LOOP ) ; - glNormal3dv ( rdod_n[i] ) ; - glVertex3dv ( rdod_r[rdod_v[i][0]] ) ; - glVertex3dv ( rdod_r[rdod_v[i][1]] ) ; - glVertex3dv ( rdod_r[rdod_v[i][2]] ) ; - glVertex3dv ( rdod_r[rdod_v[i][3]] ) ; - glEnd () ; - } -} - -/* - * - */ -void FGAPIENTRY glutSolidRhombicDodecahedron( void ) -{ - int i ; - - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidRhombicDodecahedron" ); - - glBegin ( GL_QUADS ) ; - for ( i = 0; i < 12; i++ ) - { - glNormal3dv ( rdod_n[i] ) ; - glVertex3dv ( rdod_r[rdod_v[i][0]] ) ; - glVertex3dv ( rdod_r[rdod_v[i][1]] ) ; - glVertex3dv ( rdod_r[rdod_v[i][2]] ) ; - glVertex3dv ( rdod_r[rdod_v[i][3]] ) ; - } - - glEnd () ; -} - /* -- 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); +DECLARE_SHAPE_INTERFACE(RhombicDodecahedron); + void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) { FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSierpinskiSponge" ); @@ -1287,5 +1398,7 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], fghSierpinskiSponge ( num_levels, offset, scale, FALSE ); } +DECLARE_SHAPE_INTERFACE(Tetrahedron); + /*** END OF FILE ***/