OpenGL 2.0 ES矩阵堆栈是如何工作的?

3

我在OpenGL中遇到了一些性能问题。 我想要创建一个正方形的网格。 我首先尝试的方法是每个正方形都将其变换到所需位置,然后将模型矩阵和视图矩阵相乘,将结果传递到着色器程序并绘制正方形。 对于每个正方形,我都会这样做。 当创建大约50个正方形时,帧率就会开始下降到不到我想要的水平。

然后我尝试了VBO方法,基本上每次正方形更改位置时,我都会生成一个顶点缓冲区。 采用这种方法后,帧率显著增加,但当某些事物发生变化时,由于需要重新生成所有顶点位置,因此存在太多的延迟。

我认为我需要一个矩阵堆栈...我之前使用的是OpenGL 1.1,并使用push/pop。 然而我不是很理解它实际上在做什么以及如何复制它。 有人知道可以用作示例的好的矩阵堆栈示例吗?或者可能只需要一个好的解释?

1个回答

2
你可以查看这个教程,它基本上是做你想要实现的相同的事情,但是使用的是立方体而不是正方形。它也使用了VBO:

http://www.learnopengles.com/android-lesson-seven-an-introduction-to-vertex-buffer-objects-vbos/

关于矩阵,在OpenGL ES 2.0中你不再有任何与矩阵相关的函数,但是你可以使用glmath库,它可以做同样的事情(还有更多)。

http://glm.g-truc.net/

这是一个头文件库,所以你只需要将它复制到某个地方,并在需要的地方包含它即可。
我不确定我完全理解你的目标,但我猜你可以使用VBO复制一个正方形的数据,然后重复更新每个正方形的模型矩阵。
如果你的正方形之间有某种层次关系(例如,如果其中一个移动了,左边的那个也必须相应移动),那么矩阵堆栈的概念就有意义了。
你可以把它想象成由正方形组成的骨架。如果肩膀移动了,手、手指等所有的部位也会跟着移动。你可以通过使用矩阵堆栈来模拟这一过程。你可以创建一个带有所有正方形的树形结构,这样每个正方形都有一个“子孙”列表,其将应用与父级相同的变换。然后你可以像这样递归渲染所有的正方形:
将文本翻译成中文:
  1. 对根平方应用变换
  2. 将变换推入队列中
  3. 为每个子项调用相同的渲染函数
  4. 每个子项读取队列顶部的矩阵,将其乘以自己的变换,将新矩阵推入队列并调用子项
  5. 之后每个子项弹出他们之前推入的矩阵

使用glmath非常容易,只需要创建一个矩阵队列(在这种情况下是std:vector):

std::vector<glm::mat4> matrixStack;

然后对于每个孩子:
glm::mat4 modelMatrix = matrixStack.back();
glm::mat4 nodeTransform = /*apply your transform here*/
glm::mat4 new = modelMatrix * nodeTransform;
matrixStack.push_back(new);
/*Pass in the new matrix to the shader and call to glDrawArrays or whatever to render your square*/

for (every child) {
    render();
}
matrixStack.pop_back();

对于绘图部分,我猜想你可以将顶点数组与正方形顶点绑定,然后在每个子元素调用glDrawArrays之前,在着色器中更新模型矩阵。

这基本上就是我尝试做的。他们实际上是通过顶点缓冲区来完成所有操作的。他们并没有通过平移来放置每个单独的立方体。 - sean wagner
我需要一个每帧执行多次翻译的示例。我试图分解AndEngine,因为他们正在这样做,但是我不熟悉的抽象层和OpenGL太多了。他们在其中有一个矩阵推/弹出实现,我只是不明白它到底在做什么。 - sean wagner

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