【问题标题】:OpenGL texture upload: UNSIGNED_BYTE vs UNSIGNED_INT_8_8_8_8OpenGL 纹理上传:UNSIGNED_BYTE 与 UNSIGNED_INT_8_8_8_8
【发布时间】:2011-12-08 19:52:42
【问题描述】:

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

另外,这两对是等价的吗?

  • Format = GL_RGBA, Type = GL_UNSIGNED_INT_8_8_8_8
  • Format = GL_BGRA, Type = GL_UNSIGNED_INT_8_8_8_8_REV

我已经尝试阅读 OpenGL 规范和 GL_EXT_packed_pixels 规范,但老实说,我无法区分它们。

【问题讨论】:

    标签: opengl pixelformat


    【解决方案1】:

    答案是否定的。您必须考虑计算机中的字节顺序。如果您有GL_RGBAGL_UNSIGNED_INT_8_8_8_8,这意味着像素存储在 32 位整数中,并且颜色在这样的整数中按照逻辑顺序 RGBA,例如红色在高位字节,阿尔法在低位字节。但是如果机器是 little-endian(如 Intel CPU),那么内存中的实际顺序是 ABGR。而GL_RGBAGL_UNSIGNED_BYTE 将按照RGBA 顺序存储字节,无论计算机是小端还是大端。

    GL_BGRAGL_UNSIGNED_INT_8_8_8_8_REV 会以 ARGB 逻辑顺序将颜色存储在一个整数中,但随后在 little-endian 机器上,您会在内存中获得 BGRA 顺序。

    【讨论】:

    • 值得指出的是,本例中的GL_UNSIGNED_BYTEGL_UNSIGNED_INT_...是像素传输类型。他们没有说 GL 如何存储颜色,只说当颜色数据发送给它时,GL 如何解释“打包”颜色。这是一个重要的区别,因为通常这些更奇特的格式的目标是匹配客户端 (CPU) 和服务器 (GPU) 格式,以便 GL 不需要执行数据转换并且可以进行简单的块传输。
    【解决方案2】:

    请先查看JWWalker's answer。这个答案是对它的补充。一个简单的插图。

    GL_RGBA存储在GL_UNSIGNED_INT_8_8_8_8中:

    0xrrggbbaa
    

    GL_RGBA' stored in 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

    令人困惑的是“第一”这个词。它可以表示“写入时首先出现”,如“红色字节在 0xrrggbbaa 中首先出现”。这与“使用 little-endian 编码时 alpha 字节在 0xrrggbbaa 中的第一个”中的“具有最低内存/指针地址”不同!当你使用GL_RGBA 时,它肯定看起来像红色将是第一个,但是当以 4 字节整数小端编码时,它只是在十六进制表示中的方式。

    【讨论】:

      猜你喜欢
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      相关资源
      最近更新 更多