简体   繁体   English

优化此OpenGL渲染算法

[英]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: 我的游戏从VBO绘制了一系列多维数据集,并且每次都转换为多维数据集的位置:

...
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: render()是这样的:

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? 由于我一直在画同样的东西,我该怎么做才能减少CPU的使用强度? Thanks 谢谢

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. 一个警告:尽管OpenGL内部仅使用32位浮点数(在大多数实现中),但最好使用双精度浮点数存储偏移量,以减少舍入误差的累积。

(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) 您可以在单个VBO中烘烤所有多维数据集,并且仅绘制一个(但是几何图形必须确实是完全静态的)

You can use instancing 您可以使用实例化

but with such little geometry there is little more you can do. 但是只有这么小的几何形状,您无能为力。

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. 使用VBO更新几何可能涉及一些工作,但我实际上并未尝试过,但是即使您只是使用旧的时尚顶点数组,它也应该比当前设置快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM