【问题标题】:Loading an uncompressed DDS to GL texture将未压缩的 DDS 加载到 GL 纹理
【发布时间】:2015-01-27 19:31:41
【问题描述】:

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

现在到glTexImage2D 内部格式 我通过RGBA8外部格式类型 我通过BGRA 和@987654330 @。这会导致渲染输出中出现蓝色调。在我的片段着色器中,为了验证,我做了一个调换 RB 并且它正确渲染。

我还原了着色器代码,然后用UNSIGNED_INT_8_8_8_8_REV(基于this suggestion)替换了UNSIGNED_BYTE 中的type,它仍然呈现蓝色调。现在将 external format 更改为 RGBA 并使用 typeUNSIGNED_BYTEUNSIGNED_INT_8_8_8_8_REV)呈现良好!

  • 由于OpenGL不支持ARGB,给BGRA是可以理解的。但是 RGBA 怎么会在这里正常工作呢?这似乎是错误的。
  • 为什么 type 对通道的排序没有影响?
  • GL_UNPACK_ALIGNMENT 对此有影响吗?我将其保留为默认值 (4)。如果我正确阅读了手册,这应该不会影响读取客户端内存的方式。

详情

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

【问题讨论】:

  • 我可以看看你的读者吗?
  • 当我问这个的时候,我写了一些扔掉的东西。感谢您的提问,我最终重新写了一些东西:shared here!正如答案所说,上述问题是由于最近修复的 GLI 中的错误造成的。

标签: opengl colors textures texture2d dds-format


【解决方案1】:

我终于自己找到了答案!将其发布在这里,以便将来对某人有所帮助。

由于 OpenGL 不支持 ARGB,所以给 BGRA 是可以理解的。但是 RGBA 怎么会在这里正常工作呢?这似乎是错误的。

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

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

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

GL_UNPACK_ALIGNMENT 对此有影响吗?我将其保留为默认值 (4)。如果我正确阅读了手册,这应该不会影响读取客户端内存的方式。

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

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

【讨论】:

  • 这个答案希望是正确的,但我不能 100% 确定它,因为我在演绎中做了一些假设。如果有错,opengl 的一些高手可能请让我摆脱我的无知。谢谢!
  • 请注意,DDS 文件格式可以有用于对齐的填充。在 D3D 世界中,这种事情被称为“音高”。您可能需要阅读dwPitchOrLinearSizehere 部分。
  • 感谢您的提示!我已经更新了答案;我匆忙阅读了文档,我的错。希望其余的都是正确的。
猜你喜欢
  • 2012-09-26
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 2018-01-28
  • 2023-01-12
  • 1970-01-01
相关资源
最近更新 更多