porting torus: split off vertex generation

fixed drawing to work with this



git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1266 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2012-04-28 10:57:40 +00:00
parent 5fbbc35cb5
commit fe89b94fc4

View File

@ -853,7 +853,7 @@ static void fghGenerateSphere(GLfloat radius, GLint slices, GLint stacks, GLfloa
/* Allocate vertex and normal buffers, bail out if memory allocation fails */ /* Allocate vertex and normal buffers, bail out if memory allocation fails */
*vertices = malloc((*nVert)*3*sizeof(GLfloat)); *vertices = malloc((*nVert)*3*sizeof(GLfloat));
*normals = malloc((*nVert)*3*sizeof(GLfloat)); *normals = malloc((*nVert)*3*sizeof(GLfloat));
if (!(vertices) || !(normals)) if (!(*vertices) || !(*normals))
{ {
free(*vertices); free(*vertices);
free(*normals); free(*normals);
@ -949,7 +949,7 @@ void fghGenerateCone(
/* Allocate vertex and normal buffers, bail out if memory allocation fails */ /* Allocate vertex and normal buffers, bail out if memory allocation fails */
*vertices = malloc((*nVert)*3*sizeof(GLfloat)); *vertices = malloc((*nVert)*3*sizeof(GLfloat));
*normals = malloc((*nVert)*3*sizeof(GLfloat)); *normals = malloc((*nVert)*3*sizeof(GLfloat));
if (!(vertices) || !(normals)) if (!(*vertices) || !(*normals))
{ {
free(*vertices); free(*vertices);
free(*normals); free(*normals);
@ -1031,7 +1031,7 @@ void fghGenerateCylinder(
/* Allocate vertex and normal buffers, bail out if memory allocation fails */ /* Allocate vertex and normal buffers, bail out if memory allocation fails */
*vertices = malloc((*nVert)*3*sizeof(GLfloat)); *vertices = malloc((*nVert)*3*sizeof(GLfloat));
*normals = malloc((*nVert)*3*sizeof(GLfloat)); *normals = malloc((*nVert)*3*sizeof(GLfloat));
if (!(vertices) || !(normals)) if (!(*vertices) || !(*normals))
{ {
free(*vertices); free(*vertices);
free(*normals); free(*normals);
@ -1098,6 +1098,67 @@ void fghGenerateCylinder(
free(sint); free(sint);
free(cost); free(cost);
} }
void fghGenerateTorus(
double dInnerRadius, double dOuterRadius, GLint nSides, GLint nRings, /* input */
GLfloat **vertices, GLfloat **normals, int* nVert /* output */
)
{
GLfloat iradius = (float)dInnerRadius;
GLfloat oradius = (float)dOuterRadius;
int i, j;
/* Pre-computed circle */
GLfloat *spsi, *cpsi;
GLfloat *sphi, *cphi;
/* number of unique vertices */
if (nSides<2 || nRings<2)
{
/* nothing to generate */
*nVert = 0;
return;
}
*nVert = nSides * nRings;
if ((*nVert) > 65535)
fgWarning("fghGenerateTorus: too many slices or stacks requested, indices will wrap");
/* precompute values on unit circle */
fghCircleTable(&spsi,&cpsi, nRings,FALSE);
fghCircleTable(&sphi,&cphi,-nSides,FALSE);
/* Allocate vertex and normal buffers, bail out if memory allocation fails */
*vertices = malloc((*nVert)*3*sizeof(GLfloat));
*normals = malloc((*nVert)*3*sizeof(GLfloat));
if (!(*vertices) || !(*normals))
{
free(*vertices);
free(*normals);
fgError("Failed to allocate memory in fghGenerateTorus");
}
for( j=0; j<nRings; j++ )
{
for( i=0; i<nSides; i++ )
{
int offset = 3 * ( j * nSides + i ) ;
(*vertices)[offset ] = cpsi[j] * ( oradius + cphi[i] * iradius ) ;
(*vertices)[offset+1] = spsi[j] * ( oradius + cphi[i] * iradius ) ;
(*vertices)[offset+2] = sphi[i] * iradius ;
(*normals )[offset ] = cpsi[j] * cphi[i] ;
(*normals )[offset+1] = spsi[j] * cphi[i] ;
(*normals )[offset+2] = sphi[i] ;
}
}
/* Release sin and cos tables */
free(spsi);
free(cpsi);
free(sphi);
free(cphi);
}
#endif #endif
/* -- INTERNAL DRAWING functions --------------------------------------- */ /* -- INTERNAL DRAWING functions --------------------------------------- */
@ -1700,91 +1761,47 @@ void FGAPIENTRY glutWireCylinder(double radius, double height, GLint slices, GLi
*/ */
void FGAPIENTRY glutWireTorus( double dInnerRadius, double dOuterRadius, GLint nSides, GLint nRings ) void FGAPIENTRY glutWireTorus( double dInnerRadius, double dOuterRadius, GLint nSides, GLint nRings )
{ {
GLfloat iradius = (float)dInnerRadius, oradius = (float)dOuterRadius; GLfloat *vertex, *normal;
GLfloat phi, psi, dpsi, dphi; int i, j, nVert;
GLfloat *vertex, *normal;
int i, j;
GLfloat spsi, cpsi, sphi, cphi ;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTorus" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTorus" );
if ( nSides < 1 ) nSides = 1;
if ( nRings < 1 ) nRings = 1;
/* Allocate the vertices array */ fghGenerateTorus(
vertex = (GLfloat *)calloc( sizeof(GLfloat), 3 * nSides * nRings ); dInnerRadius, dOuterRadius, nSides, nRings, /* input */
normal = (GLfloat *)calloc( sizeof(GLfloat), 3 * nSides * nRings ); &vertex, &normal, &nVert /* output */
);
glPushMatrix();
dpsi = 2.0f * (GLfloat)M_PI / (GLfloat)(nRings) ;
dphi = -2.0f * (GLfloat)M_PI / (GLfloat)(nSides) ;
psi = 0.0f;
for( j=0; j<nRings; j++ )
{
#ifdef __cplusplus
cpsi = cosf( psi ) ;
spsi = sinf( psi ) ;
#else
cpsi = (float)cos( (double)psi ) ;
spsi = (float)sin( (double)psi ) ;
#endif /* __cplusplus */
phi = 0.0f;
for( i=0; i<nSides; i++ ) for( i=0; i<nSides; i++ )
{ {
int offset = 3 * ( j * nSides + i ) ; glBegin( GL_LINE_LOOP );
#ifdef __cplusplus
cphi = cosf( phi ) ; for( j=0; j<nRings; j++ )
sphi = sinf( phi ) ; {
#else int offset = 3 * ( j * nSides + i ) ;
cphi = (float)cos( (double)phi ) ; glNormal3fv( normal + offset );
sphi = (float)sin( (double)phi ) ; glVertex3fv( vertex + offset );
#endif /* __cplusplus */ }
*(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
*(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ; glEnd();
*(vertex + offset + 2) = sphi * iradius ;
*(normal + offset + 0) = cpsi * cphi ;
*(normal + offset + 1) = spsi * cphi ;
*(normal + offset + 2) = sphi ;
phi += dphi;
} }
psi += dpsi;
}
for( i=0; i<nSides; i++ )
{
glBegin( GL_LINE_LOOP );
for( j=0; j<nRings; j++ ) for( j=0; j<nRings; j++ )
{ {
int offset = 3 * ( j * nSides + i ) ; glBegin(GL_LINE_LOOP);
glNormal3fv( normal + offset );
glVertex3fv( vertex + offset ); for( i=0; i<nSides; i++ )
{
int offset = 3 * ( j * nSides + i ) ;
glNormal3fv( normal + offset );
glVertex3fv( vertex + offset );
}
glEnd();
} }
glEnd(); free ( vertex ) ;
} free ( normal ) ;
for( j=0; j<nRings; j++ )
{
glBegin(GL_LINE_LOOP);
for( i=0; i<nSides; i++ )
{
int offset = 3 * ( j * nSides + i ) ;
glNormal3fv( normal + offset );
glVertex3fv( vertex + offset );
}
glEnd();
}
free ( vertex ) ;
free ( normal ) ;
glPopMatrix();
} }
/* /*
@ -1792,86 +1809,44 @@ void FGAPIENTRY glutWireTorus( double dInnerRadius, double dOuterRadius, GLint n
*/ */
void FGAPIENTRY glutSolidTorus( double dInnerRadius, double dOuterRadius, GLint nSides, GLint nRings ) void FGAPIENTRY glutSolidTorus( double dInnerRadius, double dOuterRadius, GLint nSides, GLint nRings )
{ {
GLfloat iradius = (float)dInnerRadius, oradius = (float)dOuterRadius; GLfloat *vertex, *normal;
GLfloat phi, psi, dpsi, dphi; int i, j, nVert;
GLfloat *vertex, *normal;
int i, j;
GLfloat spsi, cpsi, sphi, cphi ;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTorus" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTorus" );
if ( nSides < 1 ) nSides = 1;
if ( nRings < 1 ) nRings = 1;
/* Increment the number of sides and rings to allow for one more point than surface */ fghGenerateTorus(
nSides ++ ; dInnerRadius, dOuterRadius, nSides, nRings, /* input */
nRings ++ ; &vertex, &normal, &nVert /* output */
);
/* Allocate the vertices array */
vertex = (GLfloat *)calloc( sizeof(GLfloat), 3 * nSides * nRings );
normal = (GLfloat *)calloc( sizeof(GLfloat), 3 * nSides * nRings );
glPushMatrix();
dpsi = 2.0f * (GLfloat)M_PI / (GLfloat)(nRings - 1) ;
dphi = -2.0f * (GLfloat)M_PI / (GLfloat)(nSides - 1) ;
psi = 0.0f;
for( j=0; j<nRings; j++ )
{
#ifdef __cplusplus
cpsi = cosf( psi ) ;
spsi = sinf( psi ) ;
#else
cpsi = (float)cos( (double)psi ) ;
spsi = (float)sin( (double)psi ) ;
#endif /* __cplusplus */
phi = 0.0f;
glBegin( GL_QUADS );
for( i=0; i<nSides; i++ ) for( i=0; i<nSides; i++ )
{ {
int offset = 3 * ( j * nSides + i ) ; int ioff = 3;
#ifdef __cplusplus if (i==nSides-1)
cphi = cosf( phi ) ; ioff = -i*3;
sphi = sinf( phi ) ; for( j=0; j<nRings; j++ )
#else {
cphi = (float)cos( (double)phi ) ; int offset = 3 * ( j * nSides + i ) ;
sphi = (float)sin( (double)phi ) ; glNormal3fv( normal + offset );
#endif /* __cplusplus */ glVertex3fv( vertex + offset );
*(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ; glNormal3fv( normal + offset + ioff );
*(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ; glVertex3fv( vertex + offset + ioff );
*(vertex + offset + 2) = sphi * iradius ;
*(normal + offset + 0) = cpsi * cphi ; offset = 3 * ( ((j+1)%nRings) * nSides + i) ;
*(normal + offset + 1) = spsi * cphi ; glNormal3fv( normal + offset + ioff );
*(normal + offset + 2) = sphi ; glVertex3fv( vertex + offset + ioff );
phi += dphi; glNormal3fv( normal + offset );
glVertex3fv( vertex + offset );
}
} }
psi += dpsi; glEnd();
}
glBegin( GL_QUADS ); free ( vertex ) ;
for( i=0; i<nSides-1; i++ ) free ( normal ) ;
{
for( j=0; j<nRings-1; j++ )
{
int offset = 3 * ( j * nSides + i ) ;
glNormal3fv( normal + offset );
glVertex3fv( vertex + offset );
glNormal3fv( normal + offset + 3 );
glVertex3fv( vertex + offset + 3 );
glNormal3fv( normal + offset + 3 * nSides + 3 );
glVertex3fv( vertex + offset + 3 * nSides + 3 );
glNormal3fv( normal + offset + 3 * nSides );
glVertex3fv( vertex + offset + 3 * nSides );
}
}
glEnd();
free ( vertex ) ;
free ( normal ) ;
glPopMatrix();
} }
#endif /* EGL_VERSION_1_0 */ #endif /* EGL_VERSION_1_0 */