我正在使用 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();
}

它工作但真的很慢(事件监视器显示 20% 的 CPU 使用率)。由于我没有创建任何纹理,但我使用了一个占位符,它允许我进行测试
glBindTexture(foo);
for(y1, ..., yn) for(x1, ..., xn)
{
   glBegin(GL_QUAD);
     [drawing of quad with texture]
   glEnd();
}

这要快得多(2% CPU 使用率)。所以我认为是 glBindTexture() 导致了大幅放缓。然后我试图找出 glBindTexture() 到底有多慢
for(y1, ..., yn) for(x1, ..., xn)
{
  glBindTexture(foo);
  // no drawing this time
}

这也非常快(2% CPU 使用率)。为什么是这样?

最终我将不得不将 glBindTexture() 和绘图放入同一个循环中,因为我必须根据对象及其动画绑定(bind)纹理。因此,我需要找出导致第一个代码示例中出现性能问题的原因以及如何加快速度。我一直认为数百个具有不同纹理的对象使用 OpenGL 不会那么慢。哦,我已经用 Java + JOGL 构建了一次这个游戏,如果我没记错的话,我做了完全相同的事情,而且速度要快得多。 Objective-C/C++ 不应该在性能方面破坏 Java 吗?

最佳答案

当涉及到命令处理时,OpenGL 规范为实现提供了相当多的余地。您的 glBindTexture() 调用可能只是在命令队列中设置了一个 int 值,在您交换缓冲区或调用 glFinish()/glFlush() 之前,它实际上不会得到处理。如果你调用它,然后不给 OpenGL 任何使用它的几何体,它甚至可能(大部分)被忽略。

使用 texture atlases 减少 glBindTexture() 调用。
glBegin() 和 friend 们是将几何体提交给 OpenGL 的最慢方法。尝试尽可能多地批处理几何图形并使用 vertex arrays/VBOs 来减少函数调用开销。

关于cocoa - glBindTexture() + glBegin(foo) 慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4805451/

10-09 10:07