gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 01:39:29 26 4
gpt4 key购买 nike

虽然我是 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_COORDINATE_SYSTEM 控制在调用 glm::ortho 时系统是否默认使用 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 是右手的,不需要将正交转换为左手?

所以我的问题是,

  • 为什么 GLM 认为 OpenGL 是右撇子?
  • 在处理着色器时,是否存在 OpenGL 实际上希望 MVP 为右手的情况?

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

最佳答案

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

Why does GLM think OpenGL is right-handed?

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

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

  • 项目空间/模型空间
  • 世界空间
  • 眼睛空间/相机空间/视野空间
  • 剪辑空间
  • 标准化设备坐标
  • window 空间

这些坐标系中的每一个都可以有自己的约定,包括自己的惯用手。

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

经典的 OpenGL 约定是:

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

左右手的翻转是在投影矩阵中完成的。遗留 GL 没有其他约定是近裁剪平面和远裁剪平面位置始终定义为到观察方向的距离,所以 glOrtho(..., 2,5) 实际上设置了一个转换,将 z_eye=-2 映射到 z_ndc=-1 并将 z_eye=-5 映射到 z_ndc= 1

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

Okej, so everything should add up, small Z is in front and big in the back, but no. Everything is the opposite.

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

当您NOT设置GLM_FORCE_LEFT_HANDED时,glm 使用与遗留 GL 相同的约定。它将通过翻转投影矩阵中的 z 来建立右手 View 空间(并假设所有后面的空间 NDC 和窗口空间都配置为左手)。

如果您设置GLM_FORCE_LEFT_HANDED,它不会引入沿 z 的镜像,但它仍会将nearfar 视为距离查看方向,现在是 +z。这将产生建立左手 View 空间的结果(只要 NDC 和窗口空间也设置为左手)。

Is there any case where OpenGL acually want MVP as right-handed while processing shaders?

这些都只是惯例。您必须以一种或另一种方式来决定它们,并且没有人比另一个更好。如果您有不同的部分或部分使用不同的约定,那么这件事只会变得有趣(和烦人),您必须非常小心地在正确的位置正确转换数据。

关于c++ - Opengl - GLM::Ortho + GLM_COORDINATE_SYSTEM = 奇怪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47856866/

26 4 0
文章推荐: c++ - mingw是否支持clr safe?
文章推荐: javascript - 如何在两个不同的域上执行功能?
文章推荐: c++ - 为什么一个类方法在其对象文件中不存在而其他方法存在?
文章推荐: javascript - jQuery BlockUI 不阻止