Skip to content

Commit

Permalink
convert non-RGBA images to RGBA
Browse files Browse the repository at this point in the history
  • Loading branch information
DubbleClick committed Dec 3, 2023
1 parent 787623f commit dfeccda
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 15 deletions.
38 changes: 30 additions & 8 deletions header/TextureClient.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <d3dx9tex.h>

#include "FileLoader.h"
#include "uMod_IDirect3DTexture9.h"
#include <DDSTextureLoader/DDSTextureLoader9.h>
Expand Down Expand Up @@ -177,14 +179,34 @@ int TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uModTexturePtr
{
Message("LoadTexture( %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->crc_hash, this);
if (const auto ret = DirectX::CreateDDSTextureFromMemoryEx(
D3D9Device,
file_in_memory->data.data(),
file_in_memory->data.size(),
0, D3DPOOL_MANAGED, false,
reinterpret_cast<LPDIRECT3DTEXTURE9*>(ppTexture)); ret != D3D_OK) {
*ppTexture = nullptr;
Warning("LoadDDSTexture (%p, %#lX): FAILED ret: 0x%x\n", file_in_memory->data.data(), file_in_memory->crc_hash, ret);
return RETURN_TEXTURE_NOT_LOADED;
D3D9Device,
file_in_memory->data.data(),
file_in_memory->data.size(),
0, D3DPOOL_MANAGED, false,
reinterpret_cast<LPDIRECT3DTEXTURE9*>(ppTexture)); ret != D3D_OK) {
Warning("LoadDDSTexture (%p, %#lX): FAILED ret: 0x%x\n", file_in_memory->data.data(), file_in_memory->crc_hash, ret);
Warning("Trying D3DX...\n", file_in_memory->data.data(), file_in_memory->crc_hash, ret);
if (FAILED(D3DXCreateTextureFromFileInMemoryEx(
D3D9Device,
file_in_memory->data.data(),
file_in_memory->data.size(),
0,
0,
0,
0,
D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_NONE,
D3DX_DEFAULT,
0,
nullptr,
nullptr,
reinterpret_cast<LPDIRECT3DTEXTURE9*>(ppTexture)))
) {
*ppTexture = nullptr;
Warning("!!!!!!!!!!LoadDDSTexture (%p, %#lX): FAILED with D3DX!!!!!!!!!!!!!!\n", file_in_memory->data.data(), file_in_memory->crc_hash);
return RETURN_TEXTURE_NOT_LOADED;
}
}
if constexpr (std::same_as<decltype(ppTexture), uMod_IDirect3DTexture9**>) {
SetLastCreatedTexture(nullptr);
Expand Down
5 changes: 2 additions & 3 deletions source/FileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,14 @@ void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TexEntr
//TODO: #6 - Implement regex search
auto name = entry.getName();


const static std::regex re(R"(0x[0-9a-f]{8})", std::regex::optimize | std::regex::icase);
std::smatch match;
if (!std::regex_match(name, match, re)) {
if (!std::regex_search(name, match, re)) {
continue;
}

uint32_t crc_hash;
try {
try {
crc_hash = std::stoul(match.str(), nullptr, 16);
}
catch (const std::invalid_argument& e) {
Expand Down
47 changes: 43 additions & 4 deletions source/TextureClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ unsigned long TextureClient::AddFile(TexEntry& entry)
}
// Other files need to be converted to DDS
DirectX::ScratchImage image;
DirectX::ScratchImage rgba_image;
DirectX::ScratchImage dds_image;
DirectX::TexMetadata metadata{};
HRESULT hr = 0;
if (entry.ext == ".tga") {
Expand All @@ -123,23 +125,60 @@ unsigned long TextureClient::AddFile(TexEntry& entry)
}
else {
hr = DirectX::LoadFromWICMemory(entry.data.data(), entry.data.size(), DirectX::WIC_FLAGS_NONE, &metadata, image);
if (metadata.format == DXGI_FORMAT_B8G8R8X8_UNORM) {
metadata.format = DXGI_FORMAT_B8G8R8A8_UNORM;
// todo: this is undefined behaviour, but we must force them to be interpreted as BGRA instead of BGRX
const auto images = image.GetImages();
for (int i = 0; i < image.GetImageCount(); ++i) {
const_cast<DXGI_FORMAT&>(images[i].format) = DXGI_FORMAT_B8G8R8A8_UNORM;
}
const_cast<DXGI_FORMAT&>(image.GetMetadata().format) = DXGI_FORMAT_B8G8R8A8_UNORM;
}
}
if (FAILED(hr)) {
Warning("LoadImageFromMemory (%#lX%s): FAILED\n", entry.crc_hash, entry.ext.c_str());
return 0;
}
if (metadata.format != DXGI_FORMAT_R8G8B8A8_UNORM) {
hr = DirectX::Convert(
image.GetImages(),
image.GetImageCount(),
metadata,
DXGI_FORMAT_B8G8R8A8_UNORM,
DirectX::TEX_FILTER_DEFAULT,
DirectX::TEX_THRESHOLD_DEFAULT,
rgba_image);
if (FAILED(hr)) {
Warning("ConvertToARGB (%#lX%s): FAILED\n", entry.crc_hash, entry.ext.c_str());
rgba_image = std::move(image);
}
}
else {
rgba_image = std::move(image);
}
hr = DirectX::GenerateMipMaps(
rgba_image.GetImages(),
rgba_image.GetImageCount(),
rgba_image.GetMetadata(),
DirectX::TEX_FILTER_DEFAULT,
0,
dds_image);
if (FAILED(hr)) {
Warning("GenerateMipMaps (%#lX%s): FAILED\n", entry.crc_hash, entry.ext.c_str());
dds_image = std::move(image);
}
DirectX::Blob dds_blob;
hr = DirectX::SaveToDDSMemory(
image.GetImages(),
image.GetImageCount(),
image.GetMetadata(),
dds_image.GetImages(),
dds_image.GetImageCount(),
dds_image.GetMetadata(),
DirectX::DDS_FLAGS_NONE,
dds_blob);
if (FAILED(hr)) {
Warning("SaveDDSImageToMemory (%#lX%s): FAILED\n", entry.crc_hash, entry.ext.c_str());
return 0;
}
#ifdef SAVE_TEXTURES
#if 1
const auto file_name = std::format("0x{:x}.dds", entry.crc_hash);
const auto file_out = dll_path / "textures" / file_name;
std::filesystem::create_directory(file_out.parent_path());
Expand Down

0 comments on commit dfeccda

Please sign in to comment.