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

如何用DirectXTex(C++)处理DDS纹理并保存为DDS与TGA?代码存TGA失败

DirectXTex处理DDS纹理并保存TGA的问题修复与完整实现

原代码存在的核心问题

  1. 使用const Image*修改像素属于未定义行为,ScratchImage的内部数据需通过可写接口访问
  2. 若加载的DDS为压缩格式(如BC1-BC7),直接遍历修改像素无效,必须先转换为非压缩格式
  3. 未检查API调用的HRESULT返回值,无法定位保存失败的具体原因
  4. SaveToTGAFile对输入图像格式有要求,需确保是TGA支持的非压缩格式

修正后的完整代码

#include <DirectXTex.h>
#include <iostream>

using namespace DirectX;

int main()
{
    HRESULT hr = S_OK;

    // 加载DDS文件
    ScratchImage image;
    TexMetadata metadata;
    hr = LoadFromDDSFile(L"texture.dds", DDS_FLAGS_NONE, &metadata, image);
    if (FAILED(hr))
    {
        std::wcerr << L"加载DDS文件失败,错误码: " << hr << std::endl;
        return -1;
    }

    // 检查是否为压缩格式,转换为RGBA8非压缩格式以便修改像素
    ScratchImage convertedImage;
    if (IsCompressed(metadata.format))
    {
        hr = Decompress(image.GetImages(), image.GetImageCount(), image.GetMetadata(),
            DXGI_FORMAT_R8G8B8A8_UNORM, convertedImage);
        if (FAILED(hr))
        {
            std::wcerr << L"解压缩纹理失败,错误码: " << hr << std::endl;
            return -1;
        }
        image = std::move(convertedImage);
        metadata = image.GetMetadata();
    }

    // 获取可写的图像数据
    Image* img = image.GetImage(0, 0, 0);
    if (!img)
    {
        std::wcerr << L"获取图像数据失败" << std::endl;
        return -1;
    }

    // 通道操作示例:反转R通道,交换G和B通道
    size_t pixelCount = metadata.width * metadata.height;
    uint8_t* pixels = reinterpret_cast<uint8_t*>(img->pixels);
    for (size_t i = 0; i < pixelCount; ++i)
    {
        size_t offset = i * 4;
        // 反转R通道
        pixels[offset] = 255 - pixels[offset];
        // 交换G和B通道
        std::swap(pixels[offset + 1], pixels[offset + 2]);
    }

    // 保存为TGA文件
    hr = SaveToTGAFile(*img, TGA_FLAGS_NONE, L"texture.tga");
    if (FAILED(hr))
    {
        std::wcerr << L"保存TGA文件失败,错误码: " << hr << std::endl;
        return -1;
    }

    // 保存为DDS文件(使用修改后的非压缩数据,若需要保留原格式可重新压缩)
    hr = SaveToDDSFile(image.GetImages(), image.GetImageCount(), image.GetMetadata(),
        DDS_FLAGS_NONE, L"texture_modified.dds");
    if (FAILED(hr))
    {
        std::wcerr << L"保存DDS文件失败,错误码: " << hr << std::endl;
        return -1;
    }

    std::wcout << L"纹理处理完成,已保存TGA和DDS文件" << std::endl;
    return 0;
}

关键要点说明

  • 格式转换:通过IsCompressed判断纹理格式,压缩纹理调用Decompress转换为DXGI_FORMAT_R8G8B8A8_UNORM,确保可直接操作RGBA像素
  • 可写像素访问:去掉const修饰,通过Image*获取可写指针,避免未定义行为
  • 错误检查:对所有DirectXTex API的HRESULT返回值做校验,快速定位问题
  • 通道操作:示例包含反转R通道、交换G/B通道,可根据需求修改逻辑(如反转Alpha通道、交换R/A通道等)
  • 保存选项:SaveToTGAFile使用TGA_FLAGS_NONE,若需保留Alpha通道可改用TGA_FLAGS_ALPHA;保存DDS时若需恢复压缩格式,可调用Compress接口重新压缩

内容的提问来源于stack exchange,提问作者Erdos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:23:38