Generate a Plane with Triangle Strips

Generate a plane with triangle strips

Thanks you all. I've coded this. Is it correct? Or is the generated strip somehow wrong?

int width;
int height;
float* vertices = 0;
int* indices = 0;

int getVerticesCount( int width, int height ) {
return width * height * 3;
}

int getIndicesCount( int width, int height ) {
return (width*height) + (width-1)*(height-2);
}

float* getVertices( int width, int height ) {
if ( vertices ) return vertices;

vertices = new float[ getVerticesCount( width, height ) ];
int i = 0;

for ( int row=0; row<height; row++ ) {
for ( int col=0; col<width; col++ ) {
vertices[i++] = (float) col;
vertices[i++] = 0.0f;
vertices[i++] = (float) row;
}
}

return vertices;
}

int* getIndices( int width, int height ) {
if ( indices ) return indices;

indices = new int[ iSize ];
int i = 0;

for ( int row=0; row<height-1; row++ ) {
if ( (row&1)==0 ) { // even rows
for ( int col=0; col<width; col++ ) {
indices[i++] = col + row * width;
indices[i++] = col + (row+1) * width;
}
} else { // odd rows
for ( int col=width-1; col>0; col-- ) {
indices[i++] = col + (row+1) * width;
indices[i++] = col - 1 + + row * width;
}
}
}
if ( (mHeight&1) && mHeight>2 ) {
mpIndices[i++] = (mHeight-1) * mWidth;
}

return indices;
}

void render() {
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, getVertices(width,height) );
glDrawElements( GL_TRIANGLE_STRIP, getIndicesCount(width,height), GL_UNSIGNED_INT, getIndices(width,height) );
glDisableClientState( GL_VERTEX_ARRAY );
}

With width=4 and height=4 this is what I got:
Sample Image

And here I'm modifying some vertex height:
Sample Image

Creating plane with triangular strips

For me, this looks like the triangles, that are produced by the triangle-strip to "jump back" to the left side. This happens whenever you start a new row. Basically, they consist of the last-vertices of the previous row and the first vertices of the next row. Backface culling seems to work, but the large triangles are visible from the back because their winding order is exactly opposite to the one of the small triangles.

If you don't want to have them, you either have to reset the triangle-strip at the end of each row, or use another structure (GL_TRIANGLES).

Convert triangle strips to Octagonal?

Use the polygon rasterization mode GL_LINE to render a wire frame:

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
float xPos = 0.0f;
float yPos = 0.0f;
float radius = 0.5f;
int steps = 8;
float prevX = xPos;
float prevY = yPos - radius;

glBegin(GL_TRIANGLES);
glColor3f(0.0f, 0.5f, 0.0f);

for (int i=0; i <= step; ++i)
{
float angle = 3.1415926f * 2.0f * i / step;
float newX = radius * sin(angle);
float newY = - radius * cos(angle);

glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(prevX, prevY, 0.0f);
glVertex3f(newX, newY, 0.0f);

prevX = newX;
prevY = newY;
}
glEnd();

Sample Image

Use a GL_TRIANGLE_FAN Triangle primitive to simplify your code:

glBegin(GL_TRIANGLE_FAN);
glColor3f(0.0f, 0.5f, 0.0f);

for (int i=0; i <= step; ++i)
{
float angle = 3.1415926f * 2.0f * i / step;
float newX = radius * sin(angle);
float newY = - radius * cos(angle);
glVertex3f(newX, newY, 0.0f);
}
glEnd();

Sample Image

If you want to use a triangle GL_TRIANGLE_STRIP, you must change the order of the vertices:

glBegin(GL_TRIANGLE_STRIP);
glColor3f(0.0f, 0.5f, 0.0f);

for (int i=0; i <= step; ++i)
{
int strip_i = i % 2 == 0 ? i/2 : step - i/2;
float angle = 3.1415926f * 2.0f * strip_i / step;
float newX = radius * sin(angle);
float newY = - radius * cos(angle);
glVertex3f(newX, newY, 0.0f);
}
glEnd();

Sample Image

If you want to render the wire frame on top of the polygon, you need to enable the depth test and render the polygon first. Note the default depth test function is GL_LESS:

for (int pass = 0; pass < 2; ++pass)
{
if (pass == 0)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(1.0f, 1.0f, 1.0f);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor3f(0.0f, 0.5f, 0.0f);
}

glBegin(GL_TRIANGLE_STRIP);
for (int i=0; i <= step; ++i)
{
int strip_i = i % 2 == 0 ? i/2 : step - i/2;
float angle = 3.1415926f * 2.0f * strip_i / step;
float newX = radius * sin(angle);
float newY = - radius * cos(angle);
glVertex3f(newX, newY, 0.0f);
}
glEnd();
}

Sample Image

Issues with making an OpenGL plane out of triangles

I realised that vertices were being created from bottom to top and indices were ordered to create triangles from top to bottom. So I changed the vertex creation for loop.

int index = 0;
for (int y = height; y >= 0; y--)
{

for (int x = 0; x <= width; x++)
{
vertices[index] = ((float)x/4)-0.5;
vertices[index +1] = ((float)y/4)-0.5;
vertices[index + 2] = 0.0f;
index += 3;
}
}

It creates the vertices from top left to right bottom. Loop for the indices stayed the same:

int i = 0;
++width;
GLuint indices2[170] = { 0 };

for (int y = 0; y < height; y++)
{
int base = y * width;

for (int x = 0; x < width; x++)
{
indices[i++] = base + x;
indices[i++] = base + width + x;
}
if (y < height - 1)
{
indices[i++] = ((y + 1) * width + (width - 1));
indices[i++] = ((y + 1) * width);
}
}


Related Topics



Leave a reply



Submit