我为什么要使用glTranslate?

时间:2014-12-01 22:34:47

标签: c# opengl opentk

当我可以自己进行位置数学时,推动/弹出矩阵来翻译形状的目的是什么?我可以理解使用前面提到的矩阵做更难的操作(例如轮换),但为什么要专门翻译呢?

public void render()
        {
            positionX++;

            GL.PushMatrix();
            GL.Translate(positionX, positionY, 0);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            GL.Begin(PrimitiveType.Quads);

            GL.Vertex2(0, 0);
            GL.Vertex2(0 + widthX, 0);
            GL.Vertex2(0 + widthX, 0 + widthY);
            GL.Vertex2(0, 0 + widthY);

            GL.PopMatrix();

            GL.End();
        }

public void render()
        {
            positionX++;
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            GL.Begin(PrimitiveType.Quads);

            GL.Vertex2(positionX, positionY);
            GL.Vertex2(positionX + widthX, positionY);
            GL.Vertex2(positionX + widthX, positionY + widthY);
            GL.Vertex2(positionX, positionY + widthY);

            GL.End();
        }

2 个答案:

答案 0 :(得分:2)

我不认为这是一个愚蠢的问题,尽管你更多地使用OpenGL,答案可能会变得清晰。

当您需要不同的转换顺序时,使用glTranslate(或类似方法)进行翻译肯定会派上用场。只有在转换是您想要进行的第一次转换时,才能更改顶点坐标。如果你想做,例如,旋转,然后翻译,然后另一个旋转,你必须使用矩阵。

然而,主要原因是通常你不会在每一帧上将顶点发送到GPU。这非常慢,实际上,您使用的所有GL.*方法现在都已弃用。现在的方式是:

  1. 在开始渲染任何内容之前,将所有顶点数据发送到GPU一次(记住它可能是数千个多边形或更多)。
  2. GPU会将数据存储在其内部存储器中(这就是为什么你的显卡上有多少MB / GB的RAM)并给你一个id(例如1)。
  3. 渲染帧时,您只需告诉GPU“绘制您用id 1保存的内容”。这是一个单一的OpenGL调用 - 请记住,每个OpenGL调用都有成本(意味着时间),因此调用的次数越少,图形就越快。
  4. 纹理,着色器和其他东西也是如此。

    因此,一旦将顶点数据发送到GPU,通常不会修改顶点数据(技术上可以修改,但出于性能原因,这是不可取的)。因此,如果您想要进行任何转换,则必须使用矩阵。

    作为最后一点,我再次说你正在使用已弃用的功能,这对我学习一些基本概念并不是很糟糕,但我肯定会建议转到当前的OpenGL(或者至少是OpenGL 3)尽快了解着色器,顶点缓冲区,顶点数组和所有新的闪亮东西。

    TL; DR:是的,你可以自己做。但是让你的显卡做得更好是因为它可以做得更快。事实上,这是拥有专用显卡的主要原因。

答案 1 :(得分:1)

  

当我可以自己进行位置数学时,推动/弹出矩阵来翻译形状的目的是什么?

因为它允许OpenGL将操作卸载到GPU,然后大规模并行化。好看,试图超越那个。 GPU革命始于第一批卸载此操作的GPU。当时称为T' n加速(变换和照明),它是15年前开始的PC图形革命的唯一负责人。

考虑到glTranslate和朋友已弃用,您的问题可以改写为

当我可以自己进行位置数学运算时,向顶点着色器统一提供平移矩阵以翻译形状的目的是什么?

嗯,原因是,"自己做"通常归结为像

这样的结构
foreach(v in vertices)
    v_new.position = v.position + t

通常这会在CPU上执行,即使你使用像OpenMPI这样的东西,并行化也只限于CPU内核的数量。

通过OpenGL矩阵操作进行转换,OpenGL实现可以大规模并行化操作;在现代GPU的情况下,数千个"流" (大致以锁步方式运行的线程)并行执行。

虽然完全可以执行简单的翻译,如上面的着色器一样,您通常会使用矩阵将多个转换合并为一个操作。