|
|
各位大侠
我用以下算法自绘球体,该如何进行纹理映射。
#define M_PI 3.1415926
static void circleTable(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;
/* 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 circleTable");
}
/* Compute cos and sin around the circle */
for (i=0; i<size; i++)
{
(*sint) = sin(angle*i);
(*cost) = cos(angle*i);
}
/* Last sample is duplicate of the first */
(*sint)[size] = (*sint)[0];
(*cost)[size] = (*cost)[0];
}
/*
* 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
*/
/*
* Draws a solid sphere
*/
void renderSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
int i,j;
/* Adjust z and radius as stacks are drawn. */
double z0,z1;
double r0,r1;
/* Pre-computed circle */
double *sint1,*cost1;
double *sint2,*cost2;
circleTable(&sint1,&cost1,-slices);
circleTable(&sint2,&cost2,stacks*2);
/* The top stack is covered with a triangle fan */
z0 = 1.0;
z1 = cost2[1];
r0 = 0.0;
r1 = sint2[1];
glBegin(GL_TRIANGLE_FAN);
glNormal3d(0,0,1);
glVertex3d(0,0,radius);
for (j=slices; j>=0; j--)
{
glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 );
glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
}
glEnd();
/* Cover each stack with a quad strip, except the top and bottom stacks */
for( i=1; i<stacks-1; i++ )
{
z0 = z1; z1 = cost2[i+1];
r0 = r1; r1 = sint2[i+1];
glBegin(GL_QUAD_STRIP);
for(j=0; j<=slices; j++)
{
glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 );
glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 );
glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
}
glEnd();
}
/* The bottom stack is covered with a triangle fan */
z0 = z1;
r0 = r1;
glBegin(GL_TRIANGLE_FAN);
glNormal3d(0,0,-1);
glVertex3d(0,0,-radius);
for (j=0; j<=slices; j++)
{
glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 );
glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
}
glEnd();
/* Release sin and cos tables */
free(sint1);
free(cost1);
free(sint2);
free(cost2);
}
[em10] [em10] [em10] [em10] [em10] |
|