There are several solutions, but I think you’d better put all your strips in the same buffer. You can use the function glDrawElements or glDrawRangeElement to specify the starting index of each lists. (it’s the last argument that allows you to specify the offset).
You could also add invalidated triangles (by repeating the same index twice) in your strips. It will connect all your strips together and then only one call to glDraw[Range]Elements will be needed.
The best solution is to convert the triangle stripes into a index. The last 24 vertices can be used from the cache.
A more efficient variant for terrain would be to render many (up to 16 or 24) triangle stripes parallel, because in that case the most vertices will be transformed on a single time. (The 5 other times are cached)
When rendering terrain, you will most probably end up fillrate limited anyway, so I don’t think it makes a lot of sence to overoptimize the vertex data. I would just use indexed triangles or, maybe, a tri-strip.
Well I managed to render the terrain through VBOs and the frame rate really improved. Altough I think i must fix the range of arrays to render because I’m getting the terrain with a seam of unrendered triangles.
My question is how to assign the normals to the vertices? I generated the normals and I’ve them nicely stored into an array.
Maybe It’s fairly easy to provide a vertex array fallback for those users with very old hardware? I don’t know if it’s worth (I believe most cards from 2003 onwards support GL_ARB_vertex_buffer_object…)
I noticed you’re planning to use GLSL shaders so it’s probably not worth to implement the fallback path as hardware that supports GLSL shaders also support vertex buffer objects. On the other hand, it’s fairly easy to implement the fallback path in object oriented programming languages.
Well, I’ve normals and vertex data in VBOs … the problem now (i’ve worked hard to get fixed!! :mad:) is that i’m getting a seam… seems that two strips are not being rendered!
If you look at the code every strip is rendered in this form:
v1 v3
|\ |
| \ |
| \ |
| | \
v0 v2 v4
It worked without VBOs , but not with glDrawArrays.
Here’s my ugly code:
void CTerrain::GenerateMesh(void)
{
vtxdata = new GLfloat[numvtx];
for (int z = 0; z < tsize - 1; z++)
// triangle strip start...
for (int x = 0; x < tsize - 1; x++)
{
vtxdata[(z*tsize+x)*6] = (GLfloat) x;
vtxdata[((z*tsize+x)*6)+1] = (GLfloat) (hmap.GetValue(x,z)*h_scale);
vtxdata[((z*tsize+x)*6)+2] = (GLfloat) z;
vtxdata[((z*tsize+x)*6)+3] = (GLfloat) x;
vtxdata[((z*tsize+x)*6)+4] = (GLfloat) (hmap.GetValue(x,z+1)*h_scale);
vtxdata[((z*tsize+x)*6)+5] = (GLfloat) z+1;
}
// triangle strip end...*/
}
But it probably won’t solve your problem. You shouldn’t use strips. Triangles are easier to use. But you must use “index buffer” (GL_ELEMENT_ARRAY_BUFFER):
Also, make sure you get your indexing correct. As I see it you’re setting up triangle strips for z = 0…tsize-1. But you’re calling drawArrays for z = 0…tsize.