I implemented vertex arrays and VBO in my planet generator experiment... To my great surprise, VBO is performing much slower than regular vertex array, and even slower than immediate mode. The polygons are divided into 20 batches (there are 20 unique textures), so the batch size in the following data varies from 1024 to 65536 triangles.
(Mtris/second with immediate mode/regular vertex array/VBO)
20480 tris: 2.56 / 4.09 / 1.86
81920 tris: 2.64 / 13.7 / 1.95
327680 tris: 2.69 / 2.73 / 2.05
1310720 tris: 2.65 / 2.76 / 0.1 (out of VRAM?)
Setup: P4/2.4Ghz, Radeon 9700 pro 128M
Things to note are that the vertex array performance has a sharp peak at 4096 tris/batch, but VBO is consistently slow. Can you see anything obviously wrong in the code below? (this is called once per frame for each quadrant [batch], the arrays are written to only once in an init function)
ifdef USE_VAR
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
if (gfx.vbosup)
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, orb->rants[r].nvar);
glVertexPointer(3, GL_INT, 0, NULL);
glBindBufferARB( GL_ARRAY_BUFFER_ARB, orb->rants[r].nnar);
glNormalPointer(GL_FLOAT, 0, NULL);
glBindBufferARB( GL_ARRAY_BUFFER_ARB, orb->rants[r].ntar);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
}
else
{
glVertexPointer(3, GL_INT, 0, orb->rants[r].var);
glNormalPointer(GL_FLOAT, 0, orb->rants[r].nar);
glTexCoordPointer(2, GL_FLOAT, 0, orb->rants[r].tar);
}
glDrawElements(GL_TRIANGLES, orb->rants[r].ntris*3, GL_UNSIGNED_INT, orb->rants[r].iar); // array of vertex/normal/texcoord indices
glDisable(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
#else
glBegin(GL_TRIANGLES);
tris = orb->rants[r].tris;
verts = orb->rants[r].verts;
for (tri = 0; tri < orb->rants[r].ntris; tri++)
{
//glNormal3f(tris[tri].norm[0], tris[tri].norm[1], tris[tri].norm[2]);
glNormal3f(orb->rants[r].nar[tris[tri].v[0]*3+0], orb->rants[r].nar[tris[tri].v[0]*3+1], orb->rants[r].nar[tris[tri].v[0]*3+2]);
glTexCoord2f(orb->rants[r].tar[tris[tri].v[0]*2+0], orb->rants[r].tar[tris[tri].v[0]*2+1]);
glVertex3i(orb->rants[r].var[tris[tri].v[0]*3+0], orb->rants[r].var[tris[tri].v[0]*3+1], orb->rants[r].var[tris[tri].v[0]*3+2]);
glNormal3f(orb->rants[r].nar[tris[tri].v[1]*3+0], orb->rants[r].nar[tris[tri].v[1]*3+1], orb->rants[r].nar[tris[tri].v[1]*3+2]);
glTexCoord2f(orb->rants[r].tar[tris[tri].v[1]*2+0], orb->rants[r].tar[tris[tri].v[1]*2+1]);
glVertex3i(orb->rants[r].var[tris[tri].v[1]*3+0], orb->rants[r].var[tris[tri].v[1]*3+1], orb->rants[r].var[tris[tri].v[1]*3+2]);
glNormal3f(orb->rants[r].nar[tris[tri].v[2]*3+0], orb->rants[r].nar[tris[tri].v[2]*3+1], orb->rants[r].nar[tris[tri].v[2]*3+2]);
glTexCoord2f(orb->rants[r].tar[tris[tri].v[2]*2+0], orb->rants[r].tar[tris[tri].v[2]*2+1]);
glVertex3i(orb->rants[r].var[tris[tri].v[2]*3+0], orb->rants[r].var[tris[tri].v[2]*3+1], orb->rants[r].var[tris[tri].v[2]*3+2]);
pc++;
}
glEnd();
#endif