From b728f245550aed93c5e33dbccb58ced002f41959 Mon Sep 17 00:00:00 2001 From: Diederick Niehorster Date: Sun, 25 Mar 2012 10:13:52 +0000 Subject: [PATCH] ported sphere. Drawing code is still in the sphere function, that and the vertex index generating code can hopefully be abstracted away. But first need to port the other shapes so I have a better idea of the overlap. (sorry Sylvain! Just don't touch the sphere for now) git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1209 7f0cb862-5218-0410-a997-914c9d46530a --- src/fg_geometry.c | 337 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 209 insertions(+), 128 deletions(-) diff --git a/src/fg_geometry.c b/src/fg_geometry.c index ccbe5d7..438d447 100644 --- a/src/fg_geometry.c +++ b/src/fg_geometry.c @@ -60,8 +60,8 @@ static void fghDrawGeometryWire(GLfloat *vertices, GLfloat *normals, GLsizei num glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); } -/** - * Draw the geometric shape with filled triangles + +/* Draw the geometric shape with filled triangles * * - If the shape is naturally triangulated (numEdgePerFace==3), each * vertex+normal pair is used only once, so no vertex indices. @@ -86,6 +86,8 @@ static void fghDrawGeometrySolid(GLfloat *vertices, GLfloat *normals, GLubyte *v glDisableClientState(GL_NORMAL_ARRAY); } + + /* Shape decomposition to triangles * We'll use glDrawElements to draw all shapes that are not naturally * composed of triangles, so generate an index vector here, using the @@ -632,6 +634,81 @@ static void fghCircleTable(GLfloat **sint, GLfloat **cost, const int n, const GL } } +static void fghGenerateSphere(GLfloat radius, GLint slices, GLint stacks, GLfloat **vertices, GLfloat **normals, int* nVert) +{ + int i,j; + int idx = 0; /* idx into vertex/normal buffer */ + GLfloat x,y,z; + + /* Pre-computed circle */ + GLfloat *sint1,*cost1; + GLfloat *sint2,*cost2; + + /* number of unique vertices */ + if (slices==0 || stacks<2) + { + /* nothing to generate */ + *nVert = 0; + return; + } + *nVert = slices*(stacks-1)+2; + + /* precompute values on unit circle */ + fghCircleTable(&sint1,&cost1,-slices,FALSE); + fghCircleTable(&sint2,&cost2, stacks,TRUE); + + /* 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 fghGenerateSphere"); + } + + /* top */ + (*vertices)[0] = 0.f; + (*vertices)[1] = 0.f; + (*vertices)[2] = radius; + (*normals )[0] = 0.f; + (*normals )[1] = 0.f; + (*normals )[2] = 1.f; + idx = 3; + + /* each stack */ + for( i=1; i0)?1:0]; - r0 = 0; - r1 = sint2[(stacks>0)?1:0]; + /* draw */ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); - glBegin(GL_TRIANGLE_FAN); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glNormalPointer(GL_FLOAT, 0, normals); + /*draw slices*/ + for (i=0; i=0; j--) + /* cleanup allocated memory */ + free(sliceIdx); + free(stackIdx); + } + else + { + GLuint *topIdx, *bottomIdx, *stripIdx; + /* First, generate vertex index arrays for drawing with glDrawElements + * Top and bottom are covered with a triangle fan + * Each other stack with triangle strip. Only need to generate on + * of those as we'll have to draw each stack separately, and can + * just use different offsets in glDrawElements. + */ + + /* Allocate buffers for indices, bail out if memory allocation fails */ + topIdx = malloc((slices+2)*sizeof(GLuint)); + bottomIdx = malloc((slices+2)*sizeof(GLuint)); + stripIdx = malloc((slices+1)*2*(stacks-2)*sizeof(GLuint)); + if (!(topIdx) || !(bottomIdx) || !(stripIdx)) { - glNormal3f(cost1[j]*r1, sint1[j]*r1, z1 ); - glVertex3f(cost1[j]*r1*radf, sint1[j]*r1*radf, z1*radf); + free(topIdx); + free(bottomIdx); + free(stripIdx); + fgError("Failed to allocate memory in fghGenerateSphere"); } - glEnd(); + topIdx[0]=0; + topIdx[1] = 1; /* repeat first slice's idx for closing off shape */ + for (j=slices, idx=2; j>0; j--, idx++) + topIdx[idx] = j; - /* Cover each stack with a quad strip, except the top and bottom stacks */ - - for( i=1; i