2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-05-25 02:51:43 +00:00

Merge pull request #806 from Laupetin/fix/image-iwi-dumping

fix: invalid formats when dumping images as iwi
This commit is contained in:
Jan
2026-05-18 18:51:10 +02:00
committed by GitHub
26 changed files with 257 additions and 555 deletions
+30
View File
@@ -1,7 +1,37 @@
#include "ImageFormat.h" #include "ImageFormat.h"
#include <type_traits>
namespace
{
const char* IMAGE_FORMAT_NAMES[]{
"R8_G8_B8",
"B8_G8_R8_X8",
"R8_G8_B8_A8",
"B8_G8_R8_A8",
"A8",
"R16_G16_B16_A16_FLOAT",
"R8",
"R8_A8",
"BC1",
"BC2",
"BC3",
"BC4",
"BC5",
};
static_assert(std::extent_v<decltype(IMAGE_FORMAT_NAMES)> == static_cast<unsigned>(image::ImageFormatId::MAX));
} // namespace
namespace image namespace image
{ {
const char* GetImageFormatName(ImageFormatId id)
{
if (id < ImageFormatId::MAX)
return IMAGE_FORMAT_NAMES[static_cast<unsigned>(id)];
return "unknown";
}
ImageFormat::ImageFormat(const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat) ImageFormat::ImageFormat(const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat)
: m_id(id), : m_id(id),
m_d3d_format(d3dFormat), m_d3d_format(d3dFormat),
+6 -4
View File
@@ -8,9 +8,8 @@
namespace image namespace image
{ {
enum class ImageFormatId enum class ImageFormatId : std::uint8_t
{ {
UNKNOWN = -1,
R8_G8_B8, R8_G8_B8,
B8_G8_R8_X8, B8_G8_R8_X8,
R8_G8_B8_A8, R8_G8_B8_A8,
@@ -25,10 +24,13 @@ namespace image
BC4, BC4,
BC5, BC5,
MAX MAX,
UNKNOWN
}; };
enum class ImageFormatType const char* GetImageFormatName(ImageFormatId id);
enum class ImageFormatType : std::uint8_t
{ {
UNKNOWN, UNKNOWN,
UNSIGNED, UNSIGNED,
+6
View File
@@ -37,6 +37,12 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
case ImageFormatId::BC5: case ImageFormatId::BC5:
return IwiFormat::IMG_FORMAT_DXN; return IwiFormat::IMG_FORMAT_DXN;
case ImageFormatId::R8_A8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA;
case ImageFormatId::R8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE;
default: default:
return IwiFormat::IMG_FORMAT_INVALID; return IwiFormat::IMG_FORMAT_INVALID;
} }
+6
View File
@@ -37,6 +37,12 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
case ImageFormatId::BC5: case ImageFormatId::BC5:
return IwiFormat::IMG_FORMAT_DXN; return IwiFormat::IMG_FORMAT_DXN;
case ImageFormatId::R8_A8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA;
case ImageFormatId::R8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE;
default: default:
return IwiFormat::IMG_FORMAT_INVALID; return IwiFormat::IMG_FORMAT_INVALID;
} }
+6
View File
@@ -33,6 +33,12 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
case ImageFormatId::BC5: case ImageFormatId::BC5:
return IwiFormat::IMG_FORMAT_DXN; return IwiFormat::IMG_FORMAT_DXN;
case ImageFormatId::R8_A8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA;
case ImageFormatId::R8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE;
default: default:
return IwiFormat::IMG_FORMAT_INVALID; return IwiFormat::IMG_FORMAT_INVALID;
} }
+6
View File
@@ -33,6 +33,12 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
case ImageFormatId::BC5: case ImageFormatId::BC5:
return IwiFormat::IMG_FORMAT_DXN; return IwiFormat::IMG_FORMAT_DXN;
case ImageFormatId::R8_A8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA;
case ImageFormatId::R8:
return IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE;
default: default:
return IwiFormat::IMG_FORMAT_INVALID; return IwiFormat::IMG_FORMAT_INVALID;
} }
@@ -1,100 +0,0 @@
#include "ImageDumperIW3.h"
#include "Image/DdsWriter.h"
#include "Image/Dx9TextureLoader.h"
#include "Image/ImageCommon.h"
#include "Image/IwiLoader.h"
#include "Image/IwiTypes.h"
#include "Image/IwiWriter6.h"
#include "Image/Texture.h"
#include "ObjWriting.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/Logging/Log.h"
#include <algorithm>
#include <cassert>
#include <format>
using namespace IW3;
using namespace image;
namespace
{
std::unique_ptr<Texture> LoadImageFromLoadDef(const GfxImage& image)
{
Dx9TextureLoader textureLoader;
const auto& loadDef = *image.texture.loadDef;
textureLoader.Width(loadDef.dimensions[0]).Height(loadDef.dimensions[1]).Depth(loadDef.dimensions[2]);
if (loadDef.flags & image::iwi6::IMG_FLAG_VOLMAP)
textureLoader.Type(TextureType::T_3D);
else if (loadDef.flags & image::iwi6::IMG_FLAG_CUBEMAP)
textureLoader.Type(TextureType::T_CUBE);
else
textureLoader.Type(TextureType::T_2D);
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi6::IMG_FLAG_NOMIPMAPS));
return textureLoader.LoadTexture(loadDef.data);
}
std::unique_ptr<Texture> LoadImageFromIwi(const GfxImage& image, ISearchPath& searchPath)
{
const auto imageFileName = image::GetFileNameForAsset(image.name, ".iwi");
const auto filePathImage = searchPath.Open(imageFileName);
if (!filePathImage.IsOpen())
{
con::error("Could not find data for image \"{}\"", image.name);
return nullptr;
}
auto loadResult = image::LoadIwi(*filePathImage.m_stream);
return loadResult ? std::move(loadResult->m_texture) : nullptr;
}
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
{
if (image.texture.loadDef && image.texture.loadDef->resourceSize > 0)
return LoadImageFromLoadDef(image);
return LoadImageFromIwi(image, searchPath);
}
} // namespace
namespace image
{
DumperIW3::DumperIW3()
: AbstractAssetDumper()
{
switch (ObjWriting::Configuration.ImageOutputFormat)
{
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>();
break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi6::IwiWriter>();
break;
default:
assert(false);
m_writer = nullptr;
break;
}
}
void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo<GfxImage>& asset)
{
const auto* image = asset.Asset();
const auto texture = LoadImageData(context.m_obj_search_path, *image);
if (!texture)
return;
const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension()));
if (!assetFile)
return;
auto& stream = *assetFile;
m_writer->DumpImage(stream, texture.get());
}
} // namespace image
@@ -1,22 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW3/IW3.h"
#include "Image/ImageWriter.h"
#include <memory>
namespace image
{
class DumperIW3 final : public AbstractAssetDumper<IW3::AssetImage>
{
public:
DumperIW3();
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW3::AssetImage::Type>& asset) override;
private:
std::unique_ptr<ImageWriter> m_writer;
};
} // namespace image
+1 -1
View File
@@ -1,9 +1,9 @@
#include "ObjWriterIW3.h" #include "ObjWriterIW3.h"
#include "Game/IW3/Image/ImageDumperIW3.h"
#include "Game/IW3/Material/MaterialJsonDumperIW3.h" #include "Game/IW3/Material/MaterialJsonDumperIW3.h"
#include "Game/IW3/Techset/TechsetDumperIW3.h" #include "Game/IW3/Techset/TechsetDumperIW3.h"
#include "Game/IW3/XModel/XModelDumperIW3.h" #include "Game/IW3/XModel/XModelDumperIW3.h"
#include "Image/ImageDumperIW3.h"
#include "LightDef/LightDefDumperIW3.h" #include "LightDef/LightDefDumperIW3.h"
#include "Localize/LocalizeDumperIW3.h" #include "Localize/LocalizeDumperIW3.h"
#include "Maps/MapEntsDumperIW3.h" #include "Maps/MapEntsDumperIW3.h"
@@ -1,96 +0,0 @@
#include "ImageDumperIW4.h"
#include "Image/DdsWriter.h"
#include "Image/Dx9TextureLoader.h"
#include "Image/ImageCommon.h"
#include "Image/IwiLoader.h"
#include "Image/IwiWriter8.h"
#include "ObjWriting.h"
#include "Utils/Logging/Log.h"
#include <algorithm>
#include <cassert>
#include <format>
using namespace IW4;
using namespace image;
namespace
{
std::unique_ptr<Texture> LoadImageFromLoadDef(const GfxImage& image)
{
Dx9TextureLoader textureLoader;
const auto& loadDef = *image.texture.loadDef;
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
if ((loadDef.flags & image::iwi8::IMG_FLAG_MAPTYPE_MASK) == image::iwi8::IMG_FLAG_MAPTYPE_3D)
textureLoader.Type(TextureType::T_3D);
else if ((loadDef.flags & image::iwi8::IMG_FLAG_MAPTYPE_MASK) == image::iwi8::IMG_FLAG_MAPTYPE_CUBE)
textureLoader.Type(TextureType::T_CUBE);
else
textureLoader.Type(TextureType::T_2D);
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi8::IMG_FLAG_NOMIPMAPS));
return textureLoader.LoadTexture(loadDef.data);
}
std::unique_ptr<Texture> LoadImageFromIwi(const GfxImage& image, ISearchPath& searchPath)
{
const auto imageFileName = image::GetFileNameForAsset(image.name, ".iwi");
const auto filePathImage = searchPath.Open(imageFileName);
if (!filePathImage.IsOpen())
{
con::error("Could not find data for image \"{}\"", image.name);
return nullptr;
}
auto loadResult = image::LoadIwi(*filePathImage.m_stream);
return loadResult ? std::move(loadResult->m_texture) : nullptr;
}
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
{
if (image.texture.loadDef && image.texture.loadDef->resourceSize > 0)
return LoadImageFromLoadDef(image);
return LoadImageFromIwi(image, searchPath);
}
} // namespace
namespace image
{
DumperIW4::DumperIW4()
{
switch (ObjWriting::Configuration.ImageOutputFormat)
{
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>();
break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi8::IwiWriter>();
break;
default:
assert(false);
m_writer = nullptr;
break;
}
}
void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetImage::Type>& asset)
{
const auto* image = asset.Asset();
const auto texture = LoadImageData(context.m_obj_search_path, *image);
if (!texture)
return;
const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension()));
if (!assetFile)
return;
auto& stream = *assetFile;
m_writer->DumpImage(stream, texture.get());
}
} // namespace image
@@ -1,22 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW4/IW4.h"
#include "Image/ImageWriter.h"
#include <memory>
namespace image
{
class DumperIW4 final : public AbstractAssetDumper<IW4::AssetImage>
{
public:
DumperIW4();
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW4::AssetImage::Type>& asset) override;
private:
std::unique_ptr<ImageWriter> m_writer;
};
} // namespace image
+1 -1
View File
@@ -1,11 +1,11 @@
#include "ObjWriterIW4.h" #include "ObjWriterIW4.h"
#include "Game/IW4/Image/ImageDumperIW4.h"
#include "Game/IW4/Material/MaterialJsonDumperIW4.h" #include "Game/IW4/Material/MaterialJsonDumperIW4.h"
#include "Game/IW4/Techset/PixelShaderDumperIW4.h" #include "Game/IW4/Techset/PixelShaderDumperIW4.h"
#include "Game/IW4/Techset/TechsetDumperIW4.h" #include "Game/IW4/Techset/TechsetDumperIW4.h"
#include "Game/IW4/Techset/VertexShaderDumperIW4.h" #include "Game/IW4/Techset/VertexShaderDumperIW4.h"
#include "Game/IW4/XModel/XModelDumperIW4.h" #include "Game/IW4/XModel/XModelDumperIW4.h"
#include "Image/ImageDumperIW4.h"
#include "Leaderboard/LeaderboardJsonDumperIW4.h" #include "Leaderboard/LeaderboardJsonDumperIW4.h"
#include "LightDef/LightDefDumperIW4.h" #include "LightDef/LightDefDumperIW4.h"
#include "Localize/LocalizeDumperIW4.h" #include "Localize/LocalizeDumperIW4.h"
@@ -1,97 +0,0 @@
#include "ImageDumperIW5.h"
#include "Image/DdsWriter.h"
#include "Image/Dx9TextureLoader.h"
#include "Image/ImageCommon.h"
#include "Image/IwiLoader.h"
#include "Image/IwiWriter8.h"
#include "ObjWriting.h"
#include "Utils/Logging/Log.h"
#include <algorithm>
#include <cassert>
#include <format>
using namespace IW5;
using namespace image;
namespace
{
std::unique_ptr<Texture> LoadImageFromLoadDef(const GfxImage& image)
{
Dx9TextureLoader textureLoader;
const auto& loadDef = *image.texture.loadDef;
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
if ((loadDef.flags & image::iwi8::IMG_FLAG_MAPTYPE_MASK) == image::iwi8::IMG_FLAG_MAPTYPE_3D)
textureLoader.Type(TextureType::T_3D);
else if ((loadDef.flags & image::iwi8::IMG_FLAG_MAPTYPE_MASK) == image::iwi8::IMG_FLAG_MAPTYPE_CUBE)
textureLoader.Type(TextureType::T_CUBE);
else
textureLoader.Type(TextureType::T_2D);
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi8::IMG_FLAG_NOMIPMAPS));
return textureLoader.LoadTexture(loadDef.data);
}
std::unique_ptr<Texture> LoadImageFromIwi(const GfxImage& image, ISearchPath& searchPath)
{
const auto imageFileName = image::GetFileNameForAsset(image.name, ".iwi");
const auto filePathImage = searchPath.Open(imageFileName);
if (!filePathImage.IsOpen())
{
con::error("Could not find data for image \"{}\"", image.name);
return nullptr;
}
auto loadResult = image::LoadIwi(*filePathImage.m_stream);
return loadResult ? std::move(loadResult->m_texture) : nullptr;
}
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
{
if (image.texture.loadDef && image.texture.loadDef->resourceSize > 0)
return LoadImageFromLoadDef(image);
return LoadImageFromIwi(image, searchPath);
}
} // namespace
namespace image
{
DumperIW5::DumperIW5()
{
switch (ObjWriting::Configuration.ImageOutputFormat)
{
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>();
break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi8::IwiWriter>();
break;
default:
assert(false);
m_writer = nullptr;
break;
}
}
void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetImage::Type>& asset)
{
const auto* image = asset.Asset();
const auto texture = LoadImageData(context.m_obj_search_path, *image);
if (!texture)
return;
const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension()));
if (!assetFile)
return;
auto& stream = *assetFile;
m_writer->DumpImage(stream, texture.get());
}
} // namespace image
@@ -1,22 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
#include "Image/ImageWriter.h"
#include <memory>
namespace image
{
class DumperIW5 final : public AbstractAssetDumper<IW5::AssetImage>
{
public:
DumperIW5();
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW5::AssetImage::Type>& asset) override;
private:
std::unique_ptr<ImageWriter> m_writer;
};
} // namespace image
+1 -1
View File
@@ -1,11 +1,11 @@
#include "ObjWriterIW5.h" #include "ObjWriterIW5.h"
#include "Game/IW5/Image/ImageDumperIW5.h"
#include "Game/IW5/Material/MaterialJsonDumperIW5.h" #include "Game/IW5/Material/MaterialJsonDumperIW5.h"
#include "Game/IW5/Techset/PixelShaderDumperIW5.h" #include "Game/IW5/Techset/PixelShaderDumperIW5.h"
#include "Game/IW5/Techset/TechsetDumperIW5.h" #include "Game/IW5/Techset/TechsetDumperIW5.h"
#include "Game/IW5/Techset/VertexShaderDumperIW5.h" #include "Game/IW5/Techset/VertexShaderDumperIW5.h"
#include "Game/IW5/XModel/XModelDumperIW5.h" #include "Game/IW5/XModel/XModelDumperIW5.h"
#include "Image/ImageDumperIW5.h"
#include "Leaderboard/LeaderboardJsonDumperIW5.h" #include "Leaderboard/LeaderboardJsonDumperIW5.h"
#include "LightDef/LightDefDumperIW5.h" #include "LightDef/LightDefDumperIW5.h"
#include "Localize/LocalizeDumperIW5.h" #include "Localize/LocalizeDumperIW5.h"
@@ -1,96 +0,0 @@
#include "ImageDumperT5.h"
#include "Image/DdsWriter.h"
#include "Image/Dx9TextureLoader.h"
#include "Image/ImageCommon.h"
#include "Image/IwiLoader.h"
#include "Image/IwiWriter13.h"
#include "ObjWriting.h"
#include "Utils/Logging/Log.h"
#include <algorithm>
#include <cassert>
#include <format>
using namespace T5;
using namespace image;
namespace
{
std::unique_ptr<Texture> LoadImageFromLoadDef(const GfxImage& image)
{
Dx9TextureLoader textureLoader;
const auto& loadDef = *image.texture.loadDef;
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
if (loadDef.flags & image::iwi13::IMG_FLAG_VOLMAP)
textureLoader.Type(TextureType::T_3D);
else if (loadDef.flags & image::iwi13::IMG_FLAG_CUBEMAP)
textureLoader.Type(TextureType::T_CUBE);
else
textureLoader.Type(TextureType::T_2D);
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi13::IMG_FLAG_NOMIPMAPS));
return textureLoader.LoadTexture(loadDef.data);
}
std::unique_ptr<Texture> LoadImageFromIwi(const GfxImage& image, ISearchPath& searchPath)
{
const auto imageFileName = image::GetFileNameForAsset(image.name, ".iwi");
const auto filePathImage = searchPath.Open(imageFileName);
if (!filePathImage.IsOpen())
{
con::error("Could not find data for image \"{}\"", image.name);
return nullptr;
}
auto loadResult = image::LoadIwi(*filePathImage.m_stream);
return loadResult ? std::move(loadResult->m_texture) : nullptr;
}
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
{
if (image.texture.loadDef && image.texture.loadDef->resourceSize > 0)
return LoadImageFromLoadDef(image);
return LoadImageFromIwi(image, searchPath);
}
} // namespace
namespace image
{
DumperT5::DumperT5()
{
switch (ObjWriting::Configuration.ImageOutputFormat)
{
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>();
break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi13::IwiWriter>();
break;
default:
assert(false);
m_writer = nullptr;
break;
}
}
void DumperT5::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetImage::Type>& asset)
{
const auto* image = asset.Asset();
const auto texture = LoadImageData(context.m_obj_search_path, *image);
if (!texture)
return;
const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension()));
if (!assetFile)
return;
auto& stream = *assetFile;
m_writer->DumpImage(stream, texture.get());
}
} // namespace image
@@ -1,22 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T5/T5.h"
#include "Image/ImageWriter.h"
#include <memory>
namespace image
{
class DumperT5 final : public AbstractAssetDumper<T5::AssetImage>
{
public:
DumperT5();
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T5::AssetImage::Type>& asset) override;
private:
std::unique_ptr<ImageWriter> m_writer;
};
} // namespace image
+1 -1
View File
@@ -1,9 +1,9 @@
#include "ObjWriterT5.h" #include "ObjWriterT5.h"
#include "Game/T5/Image/ImageDumperT5.h"
#include "Game/T5/Material/MaterialJsonDumperT5.h" #include "Game/T5/Material/MaterialJsonDumperT5.h"
#include "Game/T5/Techset/TechsetDumperT5.h" #include "Game/T5/Techset/TechsetDumperT5.h"
#include "Game/T5/XModel/XModelDumperT5.h" #include "Game/T5/XModel/XModelDumperT5.h"
#include "Image/ImageDumperT5.h"
#include "LightDef/LightDefDumperT5.h" #include "LightDef/LightDefDumperT5.h"
#include "Localize/LocalizeDumperT5.h" #include "Localize/LocalizeDumperT5.h"
#include "PhysPreset/PhysPresetInfoStringDumperT5.h" #include "PhysPreset/PhysPresetInfoStringDumperT5.h"
@@ -1,22 +0,0 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
#include "Image/ImageWriter.h"
#include <memory>
namespace image
{
class DumperT6 final : public AbstractAssetDumper<T6::AssetImage>
{
public:
DumperT6();
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T6::AssetImage::Type>& asset) override;
private:
std::unique_ptr<ImageWriter> m_writer;
};
} // namespace image
+1 -1
View File
@@ -1,10 +1,10 @@
#include "ObjWriterT6.h" #include "ObjWriterT6.h"
#include "FontIcon/FontIconDumperT6.h" #include "FontIcon/FontIconDumperT6.h"
#include "Game/T6/Image/ImageDumperT6.h"
#include "Game/T6/Material/MaterialJsonDumperT6.h" #include "Game/T6/Material/MaterialJsonDumperT6.h"
#include "Game/T6/Techset/TechsetDumperT6.h" #include "Game/T6/Techset/TechsetDumperT6.h"
#include "Game/T6/XModel/XModelDumperT6.h" #include "Game/T6/XModel/XModelDumperT6.h"
#include "Image/ImageDumperT6.h"
#include "Leaderboard/LeaderboardJsonDumperT6.h" #include "Leaderboard/LeaderboardJsonDumperT6.h"
#include "LightDef/LightDefDumperT6.h" #include "LightDef/LightDefDumperT6.h"
#include "Localize/LocalizeDumperT6.h" #include "Localize/LocalizeDumperT6.h"
@@ -1,11 +1,64 @@
#include "ImageDumperT6.h" #options GAME (IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Image/ImageDumper" + GAME + ".cpp"
#set DUMPER_HEADER "\"ImageDumper" + GAME + ".h\""
#if GAME == "IW3"
#define FEATURE_IW3
#define DX9
#define IWI6
#elif GAME == "IW4"
#define FEATURE_IW4
#define DX9
#define IWI8
#elif GAME == "IW5"
#define FEATURE_IW5
#define DX9
#define IWI8
#elif GAME == "T5"
#define FEATURE_T5
#define DX9
#define IWI13
#elif GAME == "T6"
#define FEATURE_T6
#define DX11
#define IWI27
#endif
// This file was templated.
// See ImageDumper.cpp.template.
// Do not modify, changes will be lost.
#include DUMPER_HEADER
#ifdef DX9
#include "Image/Dx9TextureLoader.h"
#else
#include "Image/Dx12TextureLoader.h"
#endif
#ifdef FEATURE_T6
#include "ObjContainer/IPak/IPak.h"
#endif
#if defined(IWI6)
#include "Image/IwiWriter6.h"
#define IWI_NS iwi6
#elif defined(IWI8)
#include "Image/IwiWriter8.h"
#define IWI_NS iwi8
#elif defined(IWI13)
#include "Image/IwiWriter13.h"
#define IWI_NS iwi13
#elif defined(IWI27)
#include "Image/IwiWriter27.h"
#define IWI_NS iwi27
#endif
#include "Image/DdsWriter.h" #include "Image/DdsWriter.h"
#include "Image/Dx12TextureLoader.h"
#include "Image/ImageCommon.h" #include "Image/ImageCommon.h"
#include "Image/IwiLoader.h" #include "Image/IwiLoader.h"
#include "Image/IwiWriter27.h"
#include "ObjContainer/IPak/IPak.h"
#include "ObjWriting.h" #include "ObjWriting.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
@@ -13,32 +66,55 @@
#include <cassert> #include <cassert>
#include <format> #include <format>
using namespace T6; using namespace GAME;
using namespace image; using namespace image;
namespace namespace
{ {
std::unique_ptr<Texture> LoadImageFromLoadDef(const GfxImage& image) std::unique_ptr<Texture> LoadImageFromLoadDef(const GfxImage& image)
{ {
#ifdef DX9
Dx9TextureLoader textureLoader;
#else
Dx12TextureLoader textureLoader; Dx12TextureLoader textureLoader;
#endif
const auto& loadDef = *image.texture.loadDef; const auto& loadDef = *image.texture.loadDef;
#ifdef FEATURE_IW3
textureLoader.Width(loadDef.dimensions[0]).Height(loadDef.dimensions[1]).Depth(loadDef.dimensions[2]);
#else
textureLoader.Width(image.width).Height(image.height).Depth(image.depth); textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
#endif
if (loadDef.flags & image::iwi27::IMG_FLAG_VOLMAP) #if defined(IWI8)
if ((loadDef.flags & image::IWI_NS::IMG_FLAG_MAPTYPE_MASK) == image::IWI_NS::IMG_FLAG_MAPTYPE_3D)
textureLoader.Type(TextureType::T_3D); textureLoader.Type(TextureType::T_3D);
else if (loadDef.flags & image::iwi27::IMG_FLAG_CUBEMAP) else if ((loadDef.flags & image::IWI_NS::IMG_FLAG_MAPTYPE_MASK) == image::IWI_NS::IMG_FLAG_MAPTYPE_CUBE)
textureLoader.Type(TextureType::T_CUBE); textureLoader.Type(TextureType::T_CUBE);
else else
textureLoader.Type(TextureType::T_2D); textureLoader.Type(TextureType::T_2D);
#else
if (loadDef.flags & image::IWI_NS::IMG_FLAG_VOLMAP)
textureLoader.Type(TextureType::T_3D);
else if (loadDef.flags & image::IWI_NS::IMG_FLAG_CUBEMAP)
textureLoader.Type(TextureType::T_CUBE);
else
textureLoader.Type(TextureType::T_2D);
#endif
#ifdef DX9
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
#else
textureLoader.Format(static_cast<oat::DXGI_FORMAT>(loadDef.format)); textureLoader.Format(static_cast<oat::DXGI_FORMAT>(loadDef.format));
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi27::IMG_FLAG_NOMIPMAPS)); #endif
textureLoader.HasMipMaps(!(loadDef.flags & image::IWI_NS::IMG_FLAG_NOMIPMAPS));
return textureLoader.LoadTexture(loadDef.data); return textureLoader.LoadTexture(loadDef.data);
} }
std::unique_ptr<Texture> LoadImageFromIwi(const GfxImage& image, ISearchPath& searchPath) std::unique_ptr<Texture> LoadImageFromIwi(const GfxImage& image, ISearchPath& searchPath)
{ {
#ifdef FEATURE_T6
if (image.streamedPartCount > 0) if (image.streamedPartCount > 0)
{ {
for (auto* ipak : IIPak::Repository) for (auto* ipak : IIPak::Repository)
@@ -55,6 +131,7 @@ namespace
} }
} }
} }
#endif
const auto imageFileName = image::GetFileNameForAsset(image.name, ".iwi"); const auto imageFileName = image::GetFileNameForAsset(image.name, ".iwi");
const auto filePathImage = searchPath.Open(imageFileName); const auto filePathImage = searchPath.Open(imageFileName);
@@ -77,17 +154,19 @@ namespace
} }
} // namespace } // namespace
#set CLASS_NAME "Dumper" + GAME
namespace image namespace image
{ {
DumperT6::DumperT6() CLASS_NAME::CLASS_NAME()
{ {
switch (ObjWriting::Configuration.ImageOutputFormat) switch (ObjWriting::Configuration.ImageOutputFormat)
{ {
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS: case ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>(); m_writer = std::make_unique<DdsWriter>();
break; break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI: case ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi27::IwiWriter>(); m_writer = std::make_unique<IWI_NS::IwiWriter>();
break; break;
default: default:
assert(false); assert(false);
@@ -96,13 +175,22 @@ namespace image
} }
} }
void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetImage::Type>& asset) void CLASS_NAME::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetImage::Type>& asset)
{ {
const auto* image = asset.Asset(); const auto* image = asset.Asset();
const auto texture = LoadImageData(context.m_obj_search_path, *image); const auto texture = LoadImageData(context.m_obj_search_path, *image);
if (!texture) if (!texture)
return; return;
if (!m_writer->SupportsImageFormat(texture->GetFormat()))
{
con::warn("Not dumping image {} as {} does not support the image format {}",
image->name,
GetImageOutputFormatName(ObjWriting::Configuration.ImageOutputFormat),
GetImageFormatName(texture->GetFormat()->GetId()));
return;
}
const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension())); const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension()));
if (!assetFile) if (!assetFile)
@@ -0,0 +1,34 @@
#options GAME(IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Image/ImageDumper" + GAME + ".h"
#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\""
// This file was templated.
// See ImageDumper.h.template.
// Do not modify, changes will be lost.
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include GAME_HEADER
#include "Image/ImageWriter.h"
#include <memory>
#set CLASS_NAME "Dumper" + GAME
namespace image
{
class CLASS_NAME final : public AbstractAssetDumper<GAME::AssetImage>
{
public:
CLASS_NAME();
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<GAME::AssetImage::Type>& asset) override;
private:
std::unique_ptr<ImageWriter> m_writer;
};
} // namespace image
+19
View File
@@ -1,7 +1,26 @@
#include "ObjWriting.h" #include "ObjWriting.h"
#include <type_traits>
namespace
{
const char* IMAGE_OUTPUT_FORMAT_NAME[]{
"DDS",
"IWI",
};
static_assert(std::extent_v<decltype(IMAGE_OUTPUT_FORMAT_NAME)> == static_cast<unsigned>(ImageOutputFormat_e::COUNT));
} // namespace
ObjWriting::Configuration_t ObjWriting::Configuration; ObjWriting::Configuration_t ObjWriting::Configuration;
const char* GetImageOutputFormatName(ImageOutputFormat_e imageOutputFormat)
{
if (imageOutputFormat < ImageOutputFormat_e::COUNT)
return IMAGE_OUTPUT_FORMAT_NAME[static_cast<unsigned>(imageOutputFormat)];
return "unknown";
}
bool ObjWriting::ShouldHandleAssetType(const asset_type_t assetType) bool ObjWriting::ShouldHandleAssetType(const asset_type_t assetType)
{ {
if (assetType < 0) if (assetType < 0)
+11 -7
View File
@@ -5,18 +5,16 @@
#include <vector> #include <vector>
class ObjWriting
{
public:
static class Configuration_t
{
public:
enum class ImageOutputFormat_e enum class ImageOutputFormat_e
{ {
DDS, DDS,
IWI IWI,
COUNT
}; };
const char* GetImageOutputFormatName(ImageOutputFormat_e imageOutputFormat);
enum class ModelOutputFormat_e enum class ModelOutputFormat_e
{ {
XMODEL_EXPORT, XMODEL_EXPORT,
@@ -26,6 +24,12 @@ public:
GLB GLB
}; };
class ObjWriting
{
public:
static class Configuration_t
{
public:
std::vector<bool> AssetTypesToHandleBitfield; std::vector<bool> AssetTypesToHandleBitfield;
ImageOutputFormat_e ImageOutputFormat = ImageOutputFormat_e::DDS; ImageOutputFormat_e ImageOutputFormat = ImageOutputFormat_e::DDS;
+12 -12
View File
@@ -553,8 +553,8 @@ namespace
bool CanOmitDefaultArmature() bool CanOmitDefaultArmature()
{ {
return ObjWriting::Configuration.ModelOutputFormat != ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_EXPORT return ObjWriting::Configuration.ModelOutputFormat != ModelOutputFormat_e::XMODEL_EXPORT
&& ObjWriting::Configuration.ModelOutputFormat != ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_BIN; && ObjWriting::Configuration.ModelOutputFormat != ModelOutputFormat_e::XMODEL_BIN;
} }
void PopulateXModelWriter(XModelCommon& out, const AssetDumpingContext& context, const unsigned lod, const XModel& model) void PopulateXModelWriter(XModelCommon& out, const AssetDumpingContext& context, const unsigned lod, const XModel& model)
@@ -666,25 +666,25 @@ namespace
switch (ObjWriting::Configuration.ModelOutputFormat) switch (ObjWriting::Configuration.ModelOutputFormat)
{ {
case ObjWriting::Configuration_t::ModelOutputFormat_e::OBJ: case ModelOutputFormat_e::OBJ:
DumpObjLod(common, context, asset, currentLod); DumpObjLod(common, context, asset, currentLod);
if (currentLod == 0u) if (currentLod == 0u)
DumpObjMtl(common, context, asset); DumpObjMtl(common, context, asset);
break; break;
case ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_EXPORT: case ModelOutputFormat_e::XMODEL_EXPORT:
DumpXModelExportLod(common, context, asset, currentLod); DumpXModelExportLod(common, context, asset, currentLod);
break; break;
case ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_BIN: case ModelOutputFormat_e::XMODEL_BIN:
DumpXModelBinLod(common, context, asset, currentLod); DumpXModelBinLod(common, context, asset, currentLod);
break; break;
case ObjWriting::Configuration_t::ModelOutputFormat_e::GLTF: case ModelOutputFormat_e::GLTF:
DumpGltfLod<gltf::TextOutput>(common, context, asset, currentLod, ".gltf"); DumpGltfLod<gltf::TextOutput>(common, context, asset, currentLod, ".gltf");
break; break;
case ObjWriting::Configuration_t::ModelOutputFormat_e::GLB: case ModelOutputFormat_e::GLB:
DumpGltfLod<gltf::BinOutput>(common, context, asset, currentLod, ".glb"); DumpGltfLod<gltf::BinOutput>(common, context, asset, currentLod, ".glb");
break; break;
@@ -699,15 +699,15 @@ namespace
{ {
switch (ObjWriting::Configuration.ModelOutputFormat) switch (ObjWriting::Configuration.ModelOutputFormat)
{ {
case ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_EXPORT: case ModelOutputFormat_e::XMODEL_EXPORT:
return ".xmodel_export"; return ".xmodel_export";
case ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_BIN: case ModelOutputFormat_e::XMODEL_BIN:
return ".xmodel_bin"; return ".xmodel_bin";
case ObjWriting::Configuration_t::ModelOutputFormat_e::OBJ: case ModelOutputFormat_e::OBJ:
return ".obj"; return ".obj";
case ObjWriting::Configuration_t::ModelOutputFormat_e::GLTF: case ModelOutputFormat_e::GLTF:
return ".gltf"; return ".gltf";
case ObjWriting::Configuration_t::ModelOutputFormat_e::GLB: case ModelOutputFormat_e::GLB:
return ".glb"; return ".glb";
default: default:
assert(false); assert(false);
+7 -7
View File
@@ -184,13 +184,13 @@ bool UnlinkerArgs::SetImageDumpingMode() const
if (specifiedValue == "dds") if (specifiedValue == "dds")
{ {
ObjWriting::Configuration.ImageOutputFormat = ObjWriting::Configuration_t::ImageOutputFormat_e::DDS; ObjWriting::Configuration.ImageOutputFormat = ImageOutputFormat_e::DDS;
return true; return true;
} }
if (specifiedValue == "iwi") if (specifiedValue == "iwi")
{ {
ObjWriting::Configuration.ImageOutputFormat = ObjWriting::Configuration_t::ImageOutputFormat_e::IWI; ObjWriting::Configuration.ImageOutputFormat = ImageOutputFormat_e::IWI;
return true; return true;
} }
@@ -206,31 +206,31 @@ bool UnlinkerArgs::SetModelDumpingMode() const
if (specifiedValue == "xmodel_export") if (specifiedValue == "xmodel_export")
{ {
ObjWriting::Configuration.ModelOutputFormat = ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_EXPORT; ObjWriting::Configuration.ModelOutputFormat = ModelOutputFormat_e::XMODEL_EXPORT;
return true; return true;
} }
if (specifiedValue == "xmodel_bin") if (specifiedValue == "xmodel_bin")
{ {
ObjWriting::Configuration.ModelOutputFormat = ObjWriting::Configuration_t::ModelOutputFormat_e::XMODEL_BIN; ObjWriting::Configuration.ModelOutputFormat = ModelOutputFormat_e::XMODEL_BIN;
return true; return true;
} }
if (specifiedValue == "obj") if (specifiedValue == "obj")
{ {
ObjWriting::Configuration.ModelOutputFormat = ObjWriting::Configuration_t::ModelOutputFormat_e::OBJ; ObjWriting::Configuration.ModelOutputFormat = ModelOutputFormat_e::OBJ;
return true; return true;
} }
if (specifiedValue == "gltf") if (specifiedValue == "gltf")
{ {
ObjWriting::Configuration.ModelOutputFormat = ObjWriting::Configuration_t::ModelOutputFormat_e::GLTF; ObjWriting::Configuration.ModelOutputFormat = ModelOutputFormat_e::GLTF;
return true; return true;
} }
if (specifiedValue == "glb") if (specifiedValue == "glb")
{ {
ObjWriting::Configuration.ModelOutputFormat = ObjWriting::Configuration_t::ModelOutputFormat_e::GLB; ObjWriting::Configuration.ModelOutputFormat = ModelOutputFormat_e::GLB;
return true; return true;
} }