切换投影时的矩阵模式

时间:2018-06-05 12:26:09

标签: python opengl

我在很多地方看到这个,但我不太明白。例如这段代码:

def update_projection(self):
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()

    if self.perspective_mode:
        self.switch_to_perspective_mode()
    else:
        self.switch_to_parallel_mode()
    glMatrixMode(GL_MODELVIEW)

这些问题可能看起来很基本,但我不了解他们在实践中的工作:

  1. MatrixMode究竟是什么?
  2. 为什么GL_PROJECTION在投影if-clause之前?
  3. 为什么要切换回GL_MODELVIEW

2 个答案:

答案 0 :(得分:2)

  1. OpenGL(在我们这里讨论的古代版本中)提供了多个矩阵堆栈:ModelView,Projection(和其他一些)。主要区别在于,在计算照明和之后投影之前应用ModelView。使用glMatrixMode可以打开下一个命令将运行的矩阵堆栈。阅读this question中有关矩阵堆栈的更多信息。

  2. 这是因为两种方法(switch_to_perspective_modeswitch_to_parallel_mode)将设置投影矩阵,最可能是正投影或透视投影。由于它们应该应用于投影矩阵堆栈,因此必须事先切换到它。

  3. 很可能是因为下一个命令想要在ModelView矩阵上运行。

答案 1 :(得分:0)

我们使用的最常见的是MVP,它是模型 - 视图 - 投影矩阵。在这种情况下,只有2个矩阵,GL_MODELVIEW包含模型和视图组件。

这背后的想法:

  • 模型矩阵负责将模型放入世界。形状通常位于(0,0,0)周围,或者至少它们的顶点是,然后可以通过操纵模型矩阵在多个位置绘制多次
  • 视图矩阵通常表示相机的位置。无论在场景中定义哪个模型,"播放器"或观察者的位置取决于他如何看待这些物体。在大多数情况下,lookAt过程用于此组件。
  • 投影矩阵是我们用来投影屏幕上的对象的东西。它提供了有关视野的信息(但实际上取决于我们使用的是什么)。最常见的是使用glOrthoglFrustum。它们通常取决于屏幕/视图大小或宽高比。

因此投影矩阵很少甚至从不更新(第一次除外)。即使在每一帧上,视图矩阵也可能经常变化,如果" user"移动。但模型矩阵将不断更新,就像绘制的每个模型一样,甚至更频繁(每个模型的每个部分)。

所以代码的作用是:

  • 开始修改投影矩阵
  • 将其设为身份
  • 应用一个或另一个(在if声明中)
  • 开始修改模型视图矩阵

所有这些都完全有道理,但最后一个对你来说可能有点奇怪。虽然不清楚,但我打赌原因是程序期望它总是修改模型视图矩阵。因此,每当选择另一个矩阵模式时,预计该操作将恢复为模型视图矩阵。

原因是(如上所述)模型 - 视图矩阵将更新很多次,而投影则不会。如果没有模块可以说明当前正在更新哪个矩阵,那么在更新模型矩阵之前,应该调用glMatrixMode(GL_MODELVIEW)。这意味着对于绘制的每个模型,我们应该调用此行以确保设置正确的设置。这是一个巨大的冗余,并期望将模型矩阵设置为矩阵模式获得一些性能。