c++ - 无法让 CreateDDSTextureFromFile 工作

标签 c++ directx directx-11 hresult dds-format

所以,几个小时以来,我一直在努力找出我的问题,但我不知道自己做错了什么。在 DirectX 编程方面,我是一个菜鸟,所以我一直在学习一些教程,现在,我正在尝试创建一个 obj 加载器。 http://www.braynzarsoft.net/index.php?p=D3D11OBJMODEL

但是,我无法让我的纹理正常工作。

这是我尝试加载 DDS 纹理的方式:

ID3D11ShaderResourceView* tempMeshSRV = nullptr;
hr = CreateDDSTextureFromFile(gDevice, L"boxTexture.dds", NULL, &tempMeshSRV);

if (SUCCEEDED(hr))
 {
 textureNameArray.push_back(L"boxTexture.dds");
 material[matCount - 1].texArrayIndex = meshSRV.size();
 meshSRV.push_back(tempMeshSRV);
 material[matCount - 1].hasTexture = true;
 }

但是,我的 HRESULT 永远不会成功,但它也不会崩溃。如果我将鼠标悬停在 hr 上,它只会显示“HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) 我还尝试删除 if 语句,但这只会使我的框变黑。 知道我做错了什么吗? =/

提前致谢!

最佳答案

最有可能的问题是您的“boxTexture.dds”是一个每像素 24 位格式的文件。在 Direct3D 9 中,这是 D3DFMT_R8G8B8 并且相当常见。但是,有 no DXGI equivalent format每像素 24 位,因此需要格式转换才能工作。

DirectX Tool Kit 中的 DDSTextureLoader 模块被设计成一个最小开销函数,因此根本没有运行时转换。如果数据直接映射到 DXGI 格式,则会加载。如果没有,它将失败并返回 HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)

根据您的使用场景,有两种不同的解决方案。

  1. 理想的解决方案是将“boxTexture.dds”转换为受支持的格式。您可以使用 DirectXTex 提供的 texconv 命令行工具来完成此操作.这是目前为止最好的选择,这样可能代价高昂的转换操作就可以一次性完成,而不是在您的应用程序运行和加载数据时一次性完成。
  2. 如果您实际上没有控制您尝试加载的 dds 文件的来源(即它们是用户提供的任意文件,或者您正在使用某种必须支持旧格式的内容工具),那么您应该利用 DirectXTex “全脂”LoadFromDDSFile 函数,它具有用于处理遗留 DDS 文件格式的大量转换代码。

请注意,如 CodePlex wiki documentation 中所列,许多旧格式 DDS 文件可能会发生这种情况。

  • D3DFMT_R8G8B8 (24bpp RGB) - 使用 32bpp 格式
  • D3DFMT_X8B8G8R8 (32bpp RGBX) - 使用 BGRX、BGRA 或 RGBA
  • D3DFMT_A2R10G10B10 (BGRA 10:10:10:2) - 使用 RGBA 10:10:10:2
  • D3DFMT_X1R5G5B5 (BGR 5:5:5) - 使用 BGRA 5:5:5:1 或 BGR 5:6:5
  • D3DFMT_A8R3G3B2、D3DFMT_R3G3B2 (BGR 3:3:2) - 扩展为受支持的格式
  • D3DFMT_P8、D3DFMT_A8P8(8 位调色板)- 扩展为受支持的格式
  • D3DFMT_A4L4(亮度 4:4)- 扩展为支持的格式
  • D3DFMT_UYVY (YUV 4:2:2 16bpp) - 转换为 YUY2

另见 Direct3D 11 Textures and Block Compression

关于c++ - 无法让 CreateDDSTextureFromFile 工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27951873/

相关文章:

c# - C++ 中的 DirectX11 引擎和 C# 中的接口(interface)

c++ - Windows 8.1 上的 DirectX 11 缺少 SDK 组件

c++ - 有什么办法可以避免发生堆栈粉碎时终止程序?

c++ - 使用 "using"语法将标准容器成员方法引入其子类的范围对运算符不起作用

c++ - 逐行复制文件

directx - HLSL:高斯模糊效果

constants - DirectX11 设置着色器常量

c++ - 将函数传递给同一类中的另一个函数

installation - 如何从 Inno-setup 安装 DirectX 可再发行组件?

c++ - DXGetErrorString 新手问题