OpenGL纹理上传:UNSIGNED_BYTE vs UNSIGNED_INT_8_8_8_8

15

我正在调用glTexSubImage2D。如果我的像素格式是GL_RGBA,那么像素类型GL_UNSIGNED_BYTEGL_UNSIGNED_INT_8_8_8_8是否完全相同?

此外,这两个对等吗?

  • 格式=GL_RGBA,类型=GL_UNSIGNED_INT_8_8_8_8
  • 格式=GL_BGRA,类型=GL_UNSIGNED_INT_8_8_8_8_REV

我已经尝试阅读OpenGL规范和GL_EXT_packed_pixels规范,但老实说我无从下手。

2个回答

28
答案是不和不。 必须考虑计算机中的字节顺序。如果您使用的是GL_RGBAGL_UNSIGNED_INT_8_8_8_8,那么意味着像素存储在32位整数中,颜色在该整数中按照逻辑顺序RGBA排列,例如红色在高阶字节中,alpha 在低阶字节中。但是如果机器是小端(例如Intel CPU),则实际的内存顺序为ABGR。而 GL_RGBA配合 GL_UNSIGNED_BYTE 将无论计算机是小端还是大端,都会按照RGBA顺序存储字节。 GL_BGRA 配合 GL_UNSIGNED_INT_8_8_8_8_REV 会将颜色以ARGB逻辑顺序存储到一个整数中,但是在小端机器上,内存中得到的是BGRA顺序。

4
值得指出的是,在这个例子中,GL_UNSIGNED_BYTEGL_UNSIGNED_INT_... 是像素传输类型。它们并不说明 GL 存储颜色的方式,只是当颜色数据被发送到 GL 时,“打包”颜色是如何被解释的。这是一个比较重要的区别,因为通常这些更奇特的格式的目标是匹配客户端(CPU)和服务器(GPU)格式,这样 GL 就不需要执行数据转换,可以进行简单的块传输。 - Andon M. Coleman

0

首先请参考JWWalker的回答。本回答是对其的补充,提供一个快速说明。

GL_RGBA 存储在 GL_UNSIGNED_INT_8_8_8_8 中:

0xrrggbbaa

GL_RGBA 存储在 GL_UNSIGNED_BYTE 中:

[0xrr, 0xgg, 0xbb, 0xaa]

在这两种情况下,RGBA 逻辑顺序为 r、g、b 和 a,但在小端机器上(这是正常的架构),0xrrggbbaa 的小字节(即最不重要的)先存储。如果您以每个字节一次读取 uint32_t,则首先会得到 0xaa!以下是 C++ 示例:
uint32_t color{0x11223344};
uint8_t first_byte{reinterpret_cast<uint8_t*>(color)[0]};

first_byte 将等于 0x44

有一件令人困惑的事情是单词“first”。它可以表示“在书写时首先出现”,例如“红色字节在 0xrrggbbaa 中首先出现”。这与“具有最低的内存/指针地址”不同,例如“使用小端编码时,alpha 字节在 0xrrggbbaa 中排在第一位”!当您使用 GL_RGBA 时,看起来红色将会排在第一位,但在以小端方式编码的 4 字节整数中,它只在十六进制表示中是这样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接