3

我在使用 OpenGL 时遇到了一些性能问题。我本质上想创建一个正方形网格。我首先尝试在每个正方形转换到我想要的正方形的位置实现它,然后将模型和视图矩阵相乘,将其传递给着色器程序并绘制正方形。我会为每个正方形做这个。创建大约 50 个方块后,帧速率将开始下降到低于我想要的水平。

然后我尝试了一种 VBO 方法,我基本上会在每次正方形改变位置时生成一个顶点缓冲区。使用这种方法可以显着提高帧速率,但是当某些东西发生变化时我有太多的延迟,因为它必须重新生成所有顶点位置。

我认为我需要的是一个矩阵堆栈......我之前使用过 opengl 1.1,并且会使用 push/pop。我真的不明白它在做什么以及如何重现它的概念。有谁知道我可以使用矩阵堆栈的一个很好的例子吗?或者可能只是一个很好的解释?

4

1 回答 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 之前为每个孩子更新着色器中的模型矩阵。

于 2013-01-15T16:38:03.323 回答