【发布时间】:2010-06-08 23:13:43
【问题描述】:
我敢肯定这个问题不只有 1 个答案,但是,游戏引擎真的会改变内存中的向量,还是使用 gltransformations?因为一直推送和弹出矩阵似乎效率低下,但是如果您不断修改顶点,您将无法使用显示列表。所以我想知道它是如何完成的。谢谢
【问题讨论】:
我敢肯定这个问题不只有 1 个答案,但是,游戏引擎真的会改变内存中的向量,还是使用 gltransformations?因为一直推送和弹出矩阵似乎效率低下,但是如果您不断修改顶点,您将无法使用显示列表。所以我想知道它是如何完成的。谢谢
【问题讨论】:
取决于您的目标/对象。
通过设置矩阵来移动永远不会改变的对象(也可以使用 glRotatef/glTranslatef 等来移动)。它肯定比逐个顶点变换对象要快。对象存储在 DisplayList、VertexArray 或 VBO 中。您可以每次使用 glVertex* 命令发送整个对象,但如果对象永远不会更改,则无需这样做。
角色(蒙皮/绑定)使用多个矩阵进行转换,这通常由顶点着色器处理。如果需要,您可以在 CPU 上执行此操作,但除非您拥有非常先进的装配/蒙皮引擎,否则没有必要这样做。
无法在显卡上完全执行的计算,在 CPU 上执行。通常是粒子系统、布料和程序几何,有时是阴影(用于使用模板阴影计算阴影体积)。像这样的对象通常至少部分存储在内存中,并且在 CPU 上执行转换。这严格依赖于硬件。根据显卡的能力和 OpenGL 版本,可以在显卡上执行部分或全部任务(不涉及 CPU),但并非总是如此。例如,通常不可能在 GPU 上为程序几何体(即拓扑改变每一帧以及顶点位置)构建阴影体积。但是,有一些技巧可以避免它,并且情况可能会随着未来的版本而改变。
【讨论】:
根据游戏引擎的不同,有很多方法可以做到这一点。
但可能最常见的方法是在游戏引擎和显卡之间划分职责,如下所示:
游戏引擎通过在事件循环中修改适当的向量和矩阵来跟踪游戏中所有对象的位置、方向、速度等。游戏逻辑、物理、碰撞检测等都被应用到这个游戏对象的内存模型中。
当需要渲染对象时,OpenGL 调用用于设置适当的渲染状态和变换矩阵 - 这可以基于每个对象,尽管经常包含优化以最小化状态更改的次数.
然后进行 OpenGL 调用以使用 glDrawElements 绘制必要的网格(假设您使用的是顶点缓冲区对象)。这意味着各个网格顶点所需的所有转换都由图形硬件执行。由于可以通过一次 OpenGL 调用有效地绘制数百个单独的图元,因此这对性能非常重要。
【讨论】:
将一个 16 位数的矩阵写入堆栈是一项微不足道的操作,而且肯定比修改不同顶点的负载要快得多。想想典型 3D 模型中的顶点数,您就会明白为什么。
【讨论】: