我正在使用
Cocoa OpenGL为MacOS构建一个小游戏来创建GUI.游戏是一个BoulderDash-Clone,所以它基本上是一个2D数组的对象,而不是那么多(一个级别就像40个对象宽,25个对象高).很多对象都是动画的,所以我必须在绘制时动态获取纹理(我正在使用NSTimer来不断地重绘动画场景).这似乎会导致严重的性能问题.
我第一次做到了
for(y1,...,yn) for(x1,xn) { glBindTexture(foo); glBegin(GL_QUAD); [drawing the quad with texture] glEnd(); }
哪个工作但很慢(Activity Monitor显示20%的cpu使用率).由于我没有创建任何纹理,但我正在使用一个允许我测试的占位符
glBindTexture(foo); for(y1,xn) { glBegin(GL_QUAD); [drawing of quad with texture] glEnd(); }
这要快很多(2%的cpu使用率).所以我认为是glBindTexture()引起了大规模的放缓.然后我试图找出glBindTexture()的确有多缓慢
for(y1,xn) { glBindTexture(foo); // no drawing this time }
这也非常快(cpu使用率为2%).为什么是这样?
最终我必须将glBindTexture()和绘图放在同一个循环中,因为我必须根据对象及其动画绑定纹理.所以我需要找出第一个代码示例中导致性能问题的原因以及如何加快速度.我一直认为使用OpenGL,一些具有不同纹理的对象不会那么慢.哦,我已经用Java JOGL构建了这个游戏一次,如果我没记错,我做了完全相同的事情,而且速度要快得多. Objective-C/C++不应该破坏Java的性能吗?
解决方法
OpenGL规范为命令处理提供了相当多的余地.你的glBindTexture()调用可能只是在命令队列中设置一个int,在交换缓冲区或调用glFinish()/ glFlush()之前,它实际上不会被处理.如果你调用它,它甚至可能(大部分)被忽略,然后不给OpenGL任何几何使用它.
使用texture atlases来减少glBindTexture()调用.
glBegin()和朋友只是向OpenGL提交几何体的最慢方法.尝试尽可能地批量处理几何体,并使用vertex arrays/VBOs来减少函数调用开销.