为啥在 OpenGL 中显式管理矩阵更好?

Posted

技术标签:

【中文标题】为啥在 OpenGL 中显式管理矩阵更好?【英文标题】:Why is it better to explicitly manage matrices in OpenGL?为什么在 OpenGL 中显式管理矩阵更好? 【发布时间】:2011-10-19 21:32:47 【问题描述】:

最近我在 OpenGL 上搞砸了很多,我遇到了允许 OpenGL 管理视图/模型/投影矩阵或自己管理它们之间的分歧,无论是使用你自己的矩阵实现还是这样的库作为 GLM。我看到很多大型项目都有自己的相机管理(即管理自己的平移、旋转等)。我明白为什么它有助于确保您完全控制系统,但除此之外,这似乎需要做很多工作才能获得边际收益。

为什么自己管理比使用内置的 OpenGL 函数更好?显然这是在着色器管道的上下文中,而不是固定函数默认值。

(这适用于任何 3D 库)。

【问题讨论】:

我将避免投反对票,但我通常不喜欢“为什么做 X 比做 Y?”形式的问题。前提是一种方法比另一种更好。如果你不知道为什么,你可能也没有资格知道哪个更好。更好的措辞是“为什么[某些人] 提倡使用 X 而不是 Y?” 我这样表述的原因是因为我所看到的一切都表明最好明确地这样做,并且没有任何对立的地方。我知道这是一个可怕的归纳论证,但我认为它会引起更多关注。不过我同意你的观点,+1 【参考方案1】:

(顺便说一句,OpenGL ES 2 没有转换管理工具,因此在某些情况下您别无选择。)

更重要的是,我发现通过 OpenGL 的内置矩阵堆栈管理矩阵有时真的很痛苦,这迫使我在渲染代码的更复杂部分中大量推送和弹出,甚至重新排序渲染有时只是为了简化堆栈管理。我还编写了一个 C++ pusher-popper 类,它使用 RAII 来自动管理所有这些,但它需要仔细确定局部变量的范围。

当我切换到 ES 2 时,我很沮丧地发现所有这些功能都消失了。但是,我发现切换到我自己的矩阵实际上简化了我的代码,因为我可以使用局部变量和成员变量(具有有意义的名称)的组合来处理多个转换,而不会迷失在空间中,并且转换堆栈主要通过使用替换调用堆栈——即当前变换只是一个局部矩阵变量,它作为父变换参数传递给下一个函数——但可以灵活地在其他时间以不同的方式进行。

【讨论】:

+1,好点子,我会在接受之前等待更多可能的答案。【参考方案2】:

出于多种原因,它会更好。 Apple 最近关于 OSX Lion 中 OpenGL 改进的演示说得最好:较新的 OpenGL 规范(主要是 3.2 以上)更侧重于表示 GPU 实际在做什么。在 OpenGL 2.1 中,所有的矩阵运算都在 CPU 上进行。因此,使用 GL 的矩阵不仅没有神奇的加速好处,而且您被锁定在一个完全任意的矩阵管理模型中:仅投影和模型视图矩阵(用于顶点)、矩阵堆栈大小限制、一组有限的矩阵运算等。

当您开始管理自己的矩阵时,您就会开始明白为什么它会好得多。随着您的场景变得越来越复杂,您开始看到需要更多的矩阵缓存(不仅仅是“投影”和“模型视图”)。您会发现构建更有用的矩阵函数的机会。例如,哪个听起来更令人愉悦? glRotatef(90.0f, 1.0f, 0.0f, 0.0f);matrix.rotateX(90.0f); ?每次都必须指定旋转轴,这一直困扰着我!

当您开始认识到 CPU 操作和 GPU 操作之间的区别时,您将开始欣赏管理自己的矩阵。

【讨论】:

+1 提到旧的 GL 矩阵运算不会在 GPU 上神奇地执行。【参考方案3】:

GL 管理的矩阵堆栈在最近的版本中已被弃用。 OpenGL规范。所以继续自己管理它们是唯一选项。

【讨论】:

以上是关于为啥在 OpenGL 中显式管理矩阵更好?的主要内容,如果未能解决你的问题,请参考以下文章

在 GridSearchCV 中显式指定测试/训练集

在 terraform 模块中显式使用提供程序

在 DataFrameMapper 中显式删除列

在 mvvm 中显式保存

在 QT 中显式调用paintGL

在 Java 中显式调用默认方法