开发者

Optimizing this OpenGL rendering algorithm

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


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.


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.)


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜