应用变换时,OpenGL 是否会更改内存中的顶点?

Does OpenGL change vertices in memory when you apply transformations?

所以假设我的程序中有一个顶点(为简化起见),(0, 0, 0)。就在原点。我使用简单的平移矩阵渲染单个帧,将顶点沿 x 轴向下移动两个单位。相应地渲染顶点。相同的顶点现在是否在 VRAM 中显示为
(2, 0, 0)?我已经读到,每次渲染帧时都在 OpenGL 中加载所有相应的身份矩阵很重要——我认为这是因为一切都会不断地移动、旋转等,越来越远,这意味着应用转换确实会修改实际数据,不仅仅是屏幕上的外观。

这里是 link 维基上关于变换矩阵所涉及的数学的内容。 https://en.wikipedia.org/wiki/Transformation_matrix this will give you an understanding of the math behind the scenes. Another way to look at this is also on the lines of linear or vector algebra. So what happens under the hood when you render a scene is that all of the vertex (pixel) data is sent from the CPU to the GPU to be rasterized and drawn to the screen. This is your batch process or render call, now you also have a frame function that will happen x amount of times per second which will give you your frames per second. So if you are rendering at say 60 FPS then these pixels, vertices, triangles etc., will be drawn 60 times each second. When you apply a transformation to this set of vertices what happens here is you have a transformation matrix that is being multiplied to your model view projection matrix. MVP * T which this will be saved back into your existing MVP matrix if this is how you have your calculations set up. There are some differences between which version of OpenGL you are using as you go from OpenGL v1.0 Pure CPU calls up to v4.5. As far as I know after version 3.2 or 3.3 I don't remember which version off hand you have to implement the MVP yourself where versions greater than v1.5 where shaders were first introduced was handled for you already. Here is the documentation on OpenGL https://www.opengl.org/ 并且在主页上会有一个主题,说明您可以从那里 select OpenGL Registry 或您想要查看的任何特定版本的文档。从这里您可以阅读他们关于 OpenGL API 的文档,因为该站点涵盖了他们 API 中可用的所有内容。所以当你开始理解这个过程时,是的,这些顶点的实际坐标数据确实发生了变化,但是它不会持续变化,除非你用时间因子递增静态类型变量从而给你某种运动或动画模拟.如果您只应用一个变换,那么这些像素、顶点、三角形等将根据您应用的变换进行旋转、平移、缩放或剪切。我会告诉你这些操作的顺序确实很重要,但我不会告诉你它们是什么顺序,那将供你继续阅读并弄清楚。这些之所以重要是因为并非每个矩阵乘法都有有效的逆矩阵。 Identity 用于舍入误差和浮点精度等原因,因此如果您碰巧在大约 10 秒内应用了 1,000 次转换,则不会出现天文数字错误。这应该足以为您指明正确的方向,并且还可以作为 OpenGL API 工作原理的指南。

严格来说,OpenGL只是一个API定义。只要符合规范,实现就可以为所欲为。

话虽如此,您问题的答案通常是:。很难想象将变换后的顶点存储回还包含原始顶点的内存中是如何有意义的。

原始顶点位置被传递到顶点着色器,在那里它们被处理,其中可以包括变换。一旦它们退出顶点着色器,转换后的位置很可能会存储在某种缓存或专用的片上 GPU 内存中,直到它们被管道的后续步骤处理,包括透视分割、视口变换的应用、和光栅化。一旦这些顶点处理步骤完成,变换后的顶点就可以被丢弃。它们可能会在缓存中停留更长的时间,以便在再次使用相同的原始顶点的情况下可能重用已处理的顶点。但是它们并没有以任何持久的方式存储。

按照我的解释,您听说必须为每一帧重置矩阵可能是一种误解。如果你想在下一帧应用相同的矩阵,你根本不需要做任何事情。

他们最有可能谈论的是旧版 OpenGL 中矩阵堆栈的工作原理。大多数修改当前矩阵的调用,如 glTranslatef()glRotatef() 等,都会递增地应用于当前矩阵。例如,如果您调用 glRotatef(),旋转将与矩阵堆栈上已有的变换相结合。结果是您新指定的旋转首先应用于顶点,然后是已经在矩阵堆栈上的变换。

基于此,如果您想在每帧开始时从头开始指定变换,您将调用 glLoadIdentity() 以在开始指定新变换之前重置矩阵堆栈上的当前变换。或者您可以使用 glPushMatrix()/glPopMatrix() 来保存和恢复矩阵堆栈的所需状态。

如果您使用许多人所说的 "modern OpenGL",这意味着您不使用遗留的固定管道功能,则您不必担心这些。矩阵堆栈永远消失了,您可以计算自己的变换矩阵,并将它们传递给着色器代码。