【发布时间】:2021-07-08 00:47:46
【问题描述】:
我已经阅读了很多文章和代码,但我仍然无法让它工作,我已经阅读了纹理中标题的所有 128 字节,它们读取了实际纹理的 65536 字节压缩数据(纹理的分辨率为 256x256,每个压缩像素使用 1 个字节)。我试图创建我的解压缩算法但没有成功,我决定使用别人的,所以我在这里找到了this 代码。这是我试图传递给它的参数,以便它解压缩我的 DDS 纹理。BlockDecompressImageDXT5(textureHeader.dwWidth, textureHeader.dwHeight, temp, packedData)
注意:textureHeader 是一个有效的结构,其中加载了 DDS 纹理的标头数据,temp 是一个无符号字符数组,包含从 DDS 纹理读取的所有 DDS 数据,packedData 是一个无符号长数组我期待收到最终的解压缩数据。因此,在我链接的代码中,每个像素的 RGBA 通道都打包在 PackRGBA 函数中,packedData 中的每种颜色对应一个字节。在将数据指向D3D11_SUBRESOURCE_DATApSysMem 处的纹理数据之前,我已经将每个字节从 unsigned long packedData 分配到 4 个不同的 unsigned char m_DDSData 这种方式:
for (int i{ 0 }, iData{ 0 }; i < textureHeader.dwPitchOrLinearSize; i++, iData += 4) //dwPitchOrLinearSize is the size in bytes of the compressed data.
{
m_DDSData[iData] = ((packedData[i] << 24) >> 24); //first char receives the 1st byte, representing the red color.
m_DDSData[iData + 1] = ((packedData[i] << 16) >> 24); //second char receives the 2nd byte, representing the green color.
m_DDSData[iData + 2] = ((packedData[i] << 8) >> 24); //third char receives the 3rd byte, representing the blue color.
m_DDSData[iData + 3] = (packedData[i] >> 24); //fourth char receives the 4th byte, representing the alpha color.
}
注意:m_DDSData应该是D3D11_SUBRESOURCE_DATA用来指向纹理数据的最终数据数组,但是当我使用它时this是我得到的那种结果,只有一个帧用随机颜色代替我的实际纹理。我也有其他类型纹理的算法,它们可以正常工作,所以我可以保证问题只出在 DDS 压缩格式中。
编辑: 另一个例子,这是一个胸部模型,程序应该渲染胸部的纹理:https://prnt.sc/11b62b6
【问题讨论】:
-
您应该看看DirectXTex,它有用于压缩和解压缩所有 BC 格式的 C++ 代码。
-
你到底想做什么?您想使用带有 BC3_UNORM 纹理的 Direct3D 进行渲染,或者 - 您是否尝试在 CPU 上将 BC3_UNORM 纹理数据转换为线性格式?
-
@ChuckWalbourn 我真的不太清楚,我在网上没有找到很多内容来解释这些带有块压缩和 BC3_UNORM 格式的 alpha 0 或 1 的东西是如何工作的,我只是走一条死路,但回答你的问题,我的目标是加载我在这里的一些 DDS 纹理并渲染它。
-
所有纹理都采用相同的格式,我真的希望能够直接加载它们,这样我就可以在运行时访问它们的数据。但是,如果您能告诉我是否有一种方法可以加载它们而不必像您所说的那样转换它们,那也会很有帮助。
-
Direct3D 硬件支持直接渲染 BC 压缩纹理。您只需使用
DXGI_FORMAT_BC3_UNORM格式创建纹理并使用它进行渲染,然后在像素着色器中您将看到 RGBA 值。 DirectXTex 或 DirectX Toolkit 中的DDSTextureLoader 可以为您加载和创建纹理。
标签: c++ image-compression direct3d11 dds-format