X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffg_geometry.c;h=77b09a790678529eba45d7c9afc85e7f4be1cd58;hb=44856885ba35db9526d24d140b84ce492f4871d2;hp=f52e13f2dab7c88bd3d6b62fab38cf3b825c4f90;hpb=ee9edf0b34600e68936e677163238f2f47367fae;p=freeglut diff --git a/src/fg_geometry.c b/src/fg_geometry.c index f52e13f..77b09a7 100644 --- a/src/fg_geometry.c +++ b/src/fg_geometry.c @@ -29,35 +29,7 @@ #include "fg_internal.h" /* - * TODO BEFORE THE STABLE RELEASE: - * - * See fghTetrahedron - * - * Following functions have been contributed by Andreas Umbach. - * - * glutWireCube() -- looks OK - * glutSolidCube() -- OK - * - * Those functions have been implemented by John Fay. - * - * glutWireTorus() -- looks OK - * glutSolidTorus() -- looks OK - * glutWireDodecahedron() -- looks OK - * glutSolidDodecahedron() -- looks OK - * glutWireOctahedron() -- looks OK - * glutSolidOctahedron() -- looks OK - * glutWireTetrahedron() -- looks OK - * glutSolidTetrahedron() -- looks OK - * glutWireIcosahedron() -- looks OK - * glutSolidIcosahedron() -- looks OK - * - * The Following functions have been updated by Nigel Stewart, based - * on FreeGLUT 2.0.0 implementations: - * - * glutWireSphere() -- looks OK - * glutSolidSphere() -- looks OK - * glutWireCone() -- looks OK - * glutSolidCone() -- looks OK + * Need more types of polyhedra? See CPolyhedron in MRPT */ @@ -67,49 +39,149 @@ * useWireMode controls the drawing of solids (false) or wire frame * versions (TRUE) of the geometry you pass */ -static void fghDrawGeometry(GLenum vertexMode, GLdouble* vertices, GLdouble* normals, GLsizei numVertices, GLboolean useWireMode) +static void fghDrawGeometry(GLdouble *vertices, GLdouble *normals, GLboolean *edgeFlags, GLsizei numVertices, GLsizei numFaces, GLsizei numEdgePerFace, GLboolean useWireMode) { +# ifdef FREEGLUT_GLES1 + /* Solid drawing is the same for OpenGL 1.x and OpenGL ES 1.x, just + * no edge flags for ES. + * WireFrame drawing will have to be done per face though, using + * GL_LINE_LOOP and issuing one draw call per face. For triangles, + * we use glDrawArrays directly on the vertex data for each face, + * while for shapes that are composed of quads or pentagons, we use + * glDrawElements with index vector {0,1,2,5} or {0,1,2,8,5}, + * respectively. + * We use the first parameter in glDrawArrays or glDrawElements to + * go from face to face. + */ if (useWireMode) { - glPushAttrib(GL_POLYGON_BIT); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } + /* setup reading the right elements from vertex array */ + GLubyte vertIdx4[4] = {0,1,2,5}; + GLubyte vertIdx5[5] = {0,1,2,8,5}; + GLubyte *indices = NULL; + int vertStride, i, j; + + switch (numEdgePerFace) + { + case 3: + vertStride = 3; /* there are 3 vertices for each face in the array */ + break; + case 4: + indices = vertIdx4; + vertStride = 6; /* there are 6 vertices for each face in the array */ + break; + case 5: + indices = vertIdx5; + vertStride = 9; /* there are 9 vertices for each face in the array */ + break; + } - 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); + + if (numEdgePerFace==3) + 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++ ) { int idx = i*3; - local_offset[0] = offset[0] + scale * tetr_v[idx ]; - local_offset[1] = offset[1] + scale * tetr_v[idx+1]; - local_offset[2] = offset[2] + scale * tetr_v[idx+2]; + 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 ); } } @@ -402,14 +696,28 @@ 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(name##_verts,name##_norms,edgeFlags,\ + nameCaps##_VERT_PER_OBJ_TRI,nameCaps##_NUM_FACES,nameCaps##_NUM_EDGE_PER_FACE,\ + 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 fghCube( GLdouble dSize, GLboolean useWireMode ) { if (!cubeCached) { fghCubeGenerate(); - cubeCached = TRUE; + cubeCached = GL_TRUE; } if (dSize!=1.) @@ -417,56 +725,57 @@ static void fghCube( GLdouble dSize, GLboolean useWireMode ) int i; /* Need to build new vertex list containing vertices for cube of different size */ - GLdouble *vertices = malloc(CUBE_VERT_ELEM_PER_CUBE * sizeof(GLdouble)); - for (i=0; i