如何用DirectXTex(C++)处理DDS纹理并保存为DDS与TGA?代码存TGA失败
DirectXTex处理DDS纹理并保存TGA的问题修复与完整实现
原代码存在的核心问题
- 使用
const Image*修改像素属于未定义行为,ScratchImage的内部数据需通过可写接口访问 - 若加载的DDS为压缩格式(如BC1-BC7),直接遍历修改像素无效,必须先转换为非压缩格式
- 未检查API调用的HRESULT返回值,无法定位保存失败的具体原因
- 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
相关产品推荐
相关产品推荐

