tags:

views:

110

answers:

3

My game draws a series of cubes from a VBO, and just translates to the cube's position each time:

...
SetCameraMatrix();
    SetFrustum();



    //start vbo rendering
    glEnableClientState(GL_VERTEX_ARRAY);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 1);

    glVertexPointer(3, GL_FLOAT, 0, 0);
    glColor3f(1,0.5,0);

    for(int i = 0; i < collids.size(); ++i)
{

            glColor3f(collids[i]->Color.x,collids[i]->Color.y,collids[i]->Color.z);
            collids[i]->render();   

}

//end vbo rendering
glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
...

the render() is this:

void CBox::render()
{

    glPushMatrix();
    glTranslatef(center.x,center.y,center.z);

    glDrawArrays(GL_QUADS, 0, 24);
    glPopMatrix();
}

Is there a way I could optimize this? Since i'm always drawing the same thing, what could I do to make this less cpu intensive? Thanks

A: 

There are many possible optimizations. I think one I would employ off the bat is to avoid pushing/popping the matrix each time, which can be very time consuming. Since you are only translating, you can keep track of your last translation, and just shift by a relative amount. In pseudocode:

glPushMatrix()
Point3D offset(0,0,0)
for box in collids:
   glTranslatef(box.x + offset.x, box.y + offset.y, box.z + offset.z)
   draw_cube()
   offset -= (box + offset)
glPopMatrix()

One caveat: While OpenGL internally uses only 32-bit floats (in most implementations), it is probably best to use double precision floating points to store the offset, to reduce accumulation of rounding errors.

(Edited to fix computation of offset.)

Matthew Hall
Ok this helped a bit, but what else could I now do?
Milo
How many boxes are you rendering? Some more ideas: 1) Use triangle strips instead of quads (A quick 'triangle strip cube' google will show you how), and/or 2) use a display list
Matthew Hall
A: 

You can bake all your cubes in a single VBO and draw only this one (but the geometry must really be completely static)

You can use instancing

but with such little geometry there is little more you can do.

Calvin1602
A: 

If you have a lot of cubes your big problem will be the number of draw calls. Graphics cards churn through triangles at such an amazing rate that the bottleneck is often the driver doing the communication. In general, the less calls you make, the faster it will go.

With this in mind, you'll be much better off chucking everything into one array, even if your geometry is dynamic. Update the geometry for any cubes that have moved (all of them if necessary) and send it all off in one go. It may be a bit involved to update geometry using VBOs, I haven't actually tried, but even if you just used old fashion vertex arrays it should be faster than your current setup.

David