【发布时间】:2014-06-25 21:43:57
【问题描述】:
当使用场景/图形“系统”时,实际上不需要渲染时,我阅读了以下有关推送/弹出方法的帖子(下面的参考链接)。
我现在只是好奇,如果不需要矩阵推送/弹出,如何正确渲染(和转换)一组对象,例如旋转轮子和螺栓的无处不在的例子?
【问题讨论】:
当使用场景/图形“系统”时,实际上不需要渲染时,我阅读了以下有关推送/弹出方法的帖子(下面的参考链接)。
我现在只是好奇,如果不需要矩阵推送/弹出,如何正确渲染(和转换)一组对象,例如旋转轮子和螺栓的无处不在的例子?
【问题讨论】:
所有 push 和 pop 实现的只是一个矩阵堆栈。矩阵堆栈所实现的只是存储和恢复先前的有源矩阵。因此,它是一种管理场景的便捷方式,原因与调用堆栈是一种运行程序的便捷方式相同,但远非必需。
例如你可能只有相机矩阵M,对于每个对象i,对象矩阵Oi。
然后依次为每个对象计算 GL 的旧 MODELVIEW 的等效值,这只是 M 和 Oi 的组合。无需从堆栈中存储或恢复任何内容。你知道M,你知道Oi,这就是你需要知道的。
编辑:例如为了争论,假设你写的是Battlezone。然后你会在运动场上有一堆物体。每个对象都有一个位置和一个旋转。一个这样的对象是安装了摄像机的播放器。您可以通过 (i) 根据玩家的位置和旋转计算视图矩阵来绘制场景;然后 (ii) 遍历运动场上的每个对象,根据其位置和旋转计算模型矩阵;并且,对于每一个,(iii) 组合两者,将结果发布到 OpenGL 并进行必要的几何调用以绘制对象。
没有堆栈。
同样的事情适用于任何只是一个平面对象列表的游戏场(此外:为了简单起见,我忽略了广泛的阶段模型剔除)。
现在假设某些对象是子对象,其位置和方向仅根据父对象定义。在这种情况下,无论您是否将其存储为一个,您都拥有一棵对象树。
一个解决方案可能与 Battlezone 解决方案基本相同,您依次遍历每个对象,但现在您这样做了:
model matrix = identity
while(object is not root)
{
compose model matrix with matrix for this object
let object = parent object
}
所以你正在从孩子回到根。
仍然没有堆栈。
相反,您可以翻转一切,让正常的调用堆栈隐式地成为一个堆栈:
draw object: object, parent matrix: parent matrix
child matrix = composition of parent matrix and this object's matrix
draw object
for(children of object)
{
draw object: child, parent matrix: child matrix
}
所以那里有一个堆栈,但它是调用堆栈。
当然,您的树不必是正式的树数据结构。在 Battlezone 示例中,您有一个隐式树,其中所有内容都是根的第一级子级。类似地,任何其他代码结构都可能影响隐式树。
【讨论】:
C、P 和O,那么您将组合在一起C、P 和O 作为您的模型视图。只是在任何时候都没有将它们放在堆栈上,然后就没有堆栈了。遍历您已有的用于了解模型之间关系的任何方法。