2012-03-12 82 views
1

所以我编写了一个程序,使用顶点缓冲区对象渲染网格,并让我移动相机。我现在想让对象独立于摄像机/视图而移动。OpenGL - 对象转换和VBOs

但是,我不知道如何去移动我的网格穿过太空。谷歌搜索往往会发现消息来源要么告诉我用glRotatef()等旋转对象,要么使用glRotatef()及其兄弟是一个坏主意,因为它们已被弃用。也许我没有使用正确的搜索条件,但我没有找到那么多,这似乎是一个很好的起点。我看到矩阵数学的模糊引用,但我不知道如何使用它以及采取什么方法。其他消息来源说,我应该应用顶点着色器来转换对象。我想我可以手动重建我的网格每一帧,但这似乎是一个可怕的想法(网格经常有超过50K三角形,我想有至少几十个),我不'',如果它们已经存储在VBO中,那么真的需要在我的内存中不断使用顶点......对吗?

那么,如何操作独立于全局空间存储在VBO中的网格呢?我应该使用什么资源来学习这样做?

回答

9

您应该使用您的ModelView矩阵将变换应用到顶点。要将转换应用于特定对象/网格而不是整个屏幕,请将ModelView矩阵的副本压入堆栈,应用转换,绘制对象,然后弹出该矩阵以返回到旧的ModelView矩阵。

无需重新计算顶点位置!这正是这些矩阵旨在帮助您避免的原因。事实上,它们存储在VBO中并不重要 - 手动传递给OpenGL的顶点将完全相同。

您可能想查看this questiontransformation article其接受的答案链接 - 如果您仍然遇到转换和矩阵堆栈,它们将非常有用。

希望有帮助!

编辑:堆栈有用的一个简单例子。假设你正在绘制一个简单的场景:一个在海上的木筏(帆)。

首先,您需要设置相机角度,因此您需要进行任何转换以设置相机角度。您不需要 - 实际上不需要想要 - 在这里推送和弹出矩阵,因为这些转换适用于场景中的所有内容(在OpenGL中,移动摄像头=移动整个世界,奇怪地想一想,但你已经习惯了。)。

然后你画你的海洋。不需要转换,因为它是一个静态对象,不会移动。

然后你画你的木筏。但是你的木筏已经移动了!它沿着X轴漂移。现在,由于木筏是一个独立的物体,适用于木筏的转换不适用于更大的世界,因此可以将矩阵推入堆栈。这会复制现有的ModelView矩阵。所有这些相机转换已经应用;你在木筏上的“漂移”转变除了你在较低层次上进行的转换之外。

绘制筏子。然后,之前,您将该矩阵从堆栈中弹出,绘制筏上的东西 - 人和风帆。由于他们随着木筏移动,所有适用于木筏的转换应该适用于他们。

说你先画你的抛弃。但他也感动 - 他跳到空中。所以你把另一个矩阵推到栈上,应用一个“跳跃”转换,然后渲染你的人。如果有什么东西要跟这个人一起移动 - 如果他拿着任何东西,说 - 你也会在这里画。但他不是。因此,从堆栈中弹出“跳跃”矩阵。

现在你回到了“筏”的上下文中。由于您将“跳跃”转换应用于副本,因此“漂移”转换不会受到堆栈级别的影响。现在画出帆,它会在木筏的顶部,就在它应该在的地方。

然后你就用木筏做,这样你就可以弹出该矩阵出栈了。你已经回到了简单的相机转换。画更多的静态几何 - 岛屿或其他东西。

这就是为什么矩阵堆栈很有用。这也是为什么人们将更复杂的场景场景构建为“场景图” - 以便他们可以跟踪变换的嵌套。它在骨骼动画中也很有用,手腕的位置取决于肘部的位置,这取决于肩部的位置,等等。

,那就是程较长比我预想的 - 但希望有用。干杯!

+1

所以第一个'glPushMatrix()',然后变换,如'的glTranslatef(X,Y,Z)',然后绘制VBO,最后'glPopMatrix()' - 是否正确?我已经将该结构添加到当前代码中,并且它似乎工作正常!我不熟悉推送和弹出功能;谢谢!另外,感谢您的链接! – GarrickW 2012-03-12 20:06:37

+0

@GarrickW - 从技术上讲,如果您要在屏幕中移动一个“对象”,并且不希望这些转换适用于其他任何东西,则只需要推送和弹出功能。我已经添加了一个例子 - 希望它会使事情更清晰。干杯! – 2012-03-12 20:42:34

+0

啊,我明白了 - 非常感谢!这有助于澄清事情。 – GarrickW 2012-03-13 07:49:20