Opengl - GLM :: Ortho + GLM_COORDINATE_SYSTEM =很奇怪?

时间:2017-12-17 15:59:05

标签: c++ opengl

虽然我是opengl的新手,并且勉强寻求帮助,但我认为需要对Z轴,深度测试和GLM:ortho进行一些澄清。 与此争吵了一两个星期,一切都从一开始就“逆转”了。

所以即时使用:

  • glDepthFunc(GL_LESS);
  • glDepthRange(0.0f, 1.0f);
  • glm::ortho(0.0f, 800, 0.0f, 800), 0.0f, 1.0f);
  • Z轴为Y / 800(高度),Y = 20的物体落后于Y = 10.
Okej,所以一切都应该加起来,小Z在前面,后面是大,但没有。一切都是相反的。

根据这个thread和glDepthFunc / glClearDepth的默认值,当MVP被提供给着色器时,一切都应该在左手坐标中。

因此,当我读到链接的线程时,我发现glm :: ortho应该将右手坐标(因为这显然是每个人在示例中使用的东西)转换为左手坐标。听起来不错,为什么它不起作用?

当你查看GLM库时,你会发现glm :: ortho,glm :: orthoLH和glm :: orthoRH听起来非常苛刻。如果我使用glm :: orthoLH,一切都会加起来并且完美无缺,因为它将我的所有坐标转换为左手坐标。那么为什么glm :: ortho不能为我做这个呢?

编译GLM库时,显然有一个设置。当调用glm :: ortho时,GLM_COORDINATE_SYSTEM控制系统是否将默认使用glm :: orthoLH或glm :: orthoRH。令我惊讶的是,glm :: orthoLH不是默认值。

如果你查看GLM的源代码,你会发现这些行,

#define GLM_LEFT_HANDED                         0x00000001      // For DirectX, Metal, Vulkan
#define GLM_RIGHT_HANDED                        0x00000002      // For OpenGL, default in GLM

#ifdef GLM_FORCE_LEFT_HANDED
#       define GLM_COORDINATE_SYSTEM GLM_LEFT_HANDED
#else
#       define GLM_COORDINATE_SYSTEM GLM_RIGHT_HANDED
#endif

OpenGL是右撇子,不需要将ortho转换成左手?

所以我的问题是,

  • 为什么GLM认为OpenGL是右撇子?
  • 在处理着色器时,OpenGL是否真的想让MVP成为右手?

如果这没有任何意义,请纠正我。我也很困惑:))

1 个答案:

答案 0 :(得分:2)

我认为你的主要困惑与这个问题有关:

  

为什么GLM认为OpenGL是右撇子?

OpenGL不是右撇子,也不是左撇子。 OpenGL只是一个渲染API,而不是一个坐标系。

在典型的渲染管道中,您确实有许多不同的坐标系,例如:

  • 对象空间/模型空间
  • 世界空间
  • 眼睛空间/相机空间/视图空间
  • 剪辑空间
  • 规范化设备坐标
  • window sapce

这些坐标系中的每一个都可以拥有自己的惯例,包括它自己的惯用手法。

具有固定功能管道和集成矩阵堆栈的旧版OpenGL考虑了一些坐标约定(但它并未完全强制您使用这些约定)。

如此经典的OpenGL约定是:

标准化的设备空间/窗口空间左手,x指向右侧,y向上,z指向屏幕,右侧用x向右,y向上,摄像机指向-z方向。对象和世界空间通常也是右手(因此视图转换只是旋转+平移,没有镜像)。

在投影矩阵中完成了手性的翻转。传统GL的其他一些惯例是,近和远剪裁平面位置始终被定义为到观察方向的距离,因此glOrtho(..., 2,5)确实设置了映射{{1}的变换{}} z_eye=-2z_ndc=-1 z_eye=-5

如果你看看我写的映射,它应该解释这个问题:

  Okej,所以一切都应该加起来,小Z在前面,后面是大,但没有。一切都是相反的。

如你所见,“小”z(-5)在后面,“大”z(-2)在前面,就像它应该在右手坐标系中一样。

NOT 设置z_ndc=1时,glm使用与旧版GL相同的约定。它将通过在proejction矩阵中翻转z来建立右手视图空间(并假设所有后面的空间NDC和窗口空间都配置为左手)。

如果您设置了GLM_FORCE_LEFT_HANDED,它将不会沿z引入镜像,但仍会将GLM_FORCE_LEFT_HANDEDnear视为距观看方向的距离,现在为{{1 }}。这将产生建立左手视图空间的结果(只要NDC和Window空间也设置为左手)。

  

在处理着色器时,OpenGL是否真的需要右手使用MVP?

这些都是公约。你必须以某种方式决定它们,没有人比其他人更好。如果你有不同的部分或部分使用不同的约定,这些东西只会变得有趣(而且很烦人),你必须非常小心地在正确的位置正确地转换数据。