You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

失败原因分析

  1. 格式不兼容:TGA文件格式不支持DXGI_FORMAT_R32G32B32A32_FLOAT浮点格式,仅支持8/16/24/32位整数类格式(如DXGI_FORMAT_R8G8B8A8_UNORM)。
  2. 路径不存在:目标路径./Screenshots/city/color/如果未提前创建,SaveToTGAFile会因无法写入而失败。
  3. 格式符不匹配: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:58:20