diff --git a/src/Common/Image/D3DFormat.h b/src/Common/Image/D3DFormat.h new file mode 100644 index 00000000..0aba3ce7 --- /dev/null +++ b/src/Common/Image/D3DFormat.h @@ -0,0 +1,110 @@ +#pragma once + +#include "Utils/FileUtils.h" + +enum D3DFORMAT +{ + D3DFMT_UNKNOWN = 0, + + D3DFMT_R8G8B8 = 20, + D3DFMT_A8R8G8B8 = 21, + D3DFMT_X8R8G8B8 = 22, + D3DFMT_R5G6B5 = 23, + D3DFMT_X1R5G5B5 = 24, + D3DFMT_A1R5G5B5 = 25, + D3DFMT_A4R4G4B4 = 26, + D3DFMT_R3G3B2 = 27, + D3DFMT_A8 = 28, + D3DFMT_A8R3G3B2 = 29, + D3DFMT_X4R4G4B4 = 30, + D3DFMT_A2B10G10R10 = 31, + D3DFMT_A8B8G8R8 = 32, + D3DFMT_X8B8G8R8 = 33, + D3DFMT_G16R16 = 34, + D3DFMT_A2R10G10B10 = 35, + D3DFMT_A16B16G16R16 = 36, + + D3DFMT_A8P8 = 40, + D3DFMT_P8 = 41, + + D3DFMT_L8 = 50, + D3DFMT_A8L8 = 51, + D3DFMT_A4L4 = 52, + + D3DFMT_V8U8 = 60, + D3DFMT_L6V5U5 = 61, + D3DFMT_X8L8V8U8 = 62, + D3DFMT_Q8W8V8U8 = 63, + D3DFMT_V16U16 = 64, + D3DFMT_A2W10V10U10 = 67, + + D3DFMT_UYVY = FileUtils::MakeMagic32('U', 'Y', 'V', 'Y'), + D3DFMT_R8G8_B8G8 = FileUtils::MakeMagic32('R', 'G', 'B', 'G'), + D3DFMT_YUY2 = FileUtils::MakeMagic32('Y', 'U', 'Y', '2'), + D3DFMT_G8R8_G8B8 = FileUtils::MakeMagic32('G', 'R', 'G', 'B'), + D3DFMT_DXT1 = FileUtils::MakeMagic32('D', 'X', 'T', '1'), + D3DFMT_DXT2 = FileUtils::MakeMagic32('D', 'X', 'T', '2'), + D3DFMT_DXT3 = FileUtils::MakeMagic32('D', 'X', 'T', '3'), + D3DFMT_DXT4 = FileUtils::MakeMagic32('D', 'X', 'T', '4'), + D3DFMT_DXT5 = FileUtils::MakeMagic32('D', 'X', 'T', '5'), + + D3DFMT_D16_LOCKABLE = 70, + D3DFMT_D32 = 71, + D3DFMT_D15S1 = 73, + D3DFMT_D24S8 = 75, + D3DFMT_D24X8 = 77, + D3DFMT_D24X4S4 = 79, + D3DFMT_D16 = 80, + + D3DFMT_D32F_LOCKABLE = 82, + D3DFMT_D24FS8 = 83, + + /* D3D9Ex only -- */ + + /* Z-Stencil formats valid for CPU access */ + D3DFMT_D32_LOCKABLE = 84, + D3DFMT_S8_LOCKABLE = 85, + + /* -- D3D9Ex only */ + + D3DFMT_L16 = 81, + + D3DFMT_VERTEXDATA = 100, + D3DFMT_INDEX16 = 101, + D3DFMT_INDEX32 = 102, + + D3DFMT_Q16W16V16U16 = 110, + + D3DFMT_MULTI2_ARGB8 = FileUtils::MakeMagic32('M', 'E', 'T', '1'), + + // Floating point surface formats + + // s10e5 formats (16-bits per channel) + D3DFMT_R16F = 111, + D3DFMT_G16R16F = 112, + D3DFMT_A16B16G16R16F = 113, + + // IEEE s23e8 formats (32-bits per channel) + D3DFMT_R32F = 114, + D3DFMT_G32R32F = 115, + D3DFMT_A32B32G32R32F = 116, + + D3DFMT_CxV8U8 = 117, + + /* D3D9Ex only -- */ + + // Monochrome 1 bit per pixel format + D3DFMT_A1 = 118, + + // 2.8 biased fixed point + D3DFMT_A2B10G10R10_XR_BIAS = 119, + + + // Binary format indicating that the data has no inherent type + D3DFMT_BINARYBUFFER = 199, + + /* -- D3D9Ex only */ + + + D3DFMT_FORCE_DWORD = 0x7fffffff +}; \ No newline at end of file diff --git a/src/Common/Image/DxgiFormat.h b/src/Common/Image/DxgiFormat.h index 1f28051f..4f410b5d 100644 --- a/src/Common/Image/DxgiFormat.h +++ b/src/Common/Image/DxgiFormat.h @@ -1,3 +1,5 @@ +#pragma once + /* * Copyright 2016 Józef Kucia for CodeWeavers * @@ -18,7 +20,7 @@ const unsigned int DXGI_FORMAT_DEFINED = 1; -typedef enum DXGI_FORMAT +enum DXGI_FORMAT { DXGI_FORMAT_UNKNOWN = 0x00, DXGI_FORMAT_R32G32B32A32_TYPELESS = 0x01, @@ -142,4 +144,4 @@ typedef enum DXGI_FORMAT DXGI_FORMAT_V408 = 0x84, DXGI_FORMAT_FORCE_UINT = 0xffffffff, -} DXGI_FORMAT; \ No newline at end of file +}; \ No newline at end of file diff --git a/src/Common/Image/ImageFormat.cpp b/src/Common/Image/ImageFormat.cpp index b0f4dd28..f13918a8 100644 --- a/src/Common/Image/ImageFormat.cpp +++ b/src/Common/Image/ImageFormat.cpp @@ -1,9 +1,10 @@ #include "ImageFormat.h" -ImageFormat::ImageFormat(const ImageFormatId id, const DXGI_FORMAT dxgiFormat) +ImageFormat::ImageFormat(const ImageFormatId id, const D3DFORMAT d3dFormat, const DXGI_FORMAT dxgiFormat) + : m_id(id), + m_d3d_format(d3dFormat), + m_dxgi_format(dxgiFormat) { - m_id = id; - m_dxgi_format = dxgiFormat; } ImageFormatId ImageFormat::GetId() const @@ -11,16 +12,21 @@ ImageFormatId ImageFormat::GetId() const return m_id; } +D3DFORMAT ImageFormat::GetD3DFormat() const +{ + return m_d3d_format; +} + DXGI_FORMAT ImageFormat::GetDxgiFormat() const { return m_dxgi_format; } -ImageFormatUnsigned::ImageFormatUnsigned(const ImageFormatId id, const DXGI_FORMAT dxgiFormat, +ImageFormatUnsigned::ImageFormatUnsigned(const ImageFormatId id, const D3DFORMAT d3dFormat, const DXGI_FORMAT dxgiFormat, const unsigned bitsPerPixel, const unsigned rOffset, const unsigned rSize, const unsigned gOffset, const unsigned gSize, const unsigned bOffset, const unsigned bSize, const unsigned aOffset, const unsigned aSize) - : ImageFormat(id, dxgiFormat), + : ImageFormat(id, d3dFormat, dxgiFormat), m_bits_per_pixel(bitsPerPixel), m_r_offset(rOffset), m_r_size(rSize), @@ -64,9 +70,9 @@ size_t ImageFormatUnsigned::GetSizeOfMipLevel(const unsigned mipLevel, const uns return mipWidth * mipHeight * mipDepth * m_bits_per_pixel / 8; } -ImageFormatBlockCompressed::ImageFormatBlockCompressed(const ImageFormatId id, const DXGI_FORMAT dxgiFormat, +ImageFormatBlockCompressed::ImageFormatBlockCompressed(const ImageFormatId id, const D3DFORMAT d3dFormat, const DXGI_FORMAT dxgiFormat, const unsigned blockSize, const unsigned bitsPerBlock) - : ImageFormat(id, dxgiFormat), + : ImageFormat(id, d3dFormat, dxgiFormat), m_block_size(blockSize), m_bits_per_block(bitsPerBlock) { @@ -130,28 +136,19 @@ bool ImageFormatUnsigned::HasA() const return m_a_size > 0; } -const ImageFormatUnsigned ImageFormat::FORMAT_R8_G8_B8(ImageFormatId::R8_G8_B8, DXGI_FORMAT_UNKNOWN, - 24, 0, 8, 8, 8, 16, 8, 0, 0); -const ImageFormatUnsigned ImageFormat::FORMAT_B8_G8_R8_X8(ImageFormatId::B8_G8_R8_X8, DXGI_FORMAT_B8G8R8X8_UNORM, - 32, 16, 8, 8, 8, 0, 8, 0, 0); -const ImageFormatUnsigned ImageFormat::FORMAT_R8_G8_B8_A8(ImageFormatId::R8_G8_B8_A8, DXGI_FORMAT_R8G8B8A8_UNORM, - 32, 0, 8, 8, 8, 16, 8, 24, 8); -const ImageFormatUnsigned ImageFormat::FORMAT_B8_G8_R8_A8(ImageFormatId::B8_G8_R8_A8, DXGI_FORMAT_B8G8R8A8_UNORM, - 32, 16, 8, 8, 8, 0, 8, 24, 8); -const ImageFormatUnsigned ImageFormat::FORMAT_A8(ImageFormatId::A8, DXGI_FORMAT_A8_UNORM, - 8, 0, 0, 0, 0, 0, 0, 0, 8); -const ImageFormatUnsigned ImageFormat::FORMAT_R16_G16_B16_A16_FLOAT(ImageFormatId::R16_G16_B16_A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - 128, 0, 0, 0, 0, 0, 0, 0, 8); -const ImageFormatUnsigned ImageFormat::FORMAT_R8(ImageFormatId::R8, DXGI_FORMAT_R8_UNORM, - 8, 0, 8, 0, 0, 0, 0, 0, 0); -const ImageFormatUnsigned ImageFormat::FORMAT_R8_A8(ImageFormatId::R8_A8, DXGI_FORMAT_UNKNOWN, - 16, 0, 8, 0, 0, 0, 0, 8, 8); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC1(ImageFormatId::BC1, DXGI_FORMAT_BC1_UNORM, 4, 64); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC2(ImageFormatId::BC2, DXGI_FORMAT_BC2_UNORM, 4, 128); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC3(ImageFormatId::BC3, DXGI_FORMAT_BC3_UNORM, 4, 128); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC4(ImageFormatId::BC4, DXGI_FORMAT_BC4_UNORM, 4, 64); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC5(ImageFormatId::BC5, DXGI_FORMAT_BC5_UNORM, 4, 128); +const ImageFormatUnsigned ImageFormat::FORMAT_R8_G8_B8(ImageFormatId::R8_G8_B8, D3DFMT_R8G8B8, DXGI_FORMAT_UNKNOWN, 24, 0, 8, 8, 8, 16, 8, 0, 0); +const ImageFormatUnsigned ImageFormat::FORMAT_B8_G8_R8_X8(ImageFormatId::B8_G8_R8_X8, D3DFMT_X8R8G8B8, DXGI_FORMAT_B8G8R8X8_UNORM, 32, 16, 8, 8, 8, 0, 8, 0, 0); +const ImageFormatUnsigned ImageFormat::FORMAT_R8_G8_B8_A8(ImageFormatId::R8_G8_B8_A8, D3DFMT_A8B8G8R8, DXGI_FORMAT_R8G8B8A8_UNORM, 32, 0, 8, 8, 8, 16, 8, 24, 8); +const ImageFormatUnsigned ImageFormat::FORMAT_B8_G8_R8_A8(ImageFormatId::B8_G8_R8_A8, D3DFMT_A8R8G8B8, DXGI_FORMAT_B8G8R8A8_UNORM, 32, 16, 8, 8, 8, 0, 8, 24, 8); +const ImageFormatUnsigned ImageFormat::FORMAT_A8(ImageFormatId::A8, D3DFMT_A8, DXGI_FORMAT_A8_UNORM, 8, 0, 0, 0, 0, 0, 0, 0, 8); +const ImageFormatUnsigned ImageFormat::FORMAT_R16_G16_B16_A16_FLOAT(ImageFormatId::R16_G16_B16_A16_FLOAT, D3DFMT_A16B16G16R16F, DXGI_FORMAT_R16G16B16A16_FLOAT, 128, 0, 0, 0, 0, 0, 0, 0, 8); +const ImageFormatUnsigned ImageFormat::FORMAT_R8(ImageFormatId::R8, D3DFMT_L8, DXGI_FORMAT_R8_UNORM, 8, 0, 8, 0, 0, 0, 0, 0, 0); +const ImageFormatUnsigned ImageFormat::FORMAT_R8_A8(ImageFormatId::R8_A8, D3DFMT_A8L8, DXGI_FORMAT_UNKNOWN, 16, 0, 8, 0, 0, 0, 0, 8, 8); +const ImageFormatBlockCompressed ImageFormat::FORMAT_BC1(ImageFormatId::BC1, D3DFMT_DXT1, DXGI_FORMAT_BC1_UNORM, 4, 64); +const ImageFormatBlockCompressed ImageFormat::FORMAT_BC2(ImageFormatId::BC2, D3DFMT_DXT3, DXGI_FORMAT_BC2_UNORM, 4, 128); +const ImageFormatBlockCompressed ImageFormat::FORMAT_BC3(ImageFormatId::BC3, D3DFMT_DXT5, DXGI_FORMAT_BC3_UNORM, 4, 128); +const ImageFormatBlockCompressed ImageFormat::FORMAT_BC4(ImageFormatId::BC4, D3DFMT_UNKNOWN, DXGI_FORMAT_BC4_UNORM, 4, 64); +const ImageFormatBlockCompressed ImageFormat::FORMAT_BC5(ImageFormatId::BC5, D3DFMT_UNKNOWN, DXGI_FORMAT_BC5_UNORM, 4, 128); const ImageFormat* const ImageFormat::ALL_FORMATS[static_cast(ImageFormatId::MAX)] { diff --git a/src/Common/Image/ImageFormat.h b/src/Common/Image/ImageFormat.h index e49cb97f..70b559af 100644 --- a/src/Common/Image/ImageFormat.h +++ b/src/Common/Image/ImageFormat.h @@ -2,6 +2,7 @@ #include #include +#include "D3DFormat.h" #include "DxgiFormat.h" enum class ImageFormatId @@ -37,15 +38,17 @@ class ImageFormatBlockCompressed; class ImageFormat { ImageFormatId m_id; + D3DFORMAT m_d3d_format; DXGI_FORMAT m_dxgi_format; protected: - ImageFormat(ImageFormatId id, DXGI_FORMAT dxgiFormat); + ImageFormat(ImageFormatId id, D3DFORMAT d3dFormat, DXGI_FORMAT dxgiFormat); public: virtual ~ImageFormat() = default; ImageFormatId GetId() const; + D3DFORMAT GetD3DFormat() const; DXGI_FORMAT GetDxgiFormat() const; virtual ImageFormatType GetType() const = 0; @@ -81,7 +84,7 @@ public: unsigned m_a_offset; unsigned m_a_size; - ImageFormatUnsigned(ImageFormatId id, DXGI_FORMAT dxgiFormat, unsigned bitsPerPixel, unsigned rOffset, + ImageFormatUnsigned(ImageFormatId id, D3DFORMAT d3dFormat, DXGI_FORMAT dxgiFormat, unsigned bitsPerPixel, unsigned rOffset, unsigned rSize, unsigned gOffset, unsigned gSize, unsigned bOffset, unsigned bSize, unsigned aOffset, unsigned aSize); @@ -101,7 +104,7 @@ public: unsigned m_block_size; unsigned m_bits_per_block; - ImageFormatBlockCompressed(ImageFormatId id, DXGI_FORMAT dxgiFormat, unsigned blockSize, unsigned bitsPerBlock); + ImageFormatBlockCompressed(ImageFormatId id, D3DFORMAT d3dFormat, DXGI_FORMAT dxgiFormat, unsigned blockSize, unsigned bitsPerBlock); ImageFormatType GetType() const override; size_t GetPitch(unsigned mipLevel, unsigned width) const override; diff --git a/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp b/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp index 78a19afc..566cc762 100644 --- a/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp @@ -1,12 +1,15 @@ #include "ObjLoaderIW3.h" + #include "Game/IW3/GameIW3.h" #include "Game/IW3/GameAssetPoolIW3.h" #include "ObjContainer/IPak/IPak.h" #include "ObjLoading.h" #include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoading/AssetLoadingManager.h" +#include "Image/Dx9TextureLoader.h" #include "Image/Texture.h" #include "Image/IwiLoader.h" +#include "Image/IwiTypes.h" using namespace IW3; @@ -74,7 +77,31 @@ void ObjLoader::UnloadContainersOfZone(Zone* zone) const void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone) { - // TODO: Load Texture from LoadDef here + const auto* loadDef = image->texture.loadDef; + Dx9TextureLoader textureLoader(zone->GetMemory()); + + textureLoader.Width(loadDef->dimensions[0]).Height(loadDef->dimensions[1]).Depth(loadDef->dimensions[2]); + + if (loadDef->flags & iwi6::IMG_FLAG_VOLMAP) + textureLoader.Type(TextureType::T_3D); + else if (loadDef->flags & iwi6::IMG_FLAG_CUBEMAP) + textureLoader.Type(TextureType::T_CUBE); + else + textureLoader.Type(TextureType::T_2D); + + textureLoader.Format(static_cast(loadDef->format)); + textureLoader.HasMipMaps(!(loadDef->flags & iwi6::IMG_FLAG_NOMIPMAPS)); + Texture* loadedTexture = textureLoader.LoadTexture(image->texture.loadDef->data); + + if (loadedTexture != nullptr) + { + image->texture.texture = loadedTexture; + image->cardMemory.platform[0] = 0; + + const auto textureMipCount = loadedTexture->GetMipMapCount(); + for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++) + image->cardMemory.platform[0] += static_cast(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount()); + } } void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone) @@ -145,7 +172,7 @@ void ObjLoader::LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const LoadImageData(searchPath, zone); } -bool ObjLoader::LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const +bool ObjLoader::LoadAssetForZone(AssetLoadingContext* context, const asset_type_t assetType, const std::string& assetName) const { AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, *context); return assetLoadingManager.LoadAssetFromLoader(assetType, assetName); diff --git a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp index ae22394c..cf86abb8 100644 --- a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp @@ -1,12 +1,15 @@ #include "ObjLoaderIW4.h" + #include "Game/IW4/GameIW4.h" #include "Game/IW4/GameAssetPoolIW4.h" #include "ObjContainer/IPak/IPak.h" #include "ObjLoading.h" #include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoading/AssetLoadingManager.h" +#include "Image/Dx9TextureLoader.h" #include "Image/Texture.h" #include "Image/IwiLoader.h" +#include "Image/IwiTypes.h" using namespace IW4; @@ -84,7 +87,31 @@ void ObjLoader::UnloadContainersOfZone(Zone* zone) const void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone) { - // TODO: Load Texture from LoadDef here + const auto* loadDef = image->texture.loadDef; + Dx9TextureLoader textureLoader(zone->GetMemory()); + + textureLoader.Width(image->width).Height(image->height).Depth(image->depth); + + if ((loadDef->flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_3D) + textureLoader.Type(TextureType::T_3D); + else if ((loadDef->flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_CUBE) + textureLoader.Type(TextureType::T_CUBE); + else + textureLoader.Type(TextureType::T_2D); + + textureLoader.Format(static_cast(loadDef->format)); + textureLoader.HasMipMaps(!(loadDef->flags & iwi8::IMG_FLAG_NOMIPMAPS)); + Texture* loadedTexture = textureLoader.LoadTexture(image->texture.loadDef->data); + + if (loadedTexture != nullptr) + { + image->texture.texture = loadedTexture; + image->cardMemory.platform[0] = 0; + + const auto textureMipCount = loadedTexture->GetMipMapCount(); + for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++) + image->cardMemory.platform[0] += static_cast(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount()); + } } void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone) diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 9788b380..dd92470a 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -25,6 +25,8 @@ #include "Image/Texture.h" #include "Image/IwiLoader.h" #include "Game/T6/CommonT6.h" +#include "Image/Dx12TextureLoader.h" +#include "Image/IwiTypes.h" namespace T6 { @@ -329,7 +331,31 @@ namespace T6 void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone) { - // TODO: Load Texture from LoadDef here + const auto* loadDef = image->texture.loadDef; + Dx12TextureLoader textureLoader(zone->GetMemory()); + + textureLoader.Width(image->width).Height(image->height).Depth(image->depth); + + if (loadDef->flags & iwi27::IMG_FLAG_VOLMAP) + textureLoader.Type(TextureType::T_3D); + else if (loadDef->flags & iwi27::IMG_FLAG_CUBEMAP) + textureLoader.Type(TextureType::T_CUBE); + else + textureLoader.Type(TextureType::T_2D); + + textureLoader.Format(static_cast(loadDef->format)); + textureLoader.HasMipMaps(!(loadDef->flags & iwi27::IMG_FLAG_NOMIPMAPS)); + Texture* loadedTexture = textureLoader.LoadTexture(image->texture.loadDef->data); + + if (loadedTexture != nullptr) + { + image->texture.texture = loadedTexture; + image->loadedSize = 0; + + const auto textureMipCount = loadedTexture->GetMipMapCount(); + for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++) + image->loadedSize += static_cast(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount()); + } } void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone) diff --git a/src/ObjLoading/Image/Dx12TextureLoader.cpp b/src/ObjLoading/Image/Dx12TextureLoader.cpp new file mode 100644 index 00000000..b0d7cf81 --- /dev/null +++ b/src/ObjLoading/Image/Dx12TextureLoader.cpp @@ -0,0 +1,103 @@ +#include "Dx12TextureLoader.h" + +Dx12TextureLoader::Dx12TextureLoader(MemoryManager* memoryManager) + : m_memory_manager(memoryManager), + m_format(DXGI_FORMAT_UNKNOWN), + m_type(TextureType::T_2D), + m_has_mip_maps(false), + m_width(1u), + m_height(1u), + m_depth(1u) +{ +} + +const ImageFormat* Dx12TextureLoader::GetFormatForDx12Format() const +{ + for (auto i : ImageFormat::ALL_FORMATS) + { + if (i->GetDxgiFormat() == m_format) + return i; + } + + return nullptr; +} + +Dx12TextureLoader& Dx12TextureLoader::Format(const DXGI_FORMAT format) +{ + m_format = format; + return *this; +} + +Dx12TextureLoader& Dx12TextureLoader::Type(const TextureType textureType) +{ + m_type = textureType; + return *this; +} + +Dx12TextureLoader& Dx12TextureLoader::HasMipMaps(const bool hasMipMaps) +{ + m_has_mip_maps = hasMipMaps; + return *this; +} + +Dx12TextureLoader& Dx12TextureLoader::Width(const size_t width) +{ + m_width = width; + return *this; +} + +Dx12TextureLoader& Dx12TextureLoader::Height(const size_t height) +{ + m_height = height; + return *this; +} + +Dx12TextureLoader& Dx12TextureLoader::Depth(const size_t depth) +{ + m_depth = depth; + return *this; +} + +Texture* Dx12TextureLoader::LoadTexture(const void* data) +{ + const auto* format = GetFormatForDx12Format(); + + if (format == nullptr) + return nullptr; + + Texture* texture; + switch (m_type) + { + case TextureType::T_2D: + texture = m_memory_manager->Create(format, m_width, m_height, m_has_mip_maps); + break; + + case TextureType::T_3D: + texture = m_memory_manager->Create(format, m_width, m_height, m_depth, m_has_mip_maps); + break; + + case TextureType::T_CUBE: + texture = m_memory_manager->Create(format, m_width, m_width, m_has_mip_maps); + break; + + default: + return nullptr; + } + + texture->Allocate(); + const auto mipMapCount = m_has_mip_maps ? texture->GetMipMapCount() : 1; + const auto faceCount = m_type == TextureType::T_CUBE ? 6 : 1; + const void* currentDataOffset = data; + + for (auto currentMipLevel = 0; currentMipLevel < mipMapCount; currentMipLevel++) + { + for (auto currentFace = 0; currentFace < faceCount; currentFace++) + { + const auto mipSize = texture->GetSizeOfMipLevel(currentMipLevel); + memcpy(texture->GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize); + currentDataOffset = reinterpret_cast(reinterpret_cast(currentDataOffset) + mipSize); + } + } + + return texture; +} diff --git a/src/ObjLoading/Image/Dx12TextureLoader.h b/src/ObjLoading/Image/Dx12TextureLoader.h new file mode 100644 index 00000000..48306fdf --- /dev/null +++ b/src/ObjLoading/Image/Dx12TextureLoader.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include "Utils/ClassUtils.h" +#include "Image/DxgiFormat.h" +#include "Utils/MemoryManager.h" +#include "Image/Texture.h" + +class Dx12TextureLoader +{ + static std::unordered_map m_conversion_table; + + MemoryManager* m_memory_manager; + DXGI_FORMAT m_format; + TextureType m_type; + bool m_has_mip_maps; + size_t m_width; + size_t m_height; + size_t m_depth; + + _NODISCARD const ImageFormat* GetFormatForDx12Format() const; + +public: + explicit Dx12TextureLoader(MemoryManager* memoryManager); + + Dx12TextureLoader& Format(DXGI_FORMAT format); + Dx12TextureLoader& Type(TextureType textureType); + Dx12TextureLoader& HasMipMaps(bool hasMipMaps); + Dx12TextureLoader& Width(size_t width); + Dx12TextureLoader& Height(size_t height); + Dx12TextureLoader& Depth(size_t depth); + + Texture* LoadTexture(const void* data); +}; diff --git a/src/ObjLoading/Image/Dx9TextureLoader.cpp b/src/ObjLoading/Image/Dx9TextureLoader.cpp new file mode 100644 index 00000000..ffd1ca16 --- /dev/null +++ b/src/ObjLoading/Image/Dx9TextureLoader.cpp @@ -0,0 +1,103 @@ +#include "Dx9TextureLoader.h" + +Dx9TextureLoader::Dx9TextureLoader(MemoryManager* memoryManager) + : m_memory_manager(memoryManager), + m_format(D3DFMT_UNKNOWN), + m_type(TextureType::T_2D), + m_has_mip_maps(false), + m_width(1u), + m_height(1u), + m_depth(1u) +{ +} + +const ImageFormat* Dx9TextureLoader::GetFormatForDx9Format() const +{ + for (auto i : ImageFormat::ALL_FORMATS) + { + if (i->GetD3DFormat() == m_format) + return i; + } + + return nullptr; +} + +Dx9TextureLoader& Dx9TextureLoader::Format(const D3DFORMAT format) +{ + m_format = format; + return *this; +} + +Dx9TextureLoader& Dx9TextureLoader::Type(const TextureType textureType) +{ + m_type = textureType; + return *this; +} + +Dx9TextureLoader& Dx9TextureLoader::HasMipMaps(const bool hasMipMaps) +{ + m_has_mip_maps = hasMipMaps; + return *this; +} + +Dx9TextureLoader& Dx9TextureLoader::Width(const size_t width) +{ + m_width = width; + return *this; +} + +Dx9TextureLoader& Dx9TextureLoader::Height(const size_t height) +{ + m_height = height; + return *this; +} + +Dx9TextureLoader& Dx9TextureLoader::Depth(const size_t depth) +{ + m_depth = depth; + return *this; +} + +Texture* Dx9TextureLoader::LoadTexture(const void* data) +{ + const auto* format = GetFormatForDx9Format(); + + if (format == nullptr) + return nullptr; + + Texture* texture; + switch (m_type) + { + case TextureType::T_2D: + texture = m_memory_manager->Create(format, m_width, m_height, m_has_mip_maps); + break; + + case TextureType::T_3D: + texture = m_memory_manager->Create(format, m_width, m_height, m_depth, m_has_mip_maps); + break; + + case TextureType::T_CUBE: + texture = m_memory_manager->Create(format, m_width, m_width, m_has_mip_maps); + break; + + default: + return nullptr; + } + + texture->Allocate(); + const auto mipMapCount = m_has_mip_maps ? texture->GetMipMapCount() : 1; + const auto faceCount = m_type == TextureType::T_CUBE ? 6 : 1; + const void* currentDataOffset = data; + + for (auto currentMipLevel = 0; currentMipLevel < mipMapCount; currentMipLevel++) + { + for (auto currentFace = 0; currentFace < faceCount; currentFace++) + { + const auto mipSize = texture->GetSizeOfMipLevel(currentMipLevel); + memcpy(texture->GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize); + currentDataOffset = reinterpret_cast(reinterpret_cast(currentDataOffset) + mipSize); + } + } + + return texture; +} diff --git a/src/ObjLoading/Image/Dx9TextureLoader.h b/src/ObjLoading/Image/Dx9TextureLoader.h new file mode 100644 index 00000000..8af9afd7 --- /dev/null +++ b/src/ObjLoading/Image/Dx9TextureLoader.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "Utils/ClassUtils.h" +#include "Image/D3DFormat.h" +#include "Utils/MemoryManager.h" +#include "Image/Texture.h" + +class Dx9TextureLoader +{ + MemoryManager* m_memory_manager; + D3DFORMAT m_format; + TextureType m_type; + bool m_has_mip_maps; + size_t m_width; + size_t m_height; + size_t m_depth; + + _NODISCARD const ImageFormat* GetFormatForDx9Format() const; + +public: + explicit Dx9TextureLoader(MemoryManager* memoryManager); + + Dx9TextureLoader& Format(D3DFORMAT format); + Dx9TextureLoader& Type(TextureType textureType); + Dx9TextureLoader& HasMipMaps(bool hasMipMaps); + Dx9TextureLoader& Width(size_t width); + Dx9TextureLoader& Height(size_t height); + Dx9TextureLoader& Depth(size_t depth); + + Texture* LoadTexture(const void* data); +}; diff --git a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperGfxImage.cpp b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperGfxImage.cpp index 988c67ca..359f1203 100644 --- a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperGfxImage.cpp +++ b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperGfxImage.cpp @@ -38,7 +38,21 @@ bool AssetDumperGfxImage::CanDumpAsRaw() std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) { - return "images/" + asset->m_name + m_writer->GetFileExtension(); + std::string cleanAssetName = asset->m_name; + for (auto& c : cleanAssetName) + { + switch (c) + { + case '*': + c = '_'; + break; + + default: + break; + } + } + + return "images/" + cleanAssetName + m_writer->GetFileExtension(); } void AssetDumperGfxImage::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperGfxImage.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperGfxImage.cpp index 5554de59..b5ce9d19 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperGfxImage.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperGfxImage.cpp @@ -38,7 +38,21 @@ bool AssetDumperGfxImage::CanDumpAsRaw() std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) { - return "images/" + asset->m_name + m_writer->GetFileExtension(); + std::string cleanAssetName = asset->m_name; + for (auto& c : cleanAssetName) + { + switch (c) + { + case '*': + c = '_'; + break; + + default: + break; + } + } + + return "images/" + cleanAssetName + m_writer->GetFileExtension(); } void AssetDumperGfxImage::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperGfxImage.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperGfxImage.cpp index 6bca064e..50e6d18b 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperGfxImage.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperGfxImage.cpp @@ -38,7 +38,21 @@ bool AssetDumperGfxImage::CanDumpAsRaw() std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) { - return "images/" + asset->m_name + m_writer->GetFileExtension(); + std::string cleanAssetName = asset->m_name; + for (auto& c : cleanAssetName) + { + switch (c) + { + case '*': + c = '_'; + break; + + default: + break; + } + } + + return "images/" + cleanAssetName + m_writer->GetFileExtension(); } void AssetDumperGfxImage::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream)