执行glPushMatrix()
和glPopMatrix()
会产生多少开销?例如,如果我的ModelView矩阵是一个简单的翻译,我有一个简单的翻译,我应该先使用反向翻译而不先执行glPushMatrix(),还是应该执行Push,然后翻译,然后使用Pop?
答案 0 :(得分:4)
来自固定大小的矩阵堆栈的推送/弹出可能比进行另一次转换更快。它的数值更稳定;你不必担心翻译完全撤消翻译。实际上,这是一种微观优化。
虽然我会发出标准警告:OpenGL矩阵API是不推荐使用的固定功能管道的一部分。现在大多数真正的程序都实现了自己的矩阵函数(或使用像GLM这样的库),然后将生成的矩阵上传到它们的顶点着色器。
这样做的好处之一是你知道矩阵操作的性能特征,因为你自己编写了这些特性(或者可以访问源代码); GL矩阵函数的性能是实现者的心血来潮(在你问之前:它们不是GPU加速的)。另一个好处是您自己的矩阵例程可以由编译器进行内联和优化。
答案 1 :(得分:3)
除了你已经得到的答案,我还想提出两件事:
OpenGL矩阵堆栈已过时(已从OpenGL-3.3内核完全删除)
堆栈推送的成本取决于底层架构,但总是通过制作最顶层元素的副本来限制。所有意图和目的的堆栈 pop 操作都没有成本。 OpenGL本身只是一个规范,所以它很可能运行在针对堆栈操作优化的架构上,以及推送操作具有(接近)零成本(例如通过实现为写时复制)。
因此需要注意的一件重要事情是,整个OpenGL矩阵堆栈从未实现GPU端(除了一个值得注意的例外; SGI Onyx图形工作站,但这些使得图形处理器与老式的完全不同无论如何,CPU非常模糊,因为那些“图形引擎”板是混合使用与常规CPU混合的专用光栅化处理器。)
查看x86和ARM体系结构的最新实现,最重要的变量是可用的微体系结构寄存器的数量。带有SSE的x86或带有Neon的ARM已经有足够的可寻址寄存器空间来容纳几个4×4单精度矩阵。但是你在“二进制机器代码”中看到的寄存器实际上只是处理到硅片中的实际寄存器库(在现代的乱序执行流水线架构中),并且每次执行在微架构内部执行Register renaming的寄存器上操作。因此,机器代码中看起来像是一个完整的堆栈顶部元素复制操作实际上可能会分解为零拷贝寄存器重命名操作。