Direct3D11中RenderTarget数组保存为文件失败求助
问题:RenderTarget数组保存为图片文件失败的解决方案
问题描述
尝试将RenderTarget数组保存为TGA图片用于调试,但SaveToTGAFile调用失败。相关代码及ScratchImage元数据如下:
代码片段
ID3D11RenderTargetView** ppRTVs; ... //rendering ... ScratchImage ScratchImage; ID3D11Resource* Resource; wchar_t fileName[256]; ppRTVs[0]->GetResource(&Resource); HRESULT hr = CaptureTexture(pd3dDevice, pd3dImmediateContext, Resource, ScratchImage); if (FAILED(hr)) { assert(FALSE); } for (int i = 0; i < ScratchImage.GetMetadata().arraySize; i++) { const Image* singleTexture = ScratchImage.GetImage(0, i, 0); swprintf_s(fileName, L"./Screenshots/city/color/texture_%zu.tga", i); hr = SaveToTGAFile(*singleTexture, TGA_FLAGS_NONE, fileName); //failed if (FAILED(hr)) { assert(FALSE); } }
ScratchImage元数据
- width = 1920
- height = 1080
- depth = 1
- arrSize = 4
- mipLevel = 11
- format = DXGI_FORMAT_R32G32B32A32_FLOAT (2)
- dimension = TEX_DIMENSION_TEXTURE2D (3)
失败原因分析
- 格式不兼容:TGA文件格式不支持
DXGI_FORMAT_R32G32B32A32_FLOAT浮点格式,仅支持8/16/24/32位整数类格式(如DXGI_FORMAT_R8G8B8A8_UNORM)。 - 路径不存在:目标路径
./Screenshots/city/color/如果未提前创建,SaveToTGAFile会因无法写入而失败。 - 格式符不匹配:
swprintf_s中使用%zu匹配int类型的i,存在格式符类型不匹配问题。
解决方案
1. 转换纹理格式为TGA支持的格式
使用DirectXTex库的Convert函数将浮点纹理转换为R8G8B8A8_UNORM格式:
ScratchImage convertedImage; hr = Convert(ScratchImage.GetImages(), ScratchImage.GetImageCount(), ScratchImage.GetMetadata(), DXGI_FORMAT_R8G8B8A8_UNORM, TEX_FILTER_DEFAULT, TEX_THRESHOLD_DEFAULT, convertedImage); if (FAILED(hr)) { assert(FALSE); }
2. 确保保存路径存在
在保存前检查并创建目标文件夹:
#include <direct.h> #include <string> // 创建目标目录,已存在时返回错误不影响后续操作 std::wstring dirPath = L"./Screenshots/city/color/"; _wmkdir(dirPath.c_str());
3. 修正格式符与保存逻辑
使用转换后的纹理数组切片进行保存,同时修正格式符匹配问题:
for (int i = 0; i < convertedImage.GetMetadata().arraySize; i++) { const Image* singleTexture = convertedImage.GetImage(0, i, 0); swprintf_s(fileName, L"./Screenshots/city/color/texture_%d.tga", i); // 使用%d匹配int类型的i hr = SaveToTGAFile(*singleTexture, TGA_FLAGS_NONE, fileName); if (FAILED(hr)) { assert(FALSE); } }
完整修改后的代码片段
ID3D11RenderTargetView** ppRTVs; ... //rendering ... ScratchImage ScratchImage; ID3D11Resource* Resource; wchar_t fileName[256]; ppRTVs[0]->GetResource(&Resource); HRESULT hr = CaptureTexture(pd3dDevice, pd3dImmediateContext, Resource, ScratchImage); if (FAILED(hr)) { assert(FALSE); } // 转换纹理格式为TGA支持的R8G8B8A8_UNORM ScratchImage convertedImage; hr = Convert(ScratchImage.GetImages(), ScratchImage.GetImageCount(), ScratchImage.GetMetadata(), DXGI_FORMAT_R8G8B8A8_UNORM, TEX_FILTER_DEFAULT, TEX_THRESHOLD_DEFAULT, convertedImage); if (FAILED(hr)) { assert(FALSE); } // 创建保存目录 std::wstring dirPath = L"./Screenshots/city/color/"; _wmkdir(dirPath.c_str()); // 遍历数组切片保存 for (int i = 0; i < convertedImage.GetMetadata().arraySize; i++) { const Image* singleTexture = convertedImage.GetImage(0, i, 0); swprintf_s(fileName, L"./Screenshots/city/color/texture_%d.tga", i); hr = SaveToTGAFile(*singleTexture, TGA_FLAGS_NONE, fileName); if (FAILED(hr)) { assert(FALSE); } }
内容的提问来源于stack exchange,提问作者donghyunlee
相关产品推荐
相关产品推荐

