mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-07-03 22:30:07 +00:00
fix: t6 modman textures (#849)
* feat: dynamically decompress bc5 textures for modman * chore: restructure image format class * chore: keep dds file conversions * chore: convert all kinds of webgl unsupported formats * chore: add decompressors for remaining formats * chore: always set full alpha if available on bc4 and bc5 decompression
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
|
||||
#include "Context/ModManContext.h"
|
||||
#include "Game/CommonAsset.h"
|
||||
#include "Image/Compression/ImageDecompressor.h"
|
||||
#include "Image/DdsWriter.h"
|
||||
#include "Image/ImageToCommonConverter.h"
|
||||
#include "Image/TextureConverter.h"
|
||||
#include "Pool/XAssetInfo.h"
|
||||
#include "SearchPath/SearchPaths.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
#include "Utils/StringUtils.h"
|
||||
|
||||
@@ -44,6 +45,26 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<ImageFormatId> NeedsConversionToWebGlSupportedFormat(const ImageFormatId imageFormatId)
|
||||
{
|
||||
static std::unordered_map<ImageFormatId, ImageFormatId> unsupportedFormatMap{
|
||||
{ImageFormatId::BC4, ImageFormatId::B8_G8_R8 },
|
||||
{ImageFormatId::BC5, ImageFormatId::B8_G8_R8 },
|
||||
{ImageFormatId::B8_G8_R8_X8, ImageFormatId::B8_G8_R8 },
|
||||
{ImageFormatId::R8_G8_B8, ImageFormatId::B8_G8_R8 },
|
||||
{ImageFormatId::R8_G8_B8_A8, ImageFormatId::B8_G8_R8_A8},
|
||||
{ImageFormatId::A8, ImageFormatId::B8_G8_R8 },
|
||||
{ImageFormatId::R8, ImageFormatId::B8_G8_R8 },
|
||||
{ImageFormatId::R8_A8, ImageFormatId::B8_G8_R8 },
|
||||
};
|
||||
|
||||
const auto entry = unsupportedFormatMap.find(imageFormatId);
|
||||
if (entry != unsupportedFormatMap.end())
|
||||
return entry->second;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void ImageDds(const webwindowed::dynamic_asset_request& request, webwindowed::dynamic_asset_response& response)
|
||||
{
|
||||
const auto imageName = request.get_query("name");
|
||||
@@ -68,8 +89,8 @@ namespace
|
||||
assert(zone);
|
||||
|
||||
const auto gameName = GameId_Names[std::to_underlying(zone->m_game_id)];
|
||||
const auto converter = ToCommonConverter::GetForGame(zone->m_game_id);
|
||||
if (!converter)
|
||||
const auto toCommonConverter = ToCommonConverter::GetForGame(zone->m_game_id);
|
||||
if (!toCommonConverter)
|
||||
{
|
||||
con::error("No image converter for game {}", gameName);
|
||||
response.send_response(500);
|
||||
@@ -79,7 +100,7 @@ namespace
|
||||
std::unique_ptr<Texture> texture;
|
||||
{
|
||||
const auto searchPaths = ModManContext::Get().m_fast_file.GetSearchPaths();
|
||||
texture = converter->Convert(*image, searchPaths.Data());
|
||||
texture = toCommonConverter->Convert(*image, searchPaths.Data());
|
||||
if (!texture)
|
||||
{
|
||||
con::warn("Failed to convert image {} of zone {}", *imageName, *zoneName);
|
||||
@@ -88,6 +109,31 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
const auto* originalTextureFormat = texture->GetFormat();
|
||||
const auto originalTextureFormatId = originalTextureFormat->GetId();
|
||||
const auto targetFormatId = NeedsConversionToWebGlSupportedFormat(originalTextureFormatId);
|
||||
if (targetFormatId)
|
||||
{
|
||||
const auto* targetFormat = ImageFormat::GetImageFormatById(*targetFormatId);
|
||||
if (originalTextureFormat->GetType() == ImageFormatType::BLOCK_COMPRESSED)
|
||||
{
|
||||
auto* textureDecompressor = ImageDecompressor::GetDecompressorForFormat(originalTextureFormatId);
|
||||
assert(textureDecompressor);
|
||||
|
||||
if (textureDecompressor)
|
||||
texture = textureDecompressor->Decompress(*texture, targetFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureConverter converter(texture.get(), targetFormat);
|
||||
auto newTexture = converter.Convert();
|
||||
assert(newTexture);
|
||||
|
||||
if (newTexture)
|
||||
texture = std::move(newTexture);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
DdsWriter output;
|
||||
output.DumpImage(ss, texture.get());
|
||||
|
||||
Reference in New Issue
Block a user