OpenGL中的GL_R8和GL_R8UI有什么不同吗?

Is GL_R8 and GL_R8UI different in OpenGL?

本文关键字:GL 什么 R8UI 中的 R8 OpenGL      更新时间:2023-10-16

我创建了一个模块ModernGL来简化OpenGL在python3中的使用。

这就是我为具有 1、2、3 或 4 个组件的渲染缓冲区选择正确格式的方式:

const int int_formats[] = {0, GL_R8, GL_RG8, GL_RGB8, GL_RGBA8};
const int float_formats[] = {0, GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F};
int format = floats ? float_formats[components] : int_formats[components];
...
gl.RenderbufferStorage(GL_RENDERBUFFER, format, width, height);

例如,具有components=1floats=False的渲染缓冲区将选择format=GL_R8

以前(在此提交之前)我有:

const int int_formats[] = {0, GL_R8UI, GL_RG8UI, GL_RGB8UI, GL_RGBA8UI};

根据此文档: 如果您想要 3 分量无符号整数格式,每个分量 8 位,请使用 GL_RGB8UI。GL_R16F每个组件使用 16 位的 1 分量浮点格式。

然而

当我选择GL_R8UI时,glReadPixels() 将失败并显示GL_INVALID_OPERATION当我选择GL_R8时,glReadPixels() 会将像素读取为unsigned chars

我有一个测试因不支持的格式而失败。

  • GL_R8GL_R8UI有什么区别
  • 为什么我能够创建一个带有GL_R8UI的渲染缓冲区,但读取失败。

注意:我用GL_R8UIGL_RGB8UI进行了测试,GL_RGBA8UI当调用glReadPixels时,它们都没有工作。

很久以前,OpenGL 函数的工作方式与简化的 API 相同。他们接受 1、2、3 或 4 作为"组件数"并选择了正确的格式。 这早已被放弃,因为我们不仅想要支持太多不同的格式,而且我们还希望能够以不同的方式解释这些格式。

考虑数据类型GL_UNSIGNED_BYTE

  • 我们可以对其进行规范化,将其转换为 0..1 范围内的浮点数,精度为 8 位。 内部格式GL_R8,带有uniform sampler2D,产生vec4

  • 我们可以决定不将其正常化。 与上面相同,只是现在值在 0..255 范围内。

  • 我们可以将其视为 0..255 范围内的整数。 内部格式GL_R8UI,带有uniform usampler2D,产生uvec4

渲染缓冲区也是如此。 如果片段着色器以以下内容开头:

out float Color;

然后,您可以渲染到GL_R8.

但是,如果您的片段着色器以以下内容开头:

out uint Color;

然后,您必须渲染为其他格式,例如GL_R8UI. 请注意,在 OpenGL 中,整数的规则有些限制:您不能对整数纹理使用过滤,也不能对片段输出使用 alpha 混合(您可以使用ADDSUBTRACTMINMAX)。

简而言之,GL_R8GL_R8UI都与GL_UNSIGNED_BYTE,但是当您在程序中使用它们时,它们的工作方式完全不同。这就是为什么OpenGL函数不再只将许多组件作为参数的原因。