您应该使用您的 ModelView 矩阵将变换应用到您的顶点。要将转换应用于特定对象/网格而不是整个屏幕,请将 ModelView 矩阵的副本推送到堆栈上,应用转换,绘制对象,然后弹出该矩阵以返回旧的 ModelView 矩阵。
无需重新计算顶点位置!这正是这些矩阵旨在帮助您避免的。而且它们存储在 VBO 中的事实对您来说并不重要 - 手动传递给 OpenGL 的顶点会被完全一样地对待。
您可能想查看this question 和transformation article 其接受的答案链接 - 如果您仍然掌握转换和矩阵堆栈的窍门,它们会很有用。
希望有帮助!
编辑:一个快速示例说明堆栈为何有用。假设您正在绘制一个简单的场景:一个人在海洋中的木筏(有帆)上。
首先,您需要设置相机角度,因此请进行任何您需要的变换来设置它。您不需要(实际上也不想)在此处推送和弹出矩阵,因为这些变换适用于场景中的所有内容(在 OpenGL 中,移动相机 = 移动整个世界。想想很奇怪,但你已经习惯了。)。
然后你画出你的海洋。不需要转换它,因为它是一个静态对象,不会移动。
然后你画你的木筏。但是你的木筏已经移动了!它沿 X 轴漂移。现在,由于 raft 是一个独立的对象,并且适用于 raft 的变换不应该适用于更大的世界,因此您将矩阵压入堆栈。这将复制现有的 ModelView 矩阵。所有这些相机变换都已应用;您在 raft 上的“漂移”转换是您在堆栈较低级别所做的转换的补充。
画出木筏。然后,在你从堆栈中弹出那个矩阵之前,画出木筏上的东西——家伙和帆。由于它们与筏一起移动,因此适用于筏的所有变换都应应用于它们,to。
假设你先画出你的漂流者。但他也动了——他跳到空中。因此,您将另一个矩阵推入堆栈,应用“跳跃”转换,然后渲染您的人。如果有什么东西应该随着这个人移动——如果他拿着任何东西,比如说——你也会把它画在这里。但他不是。所以从堆栈中弹出“跳跃”矩阵。
现在您又回到了“筏”的上下文中。由于您将“跳跃”转换应用于副本,因此“漂移”转换在堆栈级别下保持不变。现在画帆,它会在筏子的顶部,就在它应该在的地方。
然后您就完成了 raft,因此您也可以将该矩阵从堆栈中弹出。你又回到了普通的相机变换。画一些更静态的几何图形 - 岛屿或其他东西。
这就是矩阵堆栈有用的原因。这也是为什么人们将更复杂的场景场景构建为“场景图”的原因——这样他们就可以跟踪变换的嵌套。它在骨骼动画中也很有用,其中手腕的位置取决于肘部的位置,而肘部的位置取决于肩部的位置等等。
这比我预期的要长得多 - 但希望有用。干杯!