initial start at rewrite of fg_geometry functions, using glDrawArrays.
Tetrahedon done as example (seems to work well, but further comments pending) Done restructuring of the file as well git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1143 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
bae0c12952
commit
19a3927adc
@ -31,6 +31,8 @@
|
|||||||
/*
|
/*
|
||||||
* TODO BEFORE THE STABLE RELEASE:
|
* TODO BEFORE THE STABLE RELEASE:
|
||||||
*
|
*
|
||||||
|
* See fghTetrahedron
|
||||||
|
*
|
||||||
* Following functions have been contributed by Andreas Umbach.
|
* Following functions have been contributed by Andreas Umbach.
|
||||||
*
|
*
|
||||||
* glutWireCube() -- looks OK
|
* 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<TETR_NUM_FACES; p++)
|
||||||
|
{
|
||||||
|
for (q=0; q<TETR_NUM_VERT_PER_FACE; q++)
|
||||||
|
{
|
||||||
|
int idx = p*TETR_NUM_VERT_PER_FACE*3+q*3;
|
||||||
|
tetr_verts[idx ] = tet_r[tet_i[p][q]][0];
|
||||||
|
tetr_verts[idx+1] = tet_r[tet_i[p][q]][1];
|
||||||
|
tetr_verts[idx+2] = tet_r[tet_i[p][q]][2];
|
||||||
|
|
||||||
|
tetr_norms[idx ] = -tet_r[tet_n[p]][0];
|
||||||
|
tetr_norms[idx+1] = -tet_r[tet_n[p]][1];
|
||||||
|
tetr_norms[idx+2] = -tet_r[tet_n[p]][2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- Now the various shapes involving circles -- */
|
||||||
|
/*
|
||||||
|
* 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<size; i++)
|
||||||
|
{
|
||||||
|
(*sint)[i] = sin(angle*i);
|
||||||
|
(*cost)[i] = cos(angle*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last sample is duplicate of the first */
|
||||||
|
|
||||||
|
(*sint)[size] = (*sint)[0];
|
||||||
|
(*cost)[size] = (*cost)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -- INTERNAL DRAWING functions to avoid code duplication ------------- */
|
||||||
|
|
||||||
|
static void fghTetrahedron( GLboolean useWireMode )
|
||||||
|
{
|
||||||
|
if (!tetrCached)
|
||||||
|
fghTetrahedronCache();
|
||||||
|
|
||||||
|
fghDrawGeometry(GL_TRIANGLES,tetr_verts,tetr_norms,TETR_NUM_FACES*TETR_NUM_VERT_PER_FACE,useWireMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -- INTERFACE FUNCTIONS ---------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
|
* Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
|
||||||
@ -111,58 +277,6 @@ void FGAPIENTRY glutSolidCube( GLdouble dSize )
|
|||||||
# undef N
|
# 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<size; i++)
|
|
||||||
{
|
|
||||||
(*sint)[i] = sin(angle*i);
|
|
||||||
(*cost)[i] = cos(angle*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last sample is duplicate of the first */
|
|
||||||
|
|
||||||
(*sint)[size] = (*sint)[0];
|
|
||||||
(*cost)[size] = (*cost)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draws a solid sphere
|
* Draws a solid sphere
|
||||||
@ -905,58 +1019,6 @@ void FGAPIENTRY glutSolidOctahedron( void )
|
|||||||
#undef RADIUS
|
#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 )
|
|
||||||
{
|
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTetrahedron" );
|
|
||||||
|
|
||||||
glBegin( GL_LINE_LOOP ) ;
|
|
||||||
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() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void FGAPIENTRY glutSolidTetrahedron( void )
|
|
||||||
{
|
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTetrahedron" );
|
|
||||||
|
|
||||||
glBegin( GL_TRIANGLES ) ;
|
|
||||||
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() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -1143,7 +1205,7 @@ void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], G
|
|||||||
if ( num_levels == 0 )
|
if ( num_levels == 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
|
for ( i = 0 ; i < TETR_NUM_FACES ; i++ )
|
||||||
{
|
{
|
||||||
glBegin ( GL_LINE_LOOP ) ;
|
glBegin ( GL_LINE_LOOP ) ;
|
||||||
glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
|
glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
|
||||||
@ -1163,7 +1225,7 @@ void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], G
|
|||||||
GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
|
GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
|
||||||
num_levels -- ;
|
num_levels -- ;
|
||||||
scale /= 2.0 ;
|
scale /= 2.0 ;
|
||||||
for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
|
for ( i = 0 ; i < TETR_NUM_FACES ; i++ )
|
||||||
{
|
{
|
||||||
local_offset[0] = offset[0] + scale * tet_r[i][0] ;
|
local_offset[0] = offset[0] + scale * tet_r[i][0] ;
|
||||||
local_offset[1] = offset[1] + scale * tet_r[i][1] ;
|
local_offset[1] = offset[1] + scale * tet_r[i][1] ;
|
||||||
@ -1183,7 +1245,7 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3],
|
|||||||
{
|
{
|
||||||
glBegin ( GL_TRIANGLES ) ;
|
glBegin ( GL_TRIANGLES ) ;
|
||||||
|
|
||||||
for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
|
for ( i = 0 ; i < TETR_NUM_FACES ; i++ )
|
||||||
{
|
{
|
||||||
glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
|
glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
|
||||||
for ( j = 0; j < 3; j++ )
|
for ( j = 0; j < 3; j++ )
|
||||||
@ -1202,7 +1264,7 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3],
|
|||||||
GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
|
GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
|
||||||
num_levels -- ;
|
num_levels -- ;
|
||||||
scale /= 2.0 ;
|
scale /= 2.0 ;
|
||||||
for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
|
for ( i = 0 ; i < TETR_NUM_FACES ; i++ )
|
||||||
{
|
{
|
||||||
local_offset[0] = offset[0] + scale * tet_r[i][0] ;
|
local_offset[0] = offset[0] + scale * tet_r[i][0] ;
|
||||||
local_offset[1] = offset[1] + scale * tet_r[i][1] ;
|
local_offset[1] = offset[1] + scale * tet_r[i][1] ;
|
||||||
@ -1212,4 +1274,23 @@ void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
void FGAPIENTRY glutWireTetrahedron( void )
|
||||||
|
{
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTetrahedron" );
|
||||||
|
|
||||||
|
fghTetrahedron( TRUE );
|
||||||
|
}
|
||||||
|
void FGAPIENTRY glutSolidTetrahedron( void )
|
||||||
|
{
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTetrahedron" );
|
||||||
|
|
||||||
|
fghTetrahedron( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** END OF FILE ***/
|
/*** END OF FILE ***/
|
||||||
|
Reference in New Issue
Block a user