Create vertices + indices for cylinder with triangle strips

I'm trying to create vertex and index buffer for a cylinder (in OpenGL, but it shouldn't matter). I think my vertex buffer is fine (I checked drawing with GL_POINTS). Here's the code that builds it:

int sides = 10, slices = 40;
float radius = 3.5 * 10.0;

numVertices = sides * slices;
Vertices = malloc(sizeof(Vertex) * numVertices);

int angleincs = 2*M_PI/sides;
int cs_angleincs = 2*M_PI/slices;
float zval;
float zstep = height / (float)sides;

float i;

for(int m=0; m<slices; m++)
{
int index = (m*sides);
for (int n=0; n<sides; n++)
{
Vertices[index + n].Position.x = cosf(i);
Vertices[index + n].Position.y = sinf(i);
Vertices[index + n].Position.z = zval;

i += angleincs;
}

zval += zstep;
}


I'm stuck at the index buffer generation. Any help on how to build it? I tried to adapt some code from a torus generator, and I get something that apparently resembles a cylinder but it's a bit weird and has a few extra weird triangles.

numIndices = (2 * (sides+1) * slices + slices);
Indices = malloc(sizeof(GLushort) * numIndices);

int n=0;
for (int i=0;i<slices; i++) {
for (int j=0; j<sides; j++) {
Indices[n++] = i * sides + j;
Indices[n++] = ((i+1)%slices) * sides + j;
}

Indices[n++] = i * sides;
Indices[n++] = ((i+1)%slices) * sides;
Indices[n++] = ((i+1)%slices) * sides;
}


To texture a cylinder you typically use GL_TRIANGLE_FAN for the top and bottom and a GL_TRIANGLE_STRIP (just a normal array, without element arrays) for the around.

This is code to produce a normal array of vertices to be used with an array.

// draws a cylinder 'height' high on the y axis at x,y,z position
const float theta = 2. * M_PI / (float)sides;
c = cos(theta),
s = sin(theta);
// coordinates on top of the circle, on xz plane
float x2 = radius, z2 = 0;
// make the strip
glBegin(GL_TRIANGLE_STRIP);
for(int i=0; i<=sides; i++) {
// texture coord
const float tx = (float)i/sides;
// normal
const float nf = 1./math.sqrt(x2*x2+z2*z2),
xn = x2*nf, zn = z2*nf;
glNormal3f(xn,0,zn);
glTexCoord2f(tx,0);
glVertex3f(x+x2,y,z+z2)
glNormal3f(xn,0,zn);
glTexCoord2f(tx,1);
glVertex3f(x+x2,y+height,z+z2);
// next position
const float x3 = x2;
x2 = c * x2 - s * z2;
z2 = s * x3 + c * z2;
}
glEnd();


It is straightforward to adapt this to have store those vertices in a VBO for glDrawArrays to use.

• Hey, thanks. So you suggest using a triangle fan rather than a strip, and no indices? As I said I'm on the iPhone. Also, what about texture coordinates? Sep 13 '11 at 13:24
• absolutely, don't bother with indices! They are just more code, bigger VBOs and slower to boot! I added computation of a texutre and the normals.
– Will
Sep 13 '11 at 14:30
• It works, but I need to build the cylinder using many 'slices'. I tried to adapt your code but whenever I set slices to more than 1, the geometry starts looking weird. Could you please check my code? It's basically yours + a 'delta slice' variable which gets added to y for each slice loop. Code: pastebin.com/VfHbmT14 Screen: i.imgur.com/Lomvm.png Sep 13 '11 at 21:25
• @pt2ph8 what's a slice and a side? And why a slice?
– Will
Sep 14 '11 at 6:49
• I think I just solved it myself. Basically I just wanted to divide the cylinder into smaller cylinders ("slices") to fill the whole height. Sep 14 '11 at 12:37