Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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;
}

Thanks in advance.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

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.

without GL_CULL_FACE

share|improve this answer
    
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? –  pt2ph8 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 –  pt2ph8 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. –  pt2ph8 Sep 14 '11 at 12:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.