diff --git a/freeglut/freeglut/src/fg_geometry.c b/freeglut/freeglut/src/fg_geometry.c index de1cbad..3a19a3b 100644 --- a/freeglut/freeglut/src/fg_geometry.c +++ b/freeglut/freeglut/src/fg_geometry.c @@ -31,6 +31,8 @@ /* * TODO BEFORE THE STABLE RELEASE: * + * See fghTetrahedron + * * Following functions have been contributed by Andreas Umbach. * * glutWireCube() -- looks OK @@ -59,7 +61,171 @@ */ -/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ +/* + * 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) +{ + if (useWireMode) + { + glPushAttrib(GL_POLYGON_BIT); + 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 (useWireMode) + { + glPopAttrib(); + } +} + + +/* -- INTERNAL SETUP OF GEOMETRY --------------------------------------- */ +/* -- first the cachable ones -- */ + +/* 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. +*/ + +/* -- TetraHedron -- */ +#define TETR_NUM_FACES 4 +#define TETR_NUM_VERT_PER_FACE 3 + +/* Vertex Coordinates */ +static GLdouble tet_r[TETR_NUM_FACES][TETR_NUM_VERT_PER_FACE] = +{ + { 1.0, 0.0, 0.0 }, + { -0.333333333333, 0.942809041582, 0.0 }, + { -0.333333333333, -0.471404520791, 0.816496580928 }, + { -0.333333333333, -0.471404520791, -0.816496580928 } +}; + +/* Vertex indices */ +static GLubyte tet_i[TETR_NUM_FACES][TETR_NUM_VERT_PER_FACE] = +{ + { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 } +}; +/* Normal indices */ +static GLubyte tet_n[TETR_NUM_FACES] = +{ + 0, 1, 2, 3 +}; + +/* Cache of input to glDrawArrays */ +static GLboolean tetrCached = FALSE; +static double tetr_verts[TETR_NUM_FACES * TETR_NUM_VERT_PER_FACE * 3]; +static double tetr_norms[TETR_NUM_FACES * TETR_NUM_VERT_PER_FACE * 3]; + +static void fghTetrahedronCache() +{ + int p,q; + /* + * Build array with vertices from vertex coordinates and vertex indices + * Do same for normals. + * Need to do this because of different normals at shared vertices + * (and because normals' coordinates need to be negated). + */ + for (p=0; p @@ -111,58 +277,6 @@ void FGAPIENTRY glutSolidCube( GLdouble dSize ) # undef N } -/* - * Compute lookup table of cos and sin values forming a cirle - * - * Notes: - * It is the responsibility of the caller to free these tables - * The size of the table is (n+1) to form a connected loop - * The last entry is exactly the same as the first - * The sign of n can be flipped to get the reverse loop - */ - -static void fghCircleTable(double **sint,double **cost,const int n) -{ - int i; - - /* Table size, the sign of n flips the circle direction */ - - const int size = abs(n); - - /* Determine the angle between samples */ - - const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n ); - - /* Allocate memory for n samples, plus duplicate of first entry at the end */ - - *sint = (double *) calloc(sizeof(double), size+1); - *cost = (double *) calloc(sizeof(double), size+1); - - /* Bail out if memory allocation fails, fgError never returns */ - - if (!(*sint) || !(*cost)) - { - free(*sint); - free(*cost); - fgError("Failed to allocate memory in fghCircleTable"); - } - - /* Compute cos and sin around the circle */ - - (*sint)[0] = 0.0; - (*cost)[0] = 1.0; - - for (i=1; i