OpenGL 1 像素高纹理渲染差异 Windows/Linux vs OS X

OpenGL 1 pixel high texture rendering difference Windows/Linux vs OS X

我需要帮助来理解为什么我需要进行特定更改才能使我的 OpenGL 项目在 OS X (2019 Macbook) 上运行,而如果没有更改它在 Windows 和 Linux,在 ATI 和 NVIDIA 硬件上。

有时我正在渲染一个 1024 像素宽和 1 像素高的帧缓冲区。我需要直接的正交投影,所以对于我的投影矩阵,我使用:

glm::ortho(0.f, (float)LookupMapSize, 1.f, 0.f)

使用 Windows 和 Linux 上的投影矩阵,我渲染了我的线几何图形,它按预期工作,所有像素都被写入。

然而,在 OS X 上,我最初看到我的帧缓冲区中没有任何结果,只有我用 glClearColorglClear 清除它的颜色。怀疑着色器问题,我将片段输出设置为 vec4(1) 以期待全白结果,但我仍然在帧缓冲区中只看到清晰的颜色。深度测试、混合、剔除和模板都不是问题,所以一定是我的矩阵错了。经过多次摆弄后,我终于弄清楚我必须将投影矩阵更改为:

glm::ortho(0.f, (float)LookupMapSize, 0.f, 1.f)

但是为什么呢?这种差异从何而来?所以在 Windows/Linux 中底部在 1.f,顶部在 0.f,而在 OS X 中正好相反。如果我在 Windows/Linux 上使用“OS X”矩阵,我会得到与最初在 OS X.

上完全相同的错误

我不想只在我的代码中保留这个特定于平台的更改,我想了解发生了什么。

编辑:我会自动检查我所有的 OpenGL 调用 (glGetError),没有任何 returns 任何错误。不幸的是,OpenGL 调试功能 (glDebugMessageCallback) 在 OS X...

上不可用

edit:我验证了 OSX 和 Linux/Windows glm::ortho 的结果是相同的。所以我对 OpenGL 的输入在所有平台上都是一样的。

OpenGL 未指定为像素精确渲染 API,并且 GPU 和不同的驱动程序(即使在同一 GPU 上)不会使用相同的输入产生相同的输出。但是,OpenGL 规范实际上对实现者提出了硬性要求,而您作为 API 的用户可以依赖。

在你的情况下,如果你设置一个 1 像素高的视口,并使用正交矩阵设置 y 范围从 01 意味着 y=0 将是底部 edge 像素行,1 将是顶部 edge。如果您恰好在两个像素之间的边缘上画一条线,OpenGL 规范没有指定在这种情况下实现必须“舍入”到哪个方向,它们只是必须始终采用相同的舍入方式。

所以这意味着如果你有两个选项y=0y=1其中一个 *不会 划清界线(因为从技术上讲它位于帧缓冲区之外),但哪一个完全是特定于实现的。

但是,故意在像素之间的边缘画线是个坏主意,特别是如果您有一些非常具体的像素要用它来填充。将顶点设置在要填充的像素的 中心 最有意义,这就是 y=0.5.

但是,对于只生成 widthx1 LUT 的通道,我认为不需要设置任何类型的变换矩阵,您可以在未变换的 clipsace 中工作,只需从 (-1,0,0,1)(1,0,0,1)y=0 这里没问题,因为那正是视口的中心。