GL_TRIANGLE_STRIP mesh help

Started by
2 comments, last by Fahrenheit451 18 years, 9 months ago
Hello all, Using opengl I heard that it is possible to create a square mesh using a set of “GL_TRIANGLE_STRIP’s”. This is exactly what I need! I wish to create mesh in the x – z plane, such that it is FRONT facing so that I can BACK cull! No need for a vertex array! I have tried but failed:

	   const int col = 30;	//mesh columns
	   const int row = 30;	//mesh rows

	   const float mWidth = 30.0f;	//mesh width
	   const float mHeight = 30.0f;	//mesh height
 	
	   vector vertex;

	for (int a = 0; a < col; a++)
   {
		glBegin(GL_TRIANGLE_STRIP);
		for (int b = 0; b < row; b++)	
		{
			glNormal3f(0.0f, 1.0f, 0.0f);

			vertex.x = …
			vertex.z = …;
			vertex.y = …;

			glVertex3f(vertex.x, vertex.y, vertex.z);
                  vertex.z = vertex.z - 1.0f;
			glVertex3f(vertex.x, vertex.y, vertex.z);

}
glEnd();
}

Can someone paste C/C++ to help out? This is buging me!
Advertisement
The following code is cut from Digiben's (of GameTutorials) Heightmap #2 tutorial.

// The difference from the way we render the terrain from// the original way we started with, is that we don't use GL_QUADS// anymore, we now use a GL_TRIANGLE_STIP.  This means that we don't// need to pass in the same vertex more than once.  Each 2 vertices// are connected to the next 2.  Since we want to do this in one strip,// we are going to need to reverse the order every other column.  It's// like moving the lawn.  Go to the end and turn around and come back// the way you came.  If you don't do it this way, you will get polygons// stretching across the whole terrain.  We could just do a new glBegin()// and glEnd() for every column, but I believe this way is faster.  // Not that that really matters though, because rendering a terrain// with glVertex*() calls in incredibly slow.  We will most likely want// to eventually switch this to vertex arrays.// We want to render triangle stripsglBegin( GL_TRIANGLE_STRIP );			// Go through all of the rows of the height mapfor ( X = 0; X <= MAP_SIZE; X += STEP_SIZE ){	// Chechk if we need to render the opposite way for this column	if(bSwitchSides)	{			// Render a column of the terrain, for this current X.		// We start at MAP_SIZE and render down to 0.		for ( Y = MAP_SIZE; Y >= 0; Y -= STEP_SIZE )		{			// (X, Y, Z) value for the bottom left vertex					x = X;										y = Height(pHeightMap, X, Y );				z = Y;									glVertex3i(x, y, z);					// (X, Y, Z) value for the bottom right vertex					x = X + STEP_SIZE; 			y = Height(pHeightMap, X + STEP_SIZE, Y ); 			z = Y;			glVertex3i(x, y, z);					}	}	else	{			// Render a column of the terrain, for this current X.		// We start at 0 and render down up to MAP_SIZE.		for ( Y = 0; Y <= MAP_SIZE; Y += STEP_SIZE )		{			// (X, Y, Z) value for the bottom right vertex					x = X + STEP_SIZE; 			y = Height(pHeightMap, X + STEP_SIZE, Y ); 			z = Y;			glVertex3i(x, y, z);			// (X, Y, Z) value for the bottom left vertex					x = X;									y = Height(pHeightMap, X, Y );				z = Y;									glVertex3i(x, y, z);				}	}	// Switch the direction the column renders to allow the fluid tri strips	bSwitchSides = !bSwitchSides;}// Stop rendering triangle stripsglEnd();
Thanks, that kinda works, but I'm sure I've seen it done without using "bSwitchSides".

But I think that it will muck up my glMultiTexCoord2fARB texture co-od!

I also tried (sorry for any typos, I'm going to type quick):

	for (int a = 0; a < row; a++)	{		glBegin(GL_TRIANGLE_STRIP);		for (int b = 0; b <= col; b++)			{			glNormal3f(0,1,0);			vertex.x = b- mWidth/2;			vertex.z = (a+1) - mHeight/2;			vertex.y = 0;										texcoord = lpos - vertex;			texcoord.Normalize();			texcoord *= offset;			glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (float)b/col, (float)(a+1)/row);			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (float)b/col + texcoord.x, (float)(a+1)/row + texcoord.y);			glVertex3f( vertex.x, vertex.y, vertex.z);						vertex.z -= stepy;			texcoord = lpos - vertex;			texcoord.Normalize();			texcoord *= offset;				glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (float)b/col, (float)a/row);			glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (float)b/col + texcoord.x, (float)a/row + texcoord.y);			glVertex3f( vertex.x, vertex.y, vertex.z);		}		glEnd();	}


But after all that, the damn mesh was BACK facing!!! AND the texture is upside-down!!! Ahhhh, still driving me mad!!!

More ideas...
I've never used "switchsides" either. When rendering a mesh with triangle strips you have to understand something about the way a TRIANGLE_STRIP is processed. The conventional method of creating a triangle is to provide three vertices to form the polygon:

   p1----p3    |   /    |  /    |/   p2


We consider the order p1 -> p2 -> p3 anti-clockwise. glBegin(GL_TRIANGLES) will take every three vertices to form a triangle. OpenGL doesn't care about how many vertices you provide at a time. It will simply take every set of three provided to form triangles.

A triangle strip is formed by providing the first three triangles, and then every one afterwards forms a new triangle. With triangle strip, four vertices can form two triangles, five vertices three triangles, and six vertices four triangles. How does this magic work you ask? Well here is a diagram:

   p1----p3    |   /|    |  / |    |/   |   p2----p4


Here OpenGL took the fourth vertex and "linked" with p2 and p3 to form the second triangle.

   p1----p3----p5    |   /|   /    |  / |  /    |/   |/   p2----p4


Here the fifth formed the third triangle, and suprise suprise...

         x   p1----p3----p5    |   /|   /| z  |  / |  / |    |/   |/   |   p2----p4----p6


six vertices form the four triangles.

If your mesh vertices are stored in a two dimentional array, then rendering the complete mesh without using "switchsides" is a simple task of a nested for loop. In each iteration of the inner loop you need to draw two vertices. In this example the inner loop vertices drawn are:

p1 and p2
p3 and p4
p5 and p6
p2 and p7
p4 and p8
p6 and p9

         x   p1----p3----p5    |   /|   /|    |  / |  / |    |/   |/   | z p2----p4----p6    |   /|   /|    |  / |  / |    |/   |/   |   p7----p8----p9


Your z axis loop does not need to run to the max array value of course. It needs to run to max-1, since in each inner loop you draw two vertices - the current one, and the current z+1 vertex:

VECTOR CPoint[size][size];                      // grid for surfacefor ( int z = 0; z < (size-1); z++ ) {          // Z axis  // draw triangle strip  glBegin(GL_TRIANGLE_STRIP);  for ( int x = 0; x < size; x++ ) {            // X axis    glVertex3f(CPoint[z][x].x,CPoint[z][x].y,CPoint[z][x].z);    glVertex3f(CPoint[z+1][x].x,CPoint[z+1][x].y,CPoint[z+1][x].z);  }  glEnd();}


Hope that makes sense! Let me know if not.

F451

This topic is closed to new replies.

Advertisement