Sunday, July 3, 2016

procedural generation - 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{
int index = (m*sides);
for (int n=0; 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 for (int j=0; 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.



Answer



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


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...