X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;ds=sidebyside;f=src%2Ffreeglut_geometry.c;h=36f6a78c413c9ae456d0c1b8bc74192f7acdd424;hb=02d1360233aa5a71d0f46fda6c6956c5122fad80;hp=98f2046f6955c4bc997b1ef600ed5675dfd5fdf3;hpb=98ea79ef777bea593a87aef9600ee3d4fda6e110;p=freeglut diff --git a/src/freeglut_geometry.c b/src/freeglut_geometry.c index 98f2046..36f6a78 100644 --- a/src/freeglut_geometry.c +++ b/src/freeglut_geometry.c @@ -30,6 +30,8 @@ #endif #include "../include/GL/freeglut.h" + + #include "freeglut_internal.h" /* @@ -39,13 +41,6 @@ * * glutWireCube() -- looks OK * glutSolidCube() -- OK - * glutWireSphere() -- OK - * glutSolidSphere() -- OK - * - * Following functions have been implemented by Pawel and modified by John Fay: - * - * glutWireCone() -- looks OK - * glutSolidCone() -- looks OK * * Those functions have been implemented by John Fay. * @@ -59,6 +54,14 @@ * 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 */ @@ -115,370 +118,471 @@ void FGAPIENTRY glutSolidCube( GLdouble dSize ) } /* - * Draws a wire sphere. Code contributed by Andreas Umbach + * 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 */ -void FGAPIENTRY glutWireSphere( GLdouble dRadius, GLint slices, GLint stacks ) + +static void circleTable(double **sint,double **cost,const int n) { - double radius = dRadius, phi, psi, dpsi, dphi; - double *vertex; - int i, j; - double cphi, sphi, cpsi, spsi ; + int i; - /* - * Allocate the vertices array - */ - vertex = (double *)calloc( sizeof(double), 3 * slices * (stacks - 1) ); + /* Table size, the sign of n flips the circle direction */ - glPushMatrix(); - glScaled( radius, radius, radius ); + const int size = abs(n); - dpsi = M_PI / (stacks + 1); - dphi = 2 * M_PI / slices; - psi = dpsi; + /* Determine the angle between samples */ - for( j=0; j=0; j--) + { + glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); + glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); } - glNormal3d(0, 0, -1); - glVertex3d(0, 0, -1); + glEnd(); + + /* Cover each stack with a quad strip, except the top and bottom stacks */ + + for( i=1; i + * Draws a solid sphere */ -void FGAPIENTRY glutSolidSphere( GLdouble dRadius, GLint slices, GLint stacks ) +void FGAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks) { - double radius = dRadius, phi, psi, dpsi, dphi; - double *next, *tmp, *row; - int i, j; - double cphi, sphi, cpsi, spsi ; + int i,j; - glPushMatrix(); - /* glScalef( radius, radius, radius ); */ + /* Adjust z and radius as stacks and slices are drawn. */ - row = (double *)calloc( sizeof(double), slices * 3 ); - next = (double *)calloc( sizeof(double), slices * 3 ); + double r; + double x,y,z; - dpsi = M_PI / (stacks + 1); - dphi = 2 * M_PI / slices; - psi = dpsi; - phi = 0; + /* Pre-computed circle */ + + double *sint1,*cost1; + double *sint2,*cost2; + circleTable(&sint1,&cost1,-slices ); + circleTable(&sint2,&cost2, stacks*2); - /* init first line + do polar cap */ - glBegin( GL_TRIANGLE_FAN ); - glNormal3d( 0.0, 0.0, 1.0 ); - glVertex3d( 0.0, 0.0, radius ); + /* Draw a line loop for each stack */ - for( i=0; i=0; i-- ) + double z0,z1; + double r0,r1; + + const double zStep = height/stacks; + const double rStep = base/stacks; + + /* Scaling factors for vertex normals */ + + const double cosn = ( height / sqrt ( height * height + base * base )); + const double sinn = ( base / sqrt ( height * height + base * base )); + + /* Pre-computed circle */ + + double *sint,*cost; + circleTable(&sint,&cost,-slices); + + /* Cover the circular base with a triangle fan... */ + + z0 = 0.0; + z1 = zStep; + + r0 = base; + r1 = r0 - rStep; + + glBegin(GL_TRIANGLE_FAN); + + glNormal3d(0.0,0.0,-1.0); + glVertex3d(0.0,0.0, z0 ); + + for (j=0; j<=slices; j++) + glVertex3d(cost[j]*r0, sint[j]*r0, z0); + + glEnd(); + + /* Cover each stack with a quad strip, except the top stack */ + + for( i=0; i=0; j--) + glVertex3d(cost[j]*radius, sint[j]*radius, height); + glEnd(); + + /* Do the stacks */ + + z0 = 0.0; + z1 = zStep; - for( j=0; j