我应该使用多个glDrawArrays()还是将所有顶点汇总到一个大的glDrawArrays调用中?

4

我正在开发一个个人的Java OpenGL (JOGL)项目,使用一些具有单独绘制功能和顶点的自定义对象。

public class Cube extends PhysicalObject {

 public void draw(GL gl) {

         gl.glColor3f(1.0f, 1.0f, 0.0f);

         gl.glEnableClientState(GL.GL_VERTEX_ARRAY);  // Enable Vertex Arrays

            gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);  

            gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertices); 

            gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, texCoords); 

            gl.glDrawArrays(GL.GL_QUADS, 0, 4*6);  


            gl.glDisableClientState(GL.GL_VERTEX_ARRAY);  

            gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

}

我接着循环遍历这些方块,调用它们的绘制函数。 我的问题是: 我应该将所有顶点收集到一个大的glDrawArrays调用中,即将所有顶点收集到一个大数组中并进行绘制吗?这对性能和帧率有很大影响吗?

2个回答

6
一般规则是尽量减少OpenGL调用,特别是在像Java或C#这样的语言中,与本地代码交互需要开销。但是,如果任何对象的属性会发生变化(应用不同的模型矩阵,具有不同的颜色等),则不应将它们组合在一起,因为无法对同一绘制调用的不同部分应用两个单独的模型矩阵。因此,如果所有立方体都不会改变,则最好将它们全部组合在一起,否则保持它们分开。
另一个有助于提高性能的方法是尽量减少状态更改次数。如果要绘制10,000个立方体,请将glEnableClientStateglDisableClientState调用移出立方体draw方法,并仅在所有立方体绘制之前/之后调用它们。如果它们都使用相同的纹理,在开始时绑定纹理并在结束时解除绑定。
如果你真的担心性能问题,大多数计算机(即使是两年前的netbook)都支持OpenGL 1.5,因此将数据移动到VBOs将给你带来显著的性能优势。如果你正在做像Minecraft这样的事情,那么最佳的优化方法是遍历所有的立方体并只绘制表面面。

1

如果您关心的是性能问题,我认为您不会在您提出的任何一种实现中看到非常大的变化...

根据我的过去经验,可以提高性能的一件事情是使用List(确保更好的内存性能)。

这是一个很好的Opengl瓶颈pdf。


我不确定你所说的“List”具体指的是什么。是ArrayList还是VertexBufferObject,或者我理解错了? - JulenissensHjelper
1
如果我的表述不够清晰,我向您道歉...它们被称为“CallList”或“DisplayList”。http://www.swiftless.com/tutorials/opengl/displaylists.html - Erwald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接