将未压缩的DDS加载到GL纹理

时间:2014-11-29 08:50:25

标签: opengl colors textures texture2d dds-format

this DDS档案。我写了一个简单的DDS阅读器来读取DDS标题并根据MSDN规范打印其详细信息。它表示它是RGB DDS,每像素位深度为32字节,并且忽略α,即像素格式为X8R8G8B8(或A8R8G8B8)。为了验证这一点,我还在十六进制编辑器中打开了这个文件,该编辑器显示第一个(即从数据开始)4个字节为BB GG RR 00(用第一个像素替换它们的右十六进制颜色值)。 I read OpenGL的纹理复制函数作用于字节(至少在概念上),因此从它的角度来看,这个数据是B8G8R8A8。如果我的理解错误,请纠正我。

现在转到glTexImage2D 内部格式我将RGBA8传递给外部格式类型我传递{{ 1}}和BGRA。这会在渲染输出中产生蓝色色调。在我的片段着色器中,为了验证,我做了一个混合交换UNSIGNED_BYTER并且它正确渲染。

我还原了着色器代码,然后将{em>类型从B替换为UNSIGNED_BYTE(基于this suggestion),它仍然呈现蓝色色调。现在将外部格式更改为UNSIGNED_INT_8_8_8_8_REV并使用类型RGBAUNSIGNED_BYTE),呈现正常!

  • 由于OpenGL不支持ARGB,因此给予BGRA是可以理解的。但是为什么RGBA在这里正常工作?这似乎不对。
  • 为什么类型对通道的排序没有影响?
  • GL_UNPACK_ALIGNMENT对此有影响吗?我把它作为默认值(4)。如果我正确阅读手册,这对于如何读取客户端内存没有影响。

详情

  • OpenGL版本3.3
  • 支持OpenGL 4.0的英特尔高清显卡
  • 使用GLI加载DDS文件并获取数据指针

1 个答案:

答案 0 :(得分:3)

我终于找到了自己的答案!在此发布,以便将来可以帮助某人。

  

由于OpenGL不支持ARGB,因此给予BGRA是可以理解的。但是为什么RGBA在这里正常工作?这似乎不对。

通过检查void* data指向的内存,当要求指向图像二进制数据的指针时GLI返回,可以看出GLI在将数据从文件传输到客户端内存时已经重新排序了字节。记忆窗口从低地址到高地址显示RR GG BB AA形式的数据。这解释了为什么传递GL_RGBA有效。但是,GLI的错误在于,当查询外部格式时,它返回GL_BGRA而不是GL_RGBA。已提出A bug来解决这个问题。

  

为什么类型对通道的排序没有影响?

不,它有效果。我正在尝试这个实验的机器是Intel x86_64小端机器。 OpenGL Wiki明确指出客户端像素数据始终处于客户端字节排序中。现在,当传递GL_UNSIGNED_BYTEGL_UNSIGNED_INT_8_8_8_8_REV时,底层基本类型(不是组件类型)对于两者都是unsigned int;因此,在小端机器上从int读取data意味着,寄存器中的变量将以交换的字节结束,即RAM中的RR GG BB AA将到达VRAM { {1}};当由RGBA(AA BB GG RR)类型的纹理寻址时,阅读RR GG BB AA实际上会给AA。为了纠正它,在RR 类型的情况下,OpenGL实现交换字节以中和机器的字节序。而对于GL_UNSIGNED_BYTE,我们明确指示OpenGL交换字节顺序,因此它正确呈现。但是,如果将类型作为GL_UNSIGNED_INT_8_8_8_8_REV传递,那么渲染就会被搞砸,因为我们指示OpenGL复制在机器上读取的字节。

  

GL_UNSIGNED_INT_8_8_8_8对此有影响吗?我把它作为默认值(4)。如果我正确阅读了本手册,这对于如何读取客户端内存没有任何影响。

它确实对从客户端内存到服务器内存的纹理数据解包有影响。但是,这是为了解释图像行中存在的填充字节,以正确计算步幅(音高)。但是对于这个问题,它没有任何影响,因为它的音高标志为0,即所讨论的DDS文件中没有填充位。

相关材料:https://www.opengl.org/wiki/Pixel_Transfer#Pixel_type