我this DDS档案。我写了一个简单的DDS阅读器来读取DDS标题并根据MSDN规范打印其详细信息。它表示它是RGB DDS,每像素位深度为32字节,并且忽略α,即像素格式为X8R8G8B8(或A8R8G8B8)。为了验证这一点,我还在十六进制编辑器中打开了这个文件,该编辑器显示第一个(即从数据开始)4个字节为BB GG RR 00
(用第一个像素替换它们的右十六进制颜色值)。 I read OpenGL的纹理复制函数作用于字节(至少在概念上),因此从它的角度来看,这个数据是B8G8R8A8。如果我的理解错误,请纠正我。
现在转到glTexImage2D
内部格式我将RGBA8
传递给外部格式和类型我传递{{ 1}}和BGRA
。这会在渲染输出中产生蓝色色调。在我的片段着色器中,为了验证,我做了一个混合交换UNSIGNED_BYTE
和R
并且它正确渲染。
我还原了着色器代码,然后将{em>类型从B
替换为UNSIGNED_BYTE
(基于this suggestion),它仍然呈现蓝色色调。现在将外部格式更改为UNSIGNED_INT_8_8_8_8_REV
并使用类型(RGBA
或UNSIGNED_BYTE
),呈现正常!
详情
答案 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_BYTE
或GL_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文件中没有填充位。