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

Opengl 将未压缩的DDS加载到GL纹理,opengl,colors,textures,texture2d,dds-format,Opengl,Colors,Textures,Texture2d,Dds Format,我有一份文件。我编写了一个简单的DDS阅读器,用于读取DDS头并根据MSDN规范打印其详细信息。它表示它是一个RGB DDS,每像素位深度为32字节,alpha被忽略,即像素格式为X8R8G8B8(或A8R8G8B8)。为了验证这一点,我还在一个十六进制编辑器中打开了这个文件,该编辑器将第一个(即从数据开始)4字节显示为BB GG RR 00(将它们替换为第一个像素的右十六进制颜色值)。OpenGL的纹理复制函数作用于字节(至少在概念上),因此从它的角度来看,这些数据是B8G8R8A8。如果我的

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

现在转到
glTexImage2D
内部格式I pass
RGBA8
以及外部格式和类型I pass
BGRA
无符号字节
。这将导致渲染输出中出现蓝色色调。在我的片段着色器中,为了验证,我做了一次旋转来交换
R
B
,它正确地渲染了

我还原了着色器代码,然后将类型从
UNSIGNED_BYTE
替换为
UNSIGNED_INT_8_8_8_REV
(基于),它仍然呈现蓝色色调。现在将外部格式更改为
RGBA
,并使用任何一种类型(
无符号字节
无符号字节
无符号字节
)都可以呈现良好效果

  • 由于OpenGL不支持ARGB,所以给出BGRA是可以理解的。但是为什么RGBA在这里工作正常呢?这似乎是错误的
  • 为什么类型对通道的顺序没有影响
  • GL_解包_校准是否有此轴承?我将其保留为默认值(4)。如果我正确阅读了手册,这应该不会影响如何读取客户机内存
详细信息

  • OpenGL 3.3版
  • 支持高达OpenGL 4.0的英特尔高清图形
  • 用于加载DDS文件并获取数据指针

    • 我终于自己找到了答案!把它贴在这里,以便将来对某人有所帮助

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

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

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

      不,它有效果。我正在尝试这个实验的机器是一台Intel x86_64 little endian机器。明确指出客户端像素数据始终按客户端字节顺序排列。现在,当传递
      GL_UNSIGNED_BYTE
      GL_UNSIGNED_INT_8_8_8_8_REV
      时,基本基类型(而不是组件类型)都是
      UNSIGNED INT
      ;因此,在小端机上从
      数据
      读取
      int
      意味着寄存器中的变量将以交换的字节结束,即RAM中的
      RR GG BB AA
      将以
      AA BB GG RR
      的形式到达VRAM;当由RGBA类型的纹理(
      RR GG BB AA
      )寻址时,读取
      AA
      实际上会给出
      RR
      。为了纠正它,OpenGL实现交换字节以中和机器的端性,在
      GL\u UNSIGNED\u BYTE
      类型的情况下。而对于
      GL_UNSIGNED_INT_8_8_8_8_8_REV
      我们明确指示OpenGL交换字节顺序,从而正确呈现。但是,如果类型作为
      GL_UNSIGNED_INT_8_8_8_8_8
      传递,则渲染会出错,因为我们指示OpenGL在机器上读取字节时复制字节

      GL\u UNPACK\u校准
      中是否有轴承?我将其保留为默认值(4)。如果我正确阅读了手册,这应该不会影响如何读取客户机内存

      它确实与将纹理数据从客户端内存解包到服务器内存有关系。但是,这是为了考虑图像行中存在的填充字节,以便正确计算步幅(节距)。但是对于这个问题,它没有方位,因为它的基音标志是0,也就是说,DDS文件中没有填充位


      相关材料:

      这个答案希望是正确的,但我不是100%肯定,因为我在推导中做了一些假设。如果这是错误的,请让我摆脱我的无知。谢谢正如您所知,DDS文件格式可以使用填充进行对齐。在D3D世界中,这种事情被称为“音高”。您可能需要阅读
      dwPitchOrLinearSize
      部分。谢谢您的提示!我已经更新了答案;我匆忙地看了文件,我的坏习惯。希望它的其余部分是正确的。我能看看你的读者吗?当我问这个问题时,我写了一些扔掉的东西。多亏了你的邀请,我终于重新写了一篇文章:!正如答案所说,上述问题是由于最近修复的GLI中的错误造成的。