我正在开发一个个人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调用,即将所有顶点收集到一个大数组并绘制它吗?它对性能和fps有多大帮助?
答案 0 :(得分:6)
一般规则是最小化OpenGL调用的数量,特别是在Java或C#等语言中,与本机代码接口的开销很大。但是,如果不同对象的任何属性发生变化(应用不同的模型矩阵,具有不同的颜色等),则不应将它们组合在一起,因为不可能将两个单独的模型矩阵应用于同一绘制的不同部分呼叫。所以基本上,如果你的所有立方体都没有改变,最好将它们组合在一起,否则将它们分开。
对性能有帮助的另一件事是最小化状态更改的数量。如果您要绘制10,000个多维数据集,请将glEnableClientState
和glDisableClientState
调用移出多维数据集draw
方法,并仅在绘制所有多维数据集之前/之后调用它们。如果它们都使用相同的纹理,则在开始时将纹理绑定一次,并在结束时解除绑定一次。
哦,如果您真的担心性能问题,大多数计算机(甚至是2年前的上网本)都支持OpenGL 1.5,因此将数据移动到VBOs将为您带来显着的性能优势。如果您正在执行 Minecraft 之类的操作,那么最佳的优化方法是遍历所有立方体并仅绘制表面。
答案 1 :(得分:1)
如果您关注的是性能问题,我认为您提出的任何一种方案都不会发生很大变化......
根据我过去的经验,可以提高性能的一件事就是使用List(确保更好的内存性能)。
这是一个很好的Opengl bottleneck pdf