From a5d1d09fa93f170bc684ab0753e79345be0bf3ac Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Sat, 3 Jan 2026 13:58:46 +0100 Subject: [PATCH] chore: update image namespacing --- src/ImageConverter.lua | 2 + src/ImageConverter/ImageConverter.cpp | 51 +- src/ImageConverter/ImageConverterArgs.cpp | 2 +- src/ImageConverter/ImageConverterArgs.h | 17 +- src/ObjImage/Image/DdsLoader.cpp | 11 +- src/ObjImage/Image/DdsLoader.h | 2 +- src/ObjImage/Image/DdsTypes.h | 196 ++--- src/ObjImage/Image/DdsWriter.cpp | 430 +++++----- src/ObjImage/Image/DdsWriter.h | 20 +- src/ObjImage/Image/Dx12TextureLoader.cpp | 185 ++-- src/ObjImage/Image/Dx12TextureLoader.h | 43 +- src/ObjImage/Image/Dx9TextureLoader.cpp | 185 ++-- src/ObjImage/Image/Dx9TextureLoader.h | 41 +- src/ObjImage/Image/IImageWriter.h | 21 - src/ObjImage/Image/ImageFormat.cpp | 295 +++---- src/ObjImage/Image/ImageFormat.h | 197 ++--- src/ObjImage/Image/ImageWriter.h | 24 + src/ObjImage/Image/IwiLoader.cpp | 29 +- src/ObjImage/Image/IwiLoader.h | 4 +- src/ObjImage/Image/IwiTypes.h | 437 +++++----- src/ObjImage/Image/IwiWriter13.cpp | 8 +- src/ObjImage/Image/IwiWriter13.h | 8 +- src/ObjImage/Image/IwiWriter27.cpp | 8 +- src/ObjImage/Image/IwiWriter27.h | 8 +- src/ObjImage/Image/IwiWriter6.cpp | 8 +- src/ObjImage/Image/IwiWriter6.h | 8 +- src/ObjImage/Image/IwiWriter8.cpp | 8 +- src/ObjImage/Image/IwiWriter8.h | 8 +- src/ObjImage/Image/Texture.cpp | 787 +++++++++--------- src/ObjImage/Image/Texture.h | 195 ++--- src/ObjImage/Image/TextureConverter.cpp | 379 ++++----- src/ObjImage/Image/TextureConverter.h | 37 +- .../Game/IW3/Image/AssetLoaderImageIW3.cpp | 9 +- .../Game/IW5/Image/LoaderImageIW5.cpp | 2 +- .../Game/T6/Image/LoaderImageT6.cpp | 2 +- src/ObjLoading/Image/ImageLoaderCommon.cpp | 15 + src/ObjLoading/Image/ImageLoaderCommon.h | 23 + .../Game/IW3/Image/ImageDumperIW3.cpp | 9 +- .../Game/IW3/Image/ImageDumperIW3.h | 4 +- .../Game/IW4/Image/ImageDumperIW4.cpp | 9 +- .../Game/IW4/Image/ImageDumperIW4.h | 4 +- .../Game/IW5/Image/ImageDumperIW5.cpp | 9 +- .../Game/IW5/Image/ImageDumperIW5.h | 4 +- .../Game/T5/Image/ImageDumperT5.cpp | 9 +- src/ObjWriting/Game/T5/Image/ImageDumperT5.h | 4 +- .../Game/T6/Image/ImageDumperT6.cpp | 11 +- src/ObjWriting/Game/T6/Image/ImageDumperT6.h | 4 +- 47 files changed, 1940 insertions(+), 1832 deletions(-) delete mode 100644 src/ObjImage/Image/IImageWriter.h create mode 100644 src/ObjImage/Image/ImageWriter.h create mode 100644 src/ObjLoading/Image/ImageLoaderCommon.cpp create mode 100644 src/ObjLoading/Image/ImageLoaderCommon.h diff --git a/src/ImageConverter.lua b/src/ImageConverter.lua index 79a7f3cf..a34fa239 100644 --- a/src/ImageConverter.lua +++ b/src/ImageConverter.lua @@ -38,11 +38,13 @@ function ImageConverter:project() self:include(includes) Utils:include(includes) + Common:include(includes) ObjImage:include(includes) Raw:use() links:linkto(Utils) + links:linkto(Common) links:linkto(ObjImage) links:linkall() end diff --git a/src/ImageConverter/ImageConverter.cpp b/src/ImageConverter/ImageConverter.cpp index 2db2e011..bdca8853 100644 --- a/src/ImageConverter/ImageConverter.cpp +++ b/src/ImageConverter/ImageConverter.cpp @@ -1,5 +1,6 @@ #include "ImageConverter.h" +#include "Game/IGame.h" #include "Image/DdsLoader.h" #include "Image/DdsWriter.h" #include "Image/IwiLoader.h" @@ -17,10 +18,12 @@ #include #include #include +#include namespace fs = std::filesystem; +using namespace image; -namespace image_converter +namespace { constexpr auto EXTENSION_IWI = ".iwi"; constexpr auto EXTENSION_DDS = ".dds"; @@ -29,7 +32,7 @@ namespace image_converter { public: ImageConverterImpl() - : m_game_to_convert_to(image_converter::Game::UNKNOWN) + : m_game_to_convert_to(std::nullopt) { } @@ -76,7 +79,7 @@ namespace image_converter return false; } - const auto texture = iwi::LoadIwi(file); + const auto texture = image::LoadIwi(file); if (!texture) return false; @@ -103,7 +106,7 @@ namespace image_converter return false; } - const auto texture = dds::LoadDds(file); + const auto texture = image::LoadDds(file); if (!texture) return false; @@ -129,23 +132,23 @@ namespace image_converter if (m_iwi_writer) return true; - if (m_game_to_convert_to == Game::UNKNOWN && !ShowGameTui()) + if (!m_game_to_convert_to && !ShowGameTui()) return false; - switch (m_game_to_convert_to) + switch (*m_game_to_convert_to) { - case Game::IW3: - m_iwi_writer = std::make_unique(); + case GameId::IW3: + m_iwi_writer = std::make_unique(); break; - case Game::IW4: - case Game::IW5: - m_iwi_writer = std::make_unique(); + case GameId::IW4: + case GameId::IW5: + m_iwi_writer = std::make_unique(); break; - case Game::T5: - m_iwi_writer = std::make_unique(); + case GameId::T5: + m_iwi_writer = std::make_unique(); break; - case Game::T6: - m_iwi_writer = std::make_unique(); + case GameId::T6: + m_iwi_writer = std::make_unique(); break; default: assert(false); @@ -170,19 +173,19 @@ namespace image_converter switch (num) { case 1: - m_game_to_convert_to = Game::IW3; + m_game_to_convert_to = GameId::IW3; break; case 2: - m_game_to_convert_to = Game::IW4; + m_game_to_convert_to = GameId::IW4; break; case 3: - m_game_to_convert_to = Game::IW5; + m_game_to_convert_to = GameId::IW5; break; case 4: - m_game_to_convert_to = Game::T5; + m_game_to_convert_to = GameId::T5; break; case 5: - m_game_to_convert_to = Game::T6; + m_game_to_convert_to = GameId::T6; break; default: con::error("Invalid input"); @@ -193,13 +196,13 @@ namespace image_converter } ImageConverterArgs m_args; - image_converter::Game m_game_to_convert_to; + std::optional m_game_to_convert_to; DdsWriter m_dds_writer; - std::unique_ptr m_iwi_writer; + std::unique_ptr m_iwi_writer; }; -} // namespace image_converter +} // namespace std::unique_ptr ImageConverter::Create() { - return std::make_unique(); + return std::make_unique(); } diff --git a/src/ImageConverter/ImageConverterArgs.cpp b/src/ImageConverter/ImageConverterArgs.cpp index fad732b8..e9fddb16 100644 --- a/src/ImageConverter/ImageConverterArgs.cpp +++ b/src/ImageConverter/ImageConverterArgs.cpp @@ -86,7 +86,7 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]{ }; ImageConverterArgs::ImageConverterArgs() - : m_game_to_convert_to(image_converter::Game::UNKNOWN), + : m_game_to_convert_to(std::nullopt), m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v) { } diff --git a/src/ImageConverter/ImageConverterArgs.h b/src/ImageConverter/ImageConverterArgs.h index 2a221523..fe63a6c4 100644 --- a/src/ImageConverter/ImageConverterArgs.h +++ b/src/ImageConverter/ImageConverterArgs.h @@ -1,24 +1,13 @@ #pragma once +#include "Game/IGame.h" #include "Utils/Arguments/ArgumentParser.h" #include +#include #include #include -namespace image_converter -{ - enum class Game : std::uint8_t - { - UNKNOWN, - IW3, - IW4, - IW5, - T5, - T6 - }; -} // namespace image_converter - class ImageConverterArgs { public: @@ -26,7 +15,7 @@ public: bool ParseArgs(int argc, const char** argv, bool& shouldContinue); std::vector m_files_to_convert; - image_converter::Game m_game_to_convert_to; + std::optional m_game_to_convert_to; private: /** diff --git a/src/ObjImage/Image/DdsLoader.cpp b/src/ObjImage/Image/DdsLoader.cpp index f2ef47aa..eb85379a 100644 --- a/src/ObjImage/Image/DdsLoader.cpp +++ b/src/ObjImage/Image/DdsLoader.cpp @@ -9,7 +9,9 @@ #include #include -namespace dds +using namespace image; + +namespace { class DdsLoaderInternal { @@ -193,7 +195,7 @@ namespace dds return ReadPixelFormatUnsigned(pf); } - _NODISCARD bool ReadHeader() + [[nodiscard]] bool ReadHeader() { DDS_HEADER header{}; m_stream.read(reinterpret_cast(&header), sizeof(header)); @@ -277,10 +279,13 @@ namespace dds unsigned m_depth; const ImageFormat* m_format; }; +} // namespace +namespace image +{ std::unique_ptr LoadDds(std::istream& stream) { DdsLoaderInternal internal(stream); return internal.LoadDds(); } -} // namespace dds +} // namespace image diff --git a/src/ObjImage/Image/DdsLoader.h b/src/ObjImage/Image/DdsLoader.h index 90619b9f..5b7a93fe 100644 --- a/src/ObjImage/Image/DdsLoader.h +++ b/src/ObjImage/Image/DdsLoader.h @@ -5,7 +5,7 @@ #include #include -namespace dds +namespace image { std::unique_ptr LoadDds(std::istream& stream); } diff --git a/src/ObjImage/Image/DdsTypes.h b/src/ObjImage/Image/DdsTypes.h index 0d368dad..fce20384 100644 --- a/src/ObjImage/Image/DdsTypes.h +++ b/src/ObjImage/Image/DdsTypes.h @@ -2,110 +2,114 @@ #include -constexpr uint32_t MakeFourCc(const char ch0, const char ch1, const char ch2, const char ch3) +namespace image { - return static_cast(ch0) | static_cast(ch1) << 8 | static_cast(ch2) << 16 | static_cast(ch3) << 24; -} + constexpr uint32_t MakeFourCc(const char ch0, const char ch1, const char ch2, const char ch3) + { + return static_cast(ch0) | static_cast(ch1) << 8 | static_cast(ch2) << 16 | static_cast(ch3) << 24; + } -enum DDP_FLAGS -{ - DDPF_ALPHAPIXELS = 0x1, - DDPF_ALPHA = 0x2, - DDPF_FOURCC = 0x4, - DDPF_RGB = 0x40, - DDPF_YUV = 0x200, - DDPF_LUMINANCE = 0x20000 -}; + enum DDP_FLAGS + { + DDPF_ALPHAPIXELS = 0x1, + DDPF_ALPHA = 0x2, + DDPF_FOURCC = 0x4, + DDPF_RGB = 0x40, + DDPF_YUV = 0x200, + DDPF_LUMINANCE = 0x20000 + }; -enum DDS_HEADER_FLAGS -{ - DDSD_CAPS = 0x1, - DDSD_HEIGHT = 0x2, - DDSD_WIDTH = 0x4, - DDSD_PITCH = 0x8, - DDSD_PIXELFORMAT = 0x1000, - DDSD_MIPMAPCOUNT = 0x20000, - DDSD_LINEARSIZE = 0x80000, - DDSD_DEPTH = 0x800000, -}; + enum DDS_HEADER_FLAGS + { + DDSD_CAPS = 0x1, + DDSD_HEIGHT = 0x2, + DDSD_WIDTH = 0x4, + DDSD_PITCH = 0x8, + DDSD_PIXELFORMAT = 0x1000, + DDSD_MIPMAPCOUNT = 0x20000, + DDSD_LINEARSIZE = 0x80000, + DDSD_DEPTH = 0x800000, + }; -enum DDS_HEADER_CAPS -{ - DDSCAPS_COMPLEX = 0x8, - DDSCAPS_TEXTURE = 0x1000, - DDSCAPS_MIPMAP = 0x400000, -}; + enum DDS_HEADER_CAPS + { + DDSCAPS_COMPLEX = 0x8, + DDSCAPS_TEXTURE = 0x1000, + DDSCAPS_MIPMAP = 0x400000, + }; -enum DDS_HEADER_CAPS2 -{ - DDSCAPS2_CUBEMAP = 0x200, - DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, - DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, - DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, - DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, - DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, - DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, - DDSCAPS2_VOLUME = 0x200000, -}; + enum DDS_HEADER_CAPS2 + { + DDSCAPS2_CUBEMAP = 0x200, + DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, + DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, + DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, + DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, + DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, + DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, + DDSCAPS2_VOLUME = 0x200000, + }; -struct DDS_PIXELFORMAT -{ - uint32_t dwSize; - uint32_t dwFlags; - uint32_t dwFourCC; - uint32_t dwRGBBitCount; - uint32_t dwRBitMask; - uint32_t dwGBitMask; - uint32_t dwBBitMask; - uint32_t dwABitMask; -}; + struct DDS_PIXELFORMAT + { + uint32_t dwSize; + uint32_t dwFlags; + uint32_t dwFourCC; + uint32_t dwRGBBitCount; + uint32_t dwRBitMask; + uint32_t dwGBitMask; + uint32_t dwBBitMask; + uint32_t dwABitMask; + }; -struct DDS_HEADER -{ - uint32_t dwSize; - uint32_t dwFlags; - uint32_t dwHeight; - uint32_t dwWidth; - uint32_t dwPitchOrLinearSize; - uint32_t dwDepth; - uint32_t dwMipMapCount; - uint32_t dwReserved1[11]; - DDS_PIXELFORMAT ddspf; - uint32_t dwCaps; - uint32_t dwCaps2; - uint32_t dwCaps3; - uint32_t dwCaps4; - uint32_t dwReserved2; -}; + struct DDS_HEADER + { + uint32_t dwSize; + uint32_t dwFlags; + uint32_t dwHeight; + uint32_t dwWidth; + uint32_t dwPitchOrLinearSize; + uint32_t dwDepth; + uint32_t dwMipMapCount; + uint32_t dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + uint32_t dwCaps; + uint32_t dwCaps2; + uint32_t dwCaps3; + uint32_t dwCaps4; + uint32_t dwReserved2; + }; -enum D3D10_RESOURCE_DIMENSION -{ - D3D10_RESOURCE_DIMENSION_UNKNOWN, - D3D10_RESOURCE_DIMENSION_BUFFER, - D3D10_RESOURCE_DIMENSION_TEXTURE1D, - D3D10_RESOURCE_DIMENSION_TEXTURE2D, - D3D10_RESOURCE_DIMENSION_TEXTURE3D -}; + enum D3D10_RESOURCE_DIMENSION + { + D3D10_RESOURCE_DIMENSION_UNKNOWN, + D3D10_RESOURCE_DIMENSION_BUFFER, + D3D10_RESOURCE_DIMENSION_TEXTURE1D, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + D3D10_RESOURCE_DIMENSION_TEXTURE3D + }; -enum DDS_HEADER_DXT10_MISC -{ - DDS_RESOURCE_MISC_TEXTURECUBE = 0x4 -}; + enum DDS_HEADER_DXT10_MISC + { + DDS_RESOURCE_MISC_TEXTURECUBE = 0x4 + }; -enum DDS_HEADER_DXT10_MISC2 -{ - DDS_ALPHA_MODE_UNKNOWN = 0x0, - DDS_ALPHA_MODE_STRAIGHT = 0x1, - DDS_ALPHA_MODE_PREMULTIPLIED = 0x2, - DDS_ALPHA_MODE_OPAQUE = 0x3, - DDS_ALPHA_MODE_CUSTOM = 0x4, -}; + enum DDS_HEADER_DXT10_MISC2 + { + DDS_ALPHA_MODE_UNKNOWN = 0x0, + DDS_ALPHA_MODE_STRAIGHT = 0x1, + DDS_ALPHA_MODE_PREMULTIPLIED = 0x2, + DDS_ALPHA_MODE_OPAQUE = 0x3, + DDS_ALPHA_MODE_CUSTOM = 0x4, + }; -struct DDS_HEADER_DXT10 -{ - oat::DXGI_FORMAT dxgiFormat; - D3D10_RESOURCE_DIMENSION resourceDimension; - uint32_t miscFlag; - uint32_t arraySize; - uint32_t miscFlags2; -}; + struct DDS_HEADER_DXT10 + { + oat::DXGI_FORMAT dxgiFormat; + D3D10_RESOURCE_DIMENSION resourceDimension; + uint32_t miscFlag; + uint32_t arraySize; + uint32_t miscFlags2; + }; + +} // namespace image diff --git a/src/ObjImage/Image/DdsWriter.cpp b/src/ObjImage/Image/DdsWriter.cpp index 93e88da0..bc3e5800 100644 --- a/src/ObjImage/Image/DdsWriter.cpp +++ b/src/ObjImage/Image/DdsWriter.cpp @@ -7,234 +7,242 @@ #include #include -const std::map DDS_CONVERSION_TABLE{ - {ImageFormatId::R8_G8_B8, ImageFormatId::B8_G8_R8_X8}, -}; +using namespace image; -class DdsWriterInternal +namespace { -public: - static bool SupportsImageFormat(const ImageFormat* imageFormat) + const std::map DDS_CONVERSION_TABLE{ + {ImageFormatId::R8_G8_B8, ImageFormatId::B8_G8_R8_X8}, + }; + + class DdsWriterInternal { - return true; - } - - static std::string GetFileExtension() - { - return ".dds"; - } - - DdsWriterInternal(std::ostream& stream, const Texture* texture) - : m_stream(stream), - m_texture(texture), - m_use_dx10_extension(false) - { - } - - void DumpImage() - { - ConvertTextureIfNecessary(); - - DDS_HEADER header{}; - PopulateDdsHeader(header); - - constexpr auto magic = MakeFourCc('D', 'D', 'S', ' '); - - m_stream.write(reinterpret_cast(&magic), sizeof(magic)); - m_stream.write(reinterpret_cast(&header), sizeof(header)); - - if (m_use_dx10_extension) + public: + static bool SupportsImageFormat(const ImageFormat* imageFormat) { - DDS_HEADER_DXT10 dxt10{}; - PopulateDxt10Header(dxt10); - m_stream.write(reinterpret_cast(&dxt10), sizeof(dxt10)); + return true; } - const auto mipCount = m_texture->HasMipMaps() ? m_texture->GetMipMapCount() : 1; - for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) + static std::string GetFileExtension() { - const auto* buffer = m_texture->GetBufferForMipLevel(mipLevel); - const auto mipLevelSize = m_texture->GetSizeOfMipLevel(mipLevel) * m_texture->GetFaceCount(); - m_stream.write(reinterpret_cast(buffer), static_cast(mipLevelSize)); - } - } - - static constexpr unsigned Mask1(const unsigned length) - { - if (length >= sizeof(unsigned) * 8) - return UINT32_MAX; - - return UINT32_MAX >> (sizeof(unsigned) * 8 - length); - } - - void PopulatePixelFormatBlockCompressed(DDS_PIXELFORMAT& pf, const ImageFormatBlockCompressed* format) - { - pf.dwSize = sizeof(DDS_PIXELFORMAT); - pf.dwFlags = DDPF_FOURCC; - pf.dwRGBBitCount = 0; - pf.dwRBitMask = 0; - pf.dwGBitMask = 0; - pf.dwBBitMask = 0; - pf.dwABitMask = 0; - - // Use standard pixel format for DXT1-5 for maximum compatibility and only otherwise use DX10 extension - switch (format->GetDxgiFormat()) - { - case oat::DXGI_FORMAT_BC1_UNORM: - pf.dwFourCC = MakeFourCc('D', 'X', 'T', '1'); - break; - case oat::DXGI_FORMAT_BC2_UNORM: - pf.dwFourCC = MakeFourCc('D', 'X', 'T', '3'); - break; - case oat::DXGI_FORMAT_BC3_UNORM: - pf.dwFourCC = MakeFourCc('D', 'X', 'T', '5'); - break; - default: - m_use_dx10_extension = true; - pf.dwFourCC = MakeFourCc('D', 'X', '1', '0'); - break; - } - } - - static void PopulatePixelFormatUnsigned(DDS_PIXELFORMAT& pf, const ImageFormatUnsigned* format) - { - pf.dwSize = sizeof(DDS_PIXELFORMAT); - pf.dwFourCC = 0; - pf.dwRGBBitCount = format->m_bits_per_pixel; - pf.dwRBitMask = format->HasR() ? Mask1(format->m_r_size) << format->m_r_offset : 0; - pf.dwGBitMask = format->HasG() ? Mask1(format->m_g_size) << format->m_g_offset : 0; - pf.dwBBitMask = format->HasB() ? Mask1(format->m_b_size) << format->m_b_offset : 0; - pf.dwABitMask = format->HasA() ? Mask1(format->m_a_size) << format->m_a_offset : 0; - - pf.dwFlags = 0; - if (format->HasA()) - pf.dwFlags |= DDPF_ALPHAPIXELS; - - if (format->HasR() && !format->HasG() && !format->HasB()) - pf.dwFlags |= DDPF_LUMINANCE; - else - pf.dwFlags |= DDPF_RGB; - } - - void PopulatePixelFormat(DDS_PIXELFORMAT& pf) - { - const auto* format = m_texture->GetFormat(); - - switch (format->GetType()) - { - case ImageFormatType::BLOCK_COMPRESSED: - PopulatePixelFormatBlockCompressed(pf, dynamic_cast(format)); - break; - case ImageFormatType::UNSIGNED: - PopulatePixelFormatUnsigned(pf, dynamic_cast(format)); - break; - default: - assert(false); - break; - } - } - - void PopulateDdsHeader(DDS_HEADER& header) - { - header.dwSize = sizeof(header); - header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; - - if (m_texture->HasMipMaps()) - header.dwFlags |= DDSD_MIPMAPCOUNT; - - if (m_texture->GetFormat()->GetType() == ImageFormatType::BLOCK_COMPRESSED) - header.dwFlags |= DDSD_LINEARSIZE; - else - header.dwFlags |= DDSD_PITCH; - - if (m_texture->GetDepth() > 1) - header.dwFlags |= DDSD_DEPTH; - - header.dwHeight = m_texture->GetHeight(); - header.dwWidth = m_texture->GetWidth(); - header.dwDepth = m_texture->GetDepth(); - header.dwPitchOrLinearSize = static_cast(m_texture->GetFormat()->GetPitch(0, m_texture->GetWidth())); - header.dwMipMapCount = m_texture->HasMipMaps() ? m_texture->GetMipMapCount() : 1; - - PopulatePixelFormat(header.ddspf); - - header.dwCaps = DDSCAPS_TEXTURE; - - if (m_texture->HasMipMaps()) - header.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - - if (m_texture->GetTextureType() == TextureType::T_CUBE) - header.dwCaps |= DDSCAPS_COMPLEX; - - header.dwCaps2 = 0; - - if (m_texture->GetTextureType() == TextureType::T_CUBE) - { - header.dwCaps2 |= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_NEGATIVEX | DDSCAPS2_CUBEMAP_POSITIVEY - | DDSCAPS2_CUBEMAP_NEGATIVEY | DDSCAPS2_CUBEMAP_POSITIVEZ | DDSCAPS2_CUBEMAP_NEGATIVEZ; + return ".dds"; } - header.dwCaps3 = 0; - header.dwCaps4 = 0; - header.dwReserved2 = 0; - } - - void PopulateDxt10Header(DDS_HEADER_DXT10& header) const - { - header.dxgiFormat = m_texture->GetFormat()->GetDxgiFormat(); - header.miscFlag = 0; - header.miscFlags2 = 0; - - switch (m_texture->GetTextureType()) + DdsWriterInternal(std::ostream& stream, const Texture* texture) + : m_stream(stream), + m_texture(texture), + m_use_dx10_extension(false) { - case TextureType::T_2D: - header.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - header.arraySize = 1; - break; - case TextureType::T_CUBE: - header.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - header.arraySize = 6; - header.miscFlag |= DDS_RESOURCE_MISC_TEXTURECUBE; - break; - case TextureType::T_3D: - header.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; - header.arraySize = 1; - break; } - } - void ConvertTextureIfNecessary() - { - const auto entry = DDS_CONVERSION_TABLE.find(m_texture->GetFormat()->GetId()); - - if (entry != DDS_CONVERSION_TABLE.end()) + void DumpImage() { - TextureConverter converter(m_texture, ImageFormat::ALL_FORMATS[static_cast(entry->second)]); - m_converted_texture = converter.Convert(); - m_texture = m_converted_texture.get(); + ConvertTextureIfNecessary(); + + DDS_HEADER header{}; + PopulateDdsHeader(header); + + constexpr auto magic = MakeFourCc('D', 'D', 'S', ' '); + + m_stream.write(reinterpret_cast(&magic), sizeof(magic)); + m_stream.write(reinterpret_cast(&header), sizeof(header)); + + if (m_use_dx10_extension) + { + DDS_HEADER_DXT10 dxt10{}; + PopulateDxt10Header(dxt10); + m_stream.write(reinterpret_cast(&dxt10), sizeof(dxt10)); + } + + const auto mipCount = m_texture->HasMipMaps() ? m_texture->GetMipMapCount() : 1; + for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) + { + const auto* buffer = m_texture->GetBufferForMipLevel(mipLevel); + const auto mipLevelSize = m_texture->GetSizeOfMipLevel(mipLevel) * m_texture->GetFaceCount(); + m_stream.write(reinterpret_cast(buffer), static_cast(mipLevelSize)); + } } - } - std::ostream& m_stream; - const Texture* m_texture; - std::unique_ptr m_converted_texture; - bool m_use_dx10_extension; -}; + static constexpr unsigned Mask1(const unsigned length) + { + if (length >= sizeof(unsigned) * 8) + return UINT32_MAX; -DdsWriter::~DdsWriter() = default; + return UINT32_MAX >> (sizeof(unsigned) * 8 - length); + } -bool DdsWriter::SupportsImageFormat(const ImageFormat* imageFormat) + void PopulatePixelFormatBlockCompressed(DDS_PIXELFORMAT& pf, const ImageFormatBlockCompressed* format) + { + pf.dwSize = sizeof(DDS_PIXELFORMAT); + pf.dwFlags = DDPF_FOURCC; + pf.dwRGBBitCount = 0; + pf.dwRBitMask = 0; + pf.dwGBitMask = 0; + pf.dwBBitMask = 0; + pf.dwABitMask = 0; + + // Use standard pixel format for DXT1-5 for maximum compatibility and only otherwise use DX10 extension + switch (format->GetDxgiFormat()) + { + case oat::DXGI_FORMAT_BC1_UNORM: + pf.dwFourCC = MakeFourCc('D', 'X', 'T', '1'); + break; + case oat::DXGI_FORMAT_BC2_UNORM: + pf.dwFourCC = MakeFourCc('D', 'X', 'T', '3'); + break; + case oat::DXGI_FORMAT_BC3_UNORM: + pf.dwFourCC = MakeFourCc('D', 'X', 'T', '5'); + break; + default: + m_use_dx10_extension = true; + pf.dwFourCC = MakeFourCc('D', 'X', '1', '0'); + break; + } + } + + static void PopulatePixelFormatUnsigned(DDS_PIXELFORMAT& pf, const ImageFormatUnsigned* format) + { + pf.dwSize = sizeof(DDS_PIXELFORMAT); + pf.dwFourCC = 0; + pf.dwRGBBitCount = format->m_bits_per_pixel; + pf.dwRBitMask = format->HasR() ? Mask1(format->m_r_size) << format->m_r_offset : 0; + pf.dwGBitMask = format->HasG() ? Mask1(format->m_g_size) << format->m_g_offset : 0; + pf.dwBBitMask = format->HasB() ? Mask1(format->m_b_size) << format->m_b_offset : 0; + pf.dwABitMask = format->HasA() ? Mask1(format->m_a_size) << format->m_a_offset : 0; + + pf.dwFlags = 0; + if (format->HasA()) + pf.dwFlags |= DDPF_ALPHAPIXELS; + + if (format->HasR() && !format->HasG() && !format->HasB()) + pf.dwFlags |= DDPF_LUMINANCE; + else + pf.dwFlags |= DDPF_RGB; + } + + void PopulatePixelFormat(DDS_PIXELFORMAT& pf) + { + const auto* format = m_texture->GetFormat(); + + switch (format->GetType()) + { + case ImageFormatType::BLOCK_COMPRESSED: + PopulatePixelFormatBlockCompressed(pf, dynamic_cast(format)); + break; + case ImageFormatType::UNSIGNED: + PopulatePixelFormatUnsigned(pf, dynamic_cast(format)); + break; + default: + assert(false); + break; + } + } + + void PopulateDdsHeader(DDS_HEADER& header) + { + header.dwSize = sizeof(header); + header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; + + if (m_texture->HasMipMaps()) + header.dwFlags |= DDSD_MIPMAPCOUNT; + + if (m_texture->GetFormat()->GetType() == ImageFormatType::BLOCK_COMPRESSED) + header.dwFlags |= DDSD_LINEARSIZE; + else + header.dwFlags |= DDSD_PITCH; + + if (m_texture->GetDepth() > 1) + header.dwFlags |= DDSD_DEPTH; + + header.dwHeight = m_texture->GetHeight(); + header.dwWidth = m_texture->GetWidth(); + header.dwDepth = m_texture->GetDepth(); + header.dwPitchOrLinearSize = static_cast(m_texture->GetFormat()->GetPitch(0, m_texture->GetWidth())); + header.dwMipMapCount = m_texture->HasMipMaps() ? m_texture->GetMipMapCount() : 1; + + PopulatePixelFormat(header.ddspf); + + header.dwCaps = DDSCAPS_TEXTURE; + + if (m_texture->HasMipMaps()) + header.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; + + if (m_texture->GetTextureType() == TextureType::T_CUBE) + header.dwCaps |= DDSCAPS_COMPLEX; + + header.dwCaps2 = 0; + + if (m_texture->GetTextureType() == TextureType::T_CUBE) + { + header.dwCaps2 |= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_NEGATIVEX | DDSCAPS2_CUBEMAP_POSITIVEY + | DDSCAPS2_CUBEMAP_NEGATIVEY | DDSCAPS2_CUBEMAP_POSITIVEZ | DDSCAPS2_CUBEMAP_NEGATIVEZ; + } + + header.dwCaps3 = 0; + header.dwCaps4 = 0; + header.dwReserved2 = 0; + } + + void PopulateDxt10Header(DDS_HEADER_DXT10& header) const + { + header.dxgiFormat = m_texture->GetFormat()->GetDxgiFormat(); + header.miscFlag = 0; + header.miscFlags2 = 0; + + switch (m_texture->GetTextureType()) + { + case TextureType::T_2D: + header.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + header.arraySize = 1; + break; + case TextureType::T_CUBE: + header.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + header.arraySize = 6; + header.miscFlag |= DDS_RESOURCE_MISC_TEXTURECUBE; + break; + case TextureType::T_3D: + header.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; + header.arraySize = 1; + break; + } + } + + void ConvertTextureIfNecessary() + { + const auto entry = DDS_CONVERSION_TABLE.find(m_texture->GetFormat()->GetId()); + + if (entry != DDS_CONVERSION_TABLE.end()) + { + TextureConverter converter(m_texture, ImageFormat::ALL_FORMATS[static_cast(entry->second)]); + m_converted_texture = converter.Convert(); + m_texture = m_converted_texture.get(); + } + } + + std::ostream& m_stream; + const Texture* m_texture; + std::unique_ptr m_converted_texture; + bool m_use_dx10_extension; + }; +} // namespace + +namespace image { - return DdsWriterInternal::SupportsImageFormat(imageFormat); -} + DdsWriter::~DdsWriter() = default; -std::string DdsWriter::GetFileExtension() -{ - return DdsWriterInternal::GetFileExtension(); -} + bool DdsWriter::SupportsImageFormat(const ImageFormat* imageFormat) + { + return DdsWriterInternal::SupportsImageFormat(imageFormat); + } -void DdsWriter::DumpImage(std::ostream& stream, const Texture* texture) -{ - DdsWriterInternal internal(stream, texture); - internal.DumpImage(); -} + std::string DdsWriter::GetFileExtension() + { + return DdsWriterInternal::GetFileExtension(); + } + + void DdsWriter::DumpImage(std::ostream& stream, const Texture* texture) + { + DdsWriterInternal internal(stream, texture); + internal.DumpImage(); + } +} // namespace image diff --git a/src/ObjImage/Image/DdsWriter.h b/src/ObjImage/Image/DdsWriter.h index c6acbab4..771d4842 100644 --- a/src/ObjImage/Image/DdsWriter.h +++ b/src/ObjImage/Image/DdsWriter.h @@ -1,12 +1,16 @@ #pragma once -#include "IImageWriter.h" -class DdsWriter final : public IImageWriter +#include "ImageWriter.h" + +namespace image { -public: - ~DdsWriter() override; + class DdsWriter final : public ImageWriter + { + public: + ~DdsWriter() override; - bool SupportsImageFormat(const ImageFormat* imageFormat) override; - std::string GetFileExtension() override; - void DumpImage(std::ostream& stream, const Texture* texture) override; -}; + bool SupportsImageFormat(const ImageFormat* imageFormat) override; + std::string GetFileExtension() override; + void DumpImage(std::ostream& stream, const Texture* texture) override; + }; +} // namespace image diff --git a/src/ObjImage/Image/Dx12TextureLoader.cpp b/src/ObjImage/Image/Dx12TextureLoader.cpp index 4e1fe3c0..85b5d6fc 100644 --- a/src/ObjImage/Image/Dx12TextureLoader.cpp +++ b/src/ObjImage/Image/Dx12TextureLoader.cpp @@ -2,103 +2,106 @@ #include -Dx12TextureLoader::Dx12TextureLoader() - : m_format(oat::DXGI_FORMAT_UNKNOWN), - m_type(TextureType::T_2D), - m_has_mip_maps(false), - m_width(1u), - m_height(1u), - m_depth(1u) +namespace image { -} - -const ImageFormat* Dx12TextureLoader::GetFormatForDx12Format() const -{ - for (const auto* i : ImageFormat::ALL_FORMATS) + Dx12TextureLoader::Dx12TextureLoader() + : m_format(oat::DXGI_FORMAT_UNKNOWN), + m_type(TextureType::T_2D), + m_has_mip_maps(false), + m_width(1u), + m_height(1u), + m_depth(1u) { - if (i->GetDxgiFormat() == m_format) - return i; } - return nullptr; -} - -Dx12TextureLoader& Dx12TextureLoader::Format(const oat::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 unsigned width) -{ - m_width = width; - return *this; -} - -Dx12TextureLoader& Dx12TextureLoader::Height(const unsigned height) -{ - m_height = height; - return *this; -} - -Dx12TextureLoader& Dx12TextureLoader::Depth(const unsigned depth) -{ - m_depth = depth; - return *this; -} - -std::unique_ptr Dx12TextureLoader::LoadTexture(const void* data) -{ - const auto* format = GetFormatForDx12Format(); - - if (format == nullptr) - return nullptr; - - std::unique_ptr texture; - switch (m_type) + const ImageFormat* Dx12TextureLoader::GetFormatForDx12Format() const { - case TextureType::T_2D: - texture = std::make_unique(format, m_width, m_height, m_has_mip_maps); - break; - - case TextureType::T_3D: - texture = std::make_unique(format, m_width, m_height, m_depth, m_has_mip_maps); - break; - - case TextureType::T_CUBE: - texture = std::make_unique(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++) + for (const auto* i : ImageFormat::ALL_FORMATS) { - const auto mipSize = texture->GetSizeOfMipLevel(currentMipLevel); - memcpy(texture->GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize); - currentDataOffset = reinterpret_cast(reinterpret_cast(currentDataOffset) + mipSize); + if (i->GetDxgiFormat() == m_format) + return i; } + + return nullptr; } - return texture; -} + Dx12TextureLoader& Dx12TextureLoader::Format(const oat::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 unsigned width) + { + m_width = width; + return *this; + } + + Dx12TextureLoader& Dx12TextureLoader::Height(const unsigned height) + { + m_height = height; + return *this; + } + + Dx12TextureLoader& Dx12TextureLoader::Depth(const unsigned depth) + { + m_depth = depth; + return *this; + } + + std::unique_ptr Dx12TextureLoader::LoadTexture(const void* data) + { + const auto* format = GetFormatForDx12Format(); + + if (format == nullptr) + return nullptr; + + std::unique_ptr texture; + switch (m_type) + { + case TextureType::T_2D: + texture = std::make_unique(format, m_width, m_height, m_has_mip_maps); + break; + + case TextureType::T_3D: + texture = std::make_unique(format, m_width, m_height, m_depth, m_has_mip_maps); + break; + + case TextureType::T_CUBE: + texture = std::make_unique(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; + } +} // namespace image diff --git a/src/ObjImage/Image/Dx12TextureLoader.h b/src/ObjImage/Image/Dx12TextureLoader.h index 128d2b69..c5ad4174 100644 --- a/src/ObjImage/Image/Dx12TextureLoader.h +++ b/src/ObjImage/Image/Dx12TextureLoader.h @@ -6,29 +6,32 @@ #include #include -class Dx12TextureLoader +namespace image { -public: - Dx12TextureLoader(); + class Dx12TextureLoader + { + public: + Dx12TextureLoader(); - Dx12TextureLoader& Format(oat::DXGI_FORMAT format); - Dx12TextureLoader& Type(TextureType textureType); - Dx12TextureLoader& HasMipMaps(bool hasMipMaps); - Dx12TextureLoader& Width(unsigned width); - Dx12TextureLoader& Height(unsigned height); - Dx12TextureLoader& Depth(unsigned depth); + Dx12TextureLoader& Format(oat::DXGI_FORMAT format); + Dx12TextureLoader& Type(TextureType textureType); + Dx12TextureLoader& HasMipMaps(bool hasMipMaps); + Dx12TextureLoader& Width(unsigned width); + Dx12TextureLoader& Height(unsigned height); + Dx12TextureLoader& Depth(unsigned depth); - std::unique_ptr LoadTexture(const void* data); + std::unique_ptr LoadTexture(const void* data); -private: - [[nodiscard]] const ImageFormat* GetFormatForDx12Format() const; + private: + [[nodiscard]] const ImageFormat* GetFormatForDx12Format() const; - static std::unordered_map m_conversion_table; + static std::unordered_map m_conversion_table; - oat::DXGI_FORMAT m_format; - TextureType m_type; - bool m_has_mip_maps; - unsigned m_width; - unsigned m_height; - unsigned m_depth; -}; + oat::DXGI_FORMAT m_format; + TextureType m_type; + bool m_has_mip_maps; + unsigned m_width; + unsigned m_height; + unsigned m_depth; + }; +} // namespace image diff --git a/src/ObjImage/Image/Dx9TextureLoader.cpp b/src/ObjImage/Image/Dx9TextureLoader.cpp index 9d319bd0..a4f0645e 100644 --- a/src/ObjImage/Image/Dx9TextureLoader.cpp +++ b/src/ObjImage/Image/Dx9TextureLoader.cpp @@ -2,103 +2,106 @@ #include -Dx9TextureLoader::Dx9TextureLoader() - : m_format(oat::D3DFMT_UNKNOWN), - m_type(TextureType::T_2D), - m_has_mip_maps(false), - m_width(1u), - m_height(1u), - m_depth(1u) +namespace image { -} - -const ImageFormat* Dx9TextureLoader::GetFormatForDx9Format() const -{ - for (const auto* i : ImageFormat::ALL_FORMATS) + Dx9TextureLoader::Dx9TextureLoader() + : m_format(oat::D3DFMT_UNKNOWN), + m_type(TextureType::T_2D), + m_has_mip_maps(false), + m_width(1u), + m_height(1u), + m_depth(1u) { - if (i->GetD3DFormat() == m_format) - return i; } - return nullptr; -} - -Dx9TextureLoader& Dx9TextureLoader::Format(const oat::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 unsigned width) -{ - m_width = width; - return *this; -} - -Dx9TextureLoader& Dx9TextureLoader::Height(const unsigned height) -{ - m_height = height; - return *this; -} - -Dx9TextureLoader& Dx9TextureLoader::Depth(const unsigned depth) -{ - m_depth = depth; - return *this; -} - -std::unique_ptr Dx9TextureLoader::LoadTexture(const void* data) -{ - const auto* format = GetFormatForDx9Format(); - - if (format == nullptr) - return nullptr; - - std::unique_ptr texture; - switch (m_type) + const ImageFormat* Dx9TextureLoader::GetFormatForDx9Format() const { - case TextureType::T_2D: - texture = std::make_unique(format, m_width, m_height, m_has_mip_maps); - break; - - case TextureType::T_3D: - texture = std::make_unique(format, m_width, m_height, m_depth, m_has_mip_maps); - break; - - case TextureType::T_CUBE: - texture = std::make_unique(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++) + for (const auto* i : ImageFormat::ALL_FORMATS) { - const auto mipSize = texture->GetSizeOfMipLevel(currentMipLevel); - memcpy(texture->GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize); - currentDataOffset = reinterpret_cast(reinterpret_cast(currentDataOffset) + mipSize); + if (i->GetD3DFormat() == m_format) + return i; } + + return nullptr; } - return texture; -} + Dx9TextureLoader& Dx9TextureLoader::Format(const oat::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 unsigned width) + { + m_width = width; + return *this; + } + + Dx9TextureLoader& Dx9TextureLoader::Height(const unsigned height) + { + m_height = height; + return *this; + } + + Dx9TextureLoader& Dx9TextureLoader::Depth(const unsigned depth) + { + m_depth = depth; + return *this; + } + + std::unique_ptr Dx9TextureLoader::LoadTexture(const void* data) + { + const auto* format = GetFormatForDx9Format(); + + if (format == nullptr) + return nullptr; + + std::unique_ptr texture; + switch (m_type) + { + case TextureType::T_2D: + texture = std::make_unique(format, m_width, m_height, m_has_mip_maps); + break; + + case TextureType::T_3D: + texture = std::make_unique(format, m_width, m_height, m_depth, m_has_mip_maps); + break; + + case TextureType::T_CUBE: + texture = std::make_unique(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; + } +} // namespace image diff --git a/src/ObjImage/Image/Dx9TextureLoader.h b/src/ObjImage/Image/Dx9TextureLoader.h index 212714d4..48ff5e5c 100644 --- a/src/ObjImage/Image/Dx9TextureLoader.h +++ b/src/ObjImage/Image/Dx9TextureLoader.h @@ -5,27 +5,30 @@ #include -class Dx9TextureLoader +namespace image { -public: - Dx9TextureLoader(); + class Dx9TextureLoader + { + public: + Dx9TextureLoader(); - Dx9TextureLoader& Format(oat::D3DFORMAT format); - Dx9TextureLoader& Type(TextureType textureType); - Dx9TextureLoader& HasMipMaps(bool hasMipMaps); - Dx9TextureLoader& Width(unsigned width); - Dx9TextureLoader& Height(unsigned height); - Dx9TextureLoader& Depth(unsigned depth); + Dx9TextureLoader& Format(oat::D3DFORMAT format); + Dx9TextureLoader& Type(TextureType textureType); + Dx9TextureLoader& HasMipMaps(bool hasMipMaps); + Dx9TextureLoader& Width(unsigned width); + Dx9TextureLoader& Height(unsigned height); + Dx9TextureLoader& Depth(unsigned depth); - std::unique_ptr LoadTexture(const void* data); + std::unique_ptr LoadTexture(const void* data); -private: - [[nodiscard]] const ImageFormat* GetFormatForDx9Format() const; + private: + [[nodiscard]] const ImageFormat* GetFormatForDx9Format() const; - oat::D3DFORMAT m_format; - TextureType m_type; - bool m_has_mip_maps; - unsigned m_width; - unsigned m_height; - unsigned m_depth; -}; + oat::D3DFORMAT m_format; + TextureType m_type; + bool m_has_mip_maps; + unsigned m_width; + unsigned m_height; + unsigned m_depth; + }; +} // namespace image diff --git a/src/ObjImage/Image/IImageWriter.h b/src/ObjImage/Image/IImageWriter.h deleted file mode 100644 index ed116416..00000000 --- a/src/ObjImage/Image/IImageWriter.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "Image/Texture.h" - -#include -#include - -class IImageWriter -{ -public: - IImageWriter() = default; - virtual ~IImageWriter() = default; - IImageWriter(const IImageWriter& other) = default; - IImageWriter(IImageWriter&& other) noexcept = default; - IImageWriter& operator=(const IImageWriter& other) = default; - IImageWriter& operator=(IImageWriter&& other) noexcept = default; - - virtual bool SupportsImageFormat(const ImageFormat* imageFormat) = 0; - virtual std::string GetFileExtension() = 0; - virtual void DumpImage(std::ostream& stream, const Texture* texture) = 0; -}; diff --git a/src/ObjImage/Image/ImageFormat.cpp b/src/ObjImage/Image/ImageFormat.cpp index 7581d972..6f2ace41 100644 --- a/src/ObjImage/Image/ImageFormat.cpp +++ b/src/ObjImage/Image/ImageFormat.cpp @@ -1,175 +1,178 @@ #include "ImageFormat.h" -ImageFormat::ImageFormat(const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat) - : m_id(id), - m_d3d_format(d3dFormat), - m_dxgi_format(dxgiFormat) +namespace image { -} + ImageFormat::ImageFormat(const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat) + : m_id(id), + m_d3d_format(d3dFormat), + m_dxgi_format(dxgiFormat) + { + } -ImageFormatId ImageFormat::GetId() const -{ - return m_id; -} + ImageFormatId ImageFormat::GetId() const + { + return m_id; + } -oat::D3DFORMAT ImageFormat::GetD3DFormat() const -{ - return m_d3d_format; -} + oat::D3DFORMAT ImageFormat::GetD3DFormat() const + { + return m_d3d_format; + } -oat::DXGI_FORMAT ImageFormat::GetDxgiFormat() const -{ - return m_dxgi_format; -} + oat::DXGI_FORMAT ImageFormat::GetDxgiFormat() const + { + return m_dxgi_format; + } -ImageFormatUnsigned::ImageFormatUnsigned(const ImageFormatId id, - const oat::D3DFORMAT d3dFormat, - const oat::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, d3dFormat, dxgiFormat), - m_bits_per_pixel(bitsPerPixel), - m_r_offset(rOffset), - m_r_size(rSize), - m_g_offset(gOffset), - m_g_size(gSize), - m_b_offset(bOffset), - m_b_size(bSize), - m_a_offset(aOffset), - m_a_size(aSize) -{ -} + ImageFormatUnsigned::ImageFormatUnsigned(const ImageFormatId id, + const oat::D3DFORMAT d3dFormat, + const oat::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, d3dFormat, dxgiFormat), + m_bits_per_pixel(bitsPerPixel), + m_r_offset(rOffset), + m_r_size(rSize), + m_g_offset(gOffset), + m_g_size(gSize), + m_b_offset(bOffset), + m_b_size(bSize), + m_a_offset(aOffset), + m_a_size(aSize) + { + } -ImageFormatType ImageFormatUnsigned::GetType() const -{ - return ImageFormatType::UNSIGNED; -} + ImageFormatType ImageFormatUnsigned::GetType() const + { + return ImageFormatType::UNSIGNED; + } -size_t ImageFormatUnsigned::GetPitch(const unsigned mipLevel, const unsigned width) const -{ - unsigned mipWidth = width >> mipLevel; - if (mipWidth == 0) - mipWidth = 1; + size_t ImageFormatUnsigned::GetPitch(const unsigned mipLevel, const unsigned width) const + { + unsigned mipWidth = width >> mipLevel; + if (mipWidth == 0) + mipWidth = 1; - return mipWidth * m_bits_per_pixel / 8; -} + return mipWidth * m_bits_per_pixel / 8; + } -size_t ImageFormatUnsigned::GetSizeOfMipLevel(const unsigned mipLevel, const unsigned width, const unsigned height, const unsigned depth) const -{ - unsigned mipWidth = width >> mipLevel; - unsigned mipHeight = height >> mipLevel; - unsigned mipDepth = depth >> mipLevel; + size_t ImageFormatUnsigned::GetSizeOfMipLevel(const unsigned mipLevel, const unsigned width, const unsigned height, const unsigned depth) const + { + unsigned mipWidth = width >> mipLevel; + unsigned mipHeight = height >> mipLevel; + unsigned mipDepth = depth >> mipLevel; - if (mipWidth == 0) - mipWidth = 1; - if (mipHeight == 0) - mipHeight = 1; - if (mipDepth == 0) - mipDepth = 1; + if (mipWidth == 0) + mipWidth = 1; + if (mipHeight == 0) + mipHeight = 1; + if (mipDepth == 0) + mipDepth = 1; - return mipWidth * mipHeight * mipDepth * m_bits_per_pixel / 8; -} + return mipWidth * mipHeight * mipDepth * m_bits_per_pixel / 8; + } -ImageFormatBlockCompressed::ImageFormatBlockCompressed( - const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat, const unsigned blockSize, const unsigned bitsPerBlock) - : ImageFormat(id, d3dFormat, dxgiFormat), - m_block_size(blockSize), - m_bits_per_block(bitsPerBlock) -{ -} + ImageFormatBlockCompressed::ImageFormatBlockCompressed( + const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat, const unsigned blockSize, const unsigned bitsPerBlock) + : ImageFormat(id, d3dFormat, dxgiFormat), + m_block_size(blockSize), + m_bits_per_block(bitsPerBlock) + { + } -ImageFormatType ImageFormatBlockCompressed::GetType() const -{ - return ImageFormatType::BLOCK_COMPRESSED; -} + ImageFormatType ImageFormatBlockCompressed::GetType() const + { + return ImageFormatType::BLOCK_COMPRESSED; + } -size_t ImageFormatBlockCompressed::GetPitch(const unsigned mipLevel, const unsigned width) const -{ - unsigned mipWidth = width >> mipLevel; + size_t ImageFormatBlockCompressed::GetPitch(const unsigned mipLevel, const unsigned width) const + { + unsigned mipWidth = width >> mipLevel; - if (mipWidth == 0) - mipWidth = 1; + if (mipWidth == 0) + mipWidth = 1; - const unsigned blockCount = (mipWidth + m_block_size - 1) / m_block_size; + const unsigned blockCount = (mipWidth + m_block_size - 1) / m_block_size; - return blockCount * m_bits_per_block / 8; -} + return blockCount * m_bits_per_block / 8; + } -size_t ImageFormatBlockCompressed::GetSizeOfMipLevel(const unsigned mipLevel, const unsigned width, const unsigned height, const unsigned depth) const -{ - unsigned mipWidth = width >> mipLevel; - unsigned mipHeight = height >> mipLevel; - unsigned mipDepth = depth >> mipLevel; + size_t ImageFormatBlockCompressed::GetSizeOfMipLevel(const unsigned mipLevel, const unsigned width, const unsigned height, const unsigned depth) const + { + unsigned mipWidth = width >> mipLevel; + unsigned mipHeight = height >> mipLevel; + unsigned mipDepth = depth >> mipLevel; - if (mipWidth == 0) - mipWidth = 1; - if (mipHeight == 0) - mipHeight = 1; - if (mipDepth == 0) - mipDepth = 1; + if (mipWidth == 0) + mipWidth = 1; + if (mipHeight == 0) + mipHeight = 1; + if (mipDepth == 0) + mipDepth = 1; - const unsigned blockCount = ((mipWidth + m_block_size - 1) / m_block_size) * ((mipHeight + m_block_size - 1) / m_block_size) * mipDepth; + const unsigned blockCount = ((mipWidth + m_block_size - 1) / m_block_size) * ((mipHeight + m_block_size - 1) / m_block_size) * mipDepth; - return blockCount * m_bits_per_block / 8; -} + return blockCount * m_bits_per_block / 8; + } -bool ImageFormatUnsigned::HasR() const -{ - return m_r_size > 0; -} + bool ImageFormatUnsigned::HasR() const + { + return m_r_size > 0; + } -bool ImageFormatUnsigned::HasG() const -{ - return m_g_size > 0; -} + bool ImageFormatUnsigned::HasG() const + { + return m_g_size > 0; + } -bool ImageFormatUnsigned::HasB() const -{ - return m_b_size > 0; -} + bool ImageFormatUnsigned::HasB() const + { + return m_b_size > 0; + } -bool ImageFormatUnsigned::HasA() const -{ - return m_a_size > 0; -} + bool ImageFormatUnsigned::HasA() const + { + return m_a_size > 0; + } -const ImageFormatUnsigned ImageFormat::FORMAT_R8_G8_B8(ImageFormatId::R8_G8_B8, oat::D3DFMT_R8G8B8, oat::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, oat::D3DFMT_X8R8G8B8, oat::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, oat::D3DFMT_A8B8G8R8, oat::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, oat::D3DFMT_A8R8G8B8, oat::DXGI_FORMAT_B8G8R8A8_UNORM, 32, 16, 8, 8, 8, 0, 8, 24, 8); -const ImageFormatUnsigned ImageFormat::FORMAT_A8(ImageFormatId::A8, oat::D3DFMT_A8, oat::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, oat::D3DFMT_A16B16G16R16F, oat::DXGI_FORMAT_R16G16B16A16_FLOAT, 128, 0, 0, 0, 0, 0, 0, 0, 8); -const ImageFormatUnsigned ImageFormat::FORMAT_R8(ImageFormatId::R8, oat::D3DFMT_L8, oat::DXGI_FORMAT_R8_UNORM, 8, 0, 8, 0, 0, 0, 0, 0, 0); -const ImageFormatUnsigned ImageFormat::FORMAT_R8_A8(ImageFormatId::R8_A8, oat::D3DFMT_A8L8, oat::DXGI_FORMAT_UNKNOWN, 16, 0, 8, 0, 0, 0, 0, 8, 8); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC1(ImageFormatId::BC1, oat::D3DFMT_DXT1, oat::DXGI_FORMAT_BC1_UNORM, 4, 64); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC2(ImageFormatId::BC2, oat::D3DFMT_DXT3, oat::DXGI_FORMAT_BC2_UNORM, 4, 128); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC3(ImageFormatId::BC3, oat::D3DFMT_DXT5, oat::DXGI_FORMAT_BC3_UNORM, 4, 128); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC4(ImageFormatId::BC4, oat::D3DFMT_UNKNOWN, oat::DXGI_FORMAT_BC4_UNORM, 4, 64); -const ImageFormatBlockCompressed ImageFormat::FORMAT_BC5(ImageFormatId::BC5, oat::D3DFMT_UNKNOWN, oat::DXGI_FORMAT_BC5_UNORM, 4, 128); + const ImageFormatUnsigned ImageFormat::FORMAT_R8_G8_B8(ImageFormatId::R8_G8_B8, oat::D3DFMT_R8G8B8, oat::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, oat::D3DFMT_X8R8G8B8, oat::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, oat::D3DFMT_A8B8G8R8, oat::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, oat::D3DFMT_A8R8G8B8, oat::DXGI_FORMAT_B8G8R8A8_UNORM, 32, 16, 8, 8, 8, 0, 8, 24, 8); + const ImageFormatUnsigned ImageFormat::FORMAT_A8(ImageFormatId::A8, oat::D3DFMT_A8, oat::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, oat::D3DFMT_A16B16G16R16F, oat::DXGI_FORMAT_R16G16B16A16_FLOAT, 128, 0, 0, 0, 0, 0, 0, 0, 8); + const ImageFormatUnsigned ImageFormat::FORMAT_R8(ImageFormatId::R8, oat::D3DFMT_L8, oat::DXGI_FORMAT_R8_UNORM, 8, 0, 8, 0, 0, 0, 0, 0, 0); + const ImageFormatUnsigned ImageFormat::FORMAT_R8_A8(ImageFormatId::R8_A8, oat::D3DFMT_A8L8, oat::DXGI_FORMAT_UNKNOWN, 16, 0, 8, 0, 0, 0, 0, 8, 8); + const ImageFormatBlockCompressed ImageFormat::FORMAT_BC1(ImageFormatId::BC1, oat::D3DFMT_DXT1, oat::DXGI_FORMAT_BC1_UNORM, 4, 64); + const ImageFormatBlockCompressed ImageFormat::FORMAT_BC2(ImageFormatId::BC2, oat::D3DFMT_DXT3, oat::DXGI_FORMAT_BC2_UNORM, 4, 128); + const ImageFormatBlockCompressed ImageFormat::FORMAT_BC3(ImageFormatId::BC3, oat::D3DFMT_DXT5, oat::DXGI_FORMAT_BC3_UNORM, 4, 128); + const ImageFormatBlockCompressed ImageFormat::FORMAT_BC4(ImageFormatId::BC4, oat::D3DFMT_UNKNOWN, oat::DXGI_FORMAT_BC4_UNORM, 4, 64); + const ImageFormatBlockCompressed ImageFormat::FORMAT_BC5(ImageFormatId::BC5, oat::D3DFMT_UNKNOWN, oat::DXGI_FORMAT_BC5_UNORM, 4, 128); -const ImageFormat* const ImageFormat::ALL_FORMATS[static_cast(ImageFormatId::MAX)]{ - &FORMAT_R8_G8_B8, - &FORMAT_B8_G8_R8_X8, - &FORMAT_R8_G8_B8_A8, - &FORMAT_B8_G8_R8_A8, - &FORMAT_A8, - &FORMAT_R16_G16_B16_A16_FLOAT, - &FORMAT_R8, - &FORMAT_R8_A8, - &FORMAT_BC1, - &FORMAT_BC2, - &FORMAT_BC3, - &FORMAT_BC4, - &FORMAT_BC5, -}; + const ImageFormat* const ImageFormat::ALL_FORMATS[static_cast(ImageFormatId::MAX)]{ + &FORMAT_R8_G8_B8, + &FORMAT_B8_G8_R8_X8, + &FORMAT_R8_G8_B8_A8, + &FORMAT_B8_G8_R8_A8, + &FORMAT_A8, + &FORMAT_R16_G16_B16_A16_FLOAT, + &FORMAT_R8, + &FORMAT_R8_A8, + &FORMAT_BC1, + &FORMAT_BC2, + &FORMAT_BC3, + &FORMAT_BC4, + &FORMAT_BC5, + }; +} // namespace image diff --git a/src/ObjImage/Image/ImageFormat.h b/src/ObjImage/Image/ImageFormat.h index b87f6ac5..57de0b5b 100644 --- a/src/ObjImage/Image/ImageFormat.h +++ b/src/ObjImage/Image/ImageFormat.h @@ -6,117 +6,120 @@ #include #include -enum class ImageFormatId +namespace image { - UNKNOWN = -1, - 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, + enum class ImageFormatId + { + UNKNOWN = -1, + 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, - MAX -}; + MAX + }; -enum class ImageFormatType -{ - UNKNOWN, - UNSIGNED, - BLOCK_COMPRESSED -}; + enum class ImageFormatType + { + UNKNOWN, + UNSIGNED, + BLOCK_COMPRESSED + }; -class ImageFormatUnsigned; -class ImageFormatBlockCompressed; + class ImageFormatUnsigned; + class ImageFormatBlockCompressed; -class ImageFormat -{ - ImageFormatId m_id; - oat::D3DFORMAT m_d3d_format; - oat::DXGI_FORMAT m_dxgi_format; + class ImageFormat + { + ImageFormatId m_id; + oat::D3DFORMAT m_d3d_format; + oat::DXGI_FORMAT m_dxgi_format; -protected: - ImageFormat(ImageFormatId id, oat::D3DFORMAT d3dFormat, oat::DXGI_FORMAT dxgiFormat); + protected: + ImageFormat(ImageFormatId id, oat::D3DFORMAT d3dFormat, oat::DXGI_FORMAT dxgiFormat); -public: - virtual ~ImageFormat() = default; + public: + virtual ~ImageFormat() = default; - [[nodiscard]] ImageFormatId GetId() const; - [[nodiscard]] oat::D3DFORMAT GetD3DFormat() const; - [[nodiscard]] oat::DXGI_FORMAT GetDxgiFormat() const; + [[nodiscard]] ImageFormatId GetId() const; + [[nodiscard]] oat::D3DFORMAT GetD3DFormat() const; + [[nodiscard]] oat::DXGI_FORMAT GetDxgiFormat() const; - [[nodiscard]] virtual ImageFormatType GetType() const = 0; - [[nodiscard]] virtual size_t GetPitch(unsigned mipLevel, unsigned width) const = 0; - [[nodiscard]] virtual size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const = 0; + [[nodiscard]] virtual ImageFormatType GetType() const = 0; + [[nodiscard]] virtual size_t GetPitch(unsigned mipLevel, unsigned width) const = 0; + [[nodiscard]] virtual size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const = 0; - static const ImageFormatUnsigned FORMAT_R8_G8_B8; - static const ImageFormatUnsigned FORMAT_B8_G8_R8_X8; - static const ImageFormatUnsigned FORMAT_R8_G8_B8_A8; - static const ImageFormatUnsigned FORMAT_B8_G8_R8_A8; - static const ImageFormatUnsigned FORMAT_A8; - static const ImageFormatUnsigned FORMAT_R16_G16_B16_A16_FLOAT; // TODO: Float not unsigned - static const ImageFormatUnsigned FORMAT_R8; - static const ImageFormatUnsigned FORMAT_R8_A8; - static const ImageFormatBlockCompressed FORMAT_BC1; - static const ImageFormatBlockCompressed FORMAT_BC2; - static const ImageFormatBlockCompressed FORMAT_BC3; - static const ImageFormatBlockCompressed FORMAT_BC4; - static const ImageFormatBlockCompressed FORMAT_BC5; - static const ImageFormat* const ALL_FORMATS[static_cast(ImageFormatId::MAX)]; -}; + static const ImageFormatUnsigned FORMAT_R8_G8_B8; + static const ImageFormatUnsigned FORMAT_B8_G8_R8_X8; + static const ImageFormatUnsigned FORMAT_R8_G8_B8_A8; + static const ImageFormatUnsigned FORMAT_B8_G8_R8_A8; + static const ImageFormatUnsigned FORMAT_A8; + static const ImageFormatUnsigned FORMAT_R16_G16_B16_A16_FLOAT; // TODO: Float not unsigned + static const ImageFormatUnsigned FORMAT_R8; + static const ImageFormatUnsigned FORMAT_R8_A8; + static const ImageFormatBlockCompressed FORMAT_BC1; + static const ImageFormatBlockCompressed FORMAT_BC2; + static const ImageFormatBlockCompressed FORMAT_BC3; + static const ImageFormatBlockCompressed FORMAT_BC4; + static const ImageFormatBlockCompressed FORMAT_BC5; + static const ImageFormat* const ALL_FORMATS[static_cast(ImageFormatId::MAX)]; + }; -class ImageFormatUnsigned final : public ImageFormat -{ -public: - unsigned m_bits_per_pixel; - unsigned m_r_offset; - unsigned m_r_size; - unsigned m_g_offset; - unsigned m_g_size; - unsigned m_b_offset; - unsigned m_b_size; - unsigned m_a_offset; - unsigned m_a_size; + class ImageFormatUnsigned final : public ImageFormat + { + public: + unsigned m_bits_per_pixel; + unsigned m_r_offset; + unsigned m_r_size; + unsigned m_g_offset; + unsigned m_g_size; + unsigned m_b_offset; + unsigned m_b_size; + unsigned m_a_offset; + unsigned m_a_size; - ImageFormatUnsigned(ImageFormatId id, - oat::D3DFORMAT d3dFormat, - oat::DXGI_FORMAT dxgiFormat, - unsigned bitsPerPixel, - unsigned rOffset, - unsigned rSize, - unsigned gOffset, - unsigned gSize, - unsigned bOffset, - unsigned bSize, - unsigned aOffset, - unsigned aSize); + ImageFormatUnsigned(ImageFormatId id, + oat::D3DFORMAT d3dFormat, + oat::DXGI_FORMAT dxgiFormat, + unsigned bitsPerPixel, + unsigned rOffset, + unsigned rSize, + unsigned gOffset, + unsigned gSize, + unsigned bOffset, + unsigned bSize, + unsigned aOffset, + unsigned aSize); - [[nodiscard]] ImageFormatType GetType() const override; - [[nodiscard]] size_t GetPitch(unsigned mipLevel, unsigned width) const override; - [[nodiscard]] size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const override; + [[nodiscard]] ImageFormatType GetType() const override; + [[nodiscard]] size_t GetPitch(unsigned mipLevel, unsigned width) const override; + [[nodiscard]] size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const override; - [[nodiscard]] bool HasR() const; - [[nodiscard]] bool HasG() const; - [[nodiscard]] bool HasB() const; - [[nodiscard]] bool HasA() const; -}; + [[nodiscard]] bool HasR() const; + [[nodiscard]] bool HasG() const; + [[nodiscard]] bool HasB() const; + [[nodiscard]] bool HasA() const; + }; -class ImageFormatBlockCompressed final : public ImageFormat -{ -public: - unsigned m_block_size; - unsigned m_bits_per_block; + class ImageFormatBlockCompressed final : public ImageFormat + { + public: + unsigned m_block_size; + unsigned m_bits_per_block; - ImageFormatBlockCompressed(ImageFormatId id, oat::D3DFORMAT d3dFormat, oat::DXGI_FORMAT dxgiFormat, unsigned blockSize, unsigned bitsPerBlock); + ImageFormatBlockCompressed(ImageFormatId id, oat::D3DFORMAT d3dFormat, oat::DXGI_FORMAT dxgiFormat, unsigned blockSize, unsigned bitsPerBlock); - [[nodiscard]] ImageFormatType GetType() const override; - [[nodiscard]] size_t GetPitch(unsigned mipLevel, unsigned width) const override; - [[nodiscard]] size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const override; -}; + [[nodiscard]] ImageFormatType GetType() const override; + [[nodiscard]] size_t GetPitch(unsigned mipLevel, unsigned width) const override; + [[nodiscard]] size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const override; + }; +} // namespace image diff --git a/src/ObjImage/Image/ImageWriter.h b/src/ObjImage/Image/ImageWriter.h new file mode 100644 index 00000000..4ab90250 --- /dev/null +++ b/src/ObjImage/Image/ImageWriter.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Image/Texture.h" + +#include +#include + +namespace image +{ + class ImageWriter + { + public: + ImageWriter() = default; + virtual ~ImageWriter() = default; + ImageWriter(const ImageWriter& other) = default; + ImageWriter(ImageWriter&& other) noexcept = default; + ImageWriter& operator=(const ImageWriter& other) = default; + ImageWriter& operator=(ImageWriter&& other) noexcept = default; + + virtual bool SupportsImageFormat(const ImageFormat* imageFormat) = 0; + virtual std::string GetFileExtension() = 0; + virtual void DumpImage(std::ostream& stream, const Texture* texture) = 0; + }; +} // namespace image diff --git a/src/ObjImage/Image/IwiLoader.cpp b/src/ObjImage/Image/IwiLoader.cpp index 4f0e5df5..1893904a 100644 --- a/src/ObjImage/Image/IwiLoader.cpp +++ b/src/ObjImage/Image/IwiLoader.cpp @@ -8,7 +8,9 @@ #include #include -namespace iwi +using namespace image; + +namespace { const ImageFormat* GetFormat6(int8_t format) { @@ -74,7 +76,7 @@ namespace iwi texture->Allocate(); - auto currentFileSize = sizeof(iwi6::IwiHeader) + sizeof(IwiVersion); + auto currentFileSize = sizeof(iwi6::IwiHeader) + sizeof(IwiVersionHeader); const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--) @@ -188,7 +190,7 @@ namespace iwi texture->Allocate(); - auto currentFileSize = sizeof(iwi8::IwiHeader) + sizeof(IwiVersion); + auto currentFileSize = sizeof(iwi8::IwiHeader) + sizeof(IwiVersionHeader); const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--) @@ -283,7 +285,7 @@ namespace iwi texture->Allocate(); - auto currentFileSize = sizeof(iwi13::IwiHeader) + sizeof(IwiVersion); + auto currentFileSize = sizeof(iwi13::IwiHeader) + sizeof(IwiVersionHeader); const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--) @@ -380,7 +382,7 @@ namespace iwi texture->Allocate(); - auto currentFileSize = sizeof(iwi27::IwiHeader) + sizeof(IwiVersion); + auto currentFileSize = sizeof(iwi27::IwiHeader) + sizeof(IwiVersionHeader); const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--) @@ -405,22 +407,25 @@ namespace iwi return texture; } +} // namespace +namespace image +{ std::unique_ptr LoadIwi(std::istream& stream) { - IwiVersion iwiVersion{}; + IwiVersionHeader iwiVersionHeader{}; - stream.read(reinterpret_cast(&iwiVersion), sizeof(iwiVersion)); - if (stream.gcount() != sizeof(iwiVersion)) + stream.read(reinterpret_cast(&iwiVersionHeader), sizeof(iwiVersionHeader)); + if (stream.gcount() != sizeof(iwiVersionHeader)) return nullptr; - if (iwiVersion.tag[0] != 'I' || iwiVersion.tag[1] != 'W' || iwiVersion.tag[2] != 'i') + if (iwiVersionHeader.tag[0] != 'I' || iwiVersionHeader.tag[1] != 'W' || iwiVersionHeader.tag[2] != 'i') { con::error("Invalid IWI magic"); return nullptr; } - switch (iwiVersion.version) + switch (iwiVersionHeader.version) { case 6: return LoadIwi6(stream); @@ -438,7 +443,7 @@ namespace iwi break; } - con::error("Unknown IWI version {}", iwiVersion.version); + con::error("Unknown IWI version {}", iwiVersionHeader.version); return nullptr; } -} // namespace iwi +} // namespace image diff --git a/src/ObjImage/Image/IwiLoader.h b/src/ObjImage/Image/IwiLoader.h index a1f65c65..29aaeb61 100644 --- a/src/ObjImage/Image/IwiLoader.h +++ b/src/ObjImage/Image/IwiLoader.h @@ -5,7 +5,7 @@ #include #include -namespace iwi +namespace image { std::unique_ptr LoadIwi(std::istream& stream); -}; // namespace iwi +}; // namespace image diff --git a/src/ObjImage/Image/IwiTypes.h b/src/ObjImage/Image/IwiTypes.h index 545861ca..37eb04e9 100644 --- a/src/ObjImage/Image/IwiTypes.h +++ b/src/ObjImage/Image/IwiTypes.h @@ -2,234 +2,245 @@ #include -struct IwiVersion +namespace image { - char tag[3]; - char version; -}; - -// IW3 -namespace iwi6 -{ - struct IwiHeader + enum class IwiVersion : std::uint8_t { - int8_t format; - int8_t flags; - uint16_t dimensions[3]; - uint32_t fileSizeForPicmip[4]; + // IW3 + IWI_6 = 6, + // IW4, IW5 + IWI_8 = 8, + // T5 + IWI_13 = 13, + // T6 + IWI_27 = 27 }; - enum class IwiFormat + struct IwiVersionHeader { - IMG_FORMAT_INVALID = 0x0, - IMG_FORMAT_BITMAP_RGBA = 0x1, - IMG_FORMAT_BITMAP_RGB = 0x2, - IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, - IMG_FORMAT_BITMAP_LUMINANCE = 0x4, - IMG_FORMAT_BITMAP_ALPHA = 0x5, - IMG_FORMAT_WAVELET_RGBA = 0x6, - IMG_FORMAT_WAVELET_RGB = 0x7, - IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, - IMG_FORMAT_WAVELET_LUMINANCE = 0x9, - IMG_FORMAT_WAVELET_ALPHA = 0xA, - IMG_FORMAT_DXT1 = 0xB, - IMG_FORMAT_DXT3 = 0xC, - IMG_FORMAT_DXT5 = 0xD, - IMG_FORMAT_DXN = 0xE, - - IMG_FORMAT_COUNT + char tag[3]; + char version; }; - enum IwiFlags + namespace iwi6 { - IMG_FLAG_NOPICMIP = 1 << 0, - IMG_FLAG_NOMIPMAPS = 1 << 1, - IMG_FLAG_CUBEMAP = 1 << 2, - IMG_FLAG_VOLMAP = 1 << 3, - IMG_FLAG_STREAMING = 1 << 4, - IMG_FLAG_LEGACY_NORMALS = 1 << 5, - IMG_FLAG_CLAMP_U = 1 << 6, - IMG_FLAG_CLAMP_V = 1 << 7, - IMG_FLAG_DYNAMIC = 1 << 16, - IMG_FLAG_RENDER_TARGET = 1 << 17, - IMG_FLAG_SYSTEMMEM = 1 << 18 - }; -} // namespace iwi6 + struct IwiHeader + { + int8_t format; + int8_t flags; + uint16_t dimensions[3]; + uint32_t fileSizeForPicmip[4]; + }; -// IW4 -namespace iwi8 -{ - struct IwiHeader + enum class IwiFormat + { + IMG_FORMAT_INVALID = 0x0, + IMG_FORMAT_BITMAP_RGBA = 0x1, + IMG_FORMAT_BITMAP_RGB = 0x2, + IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, + IMG_FORMAT_BITMAP_LUMINANCE = 0x4, + IMG_FORMAT_BITMAP_ALPHA = 0x5, + IMG_FORMAT_WAVELET_RGBA = 0x6, + IMG_FORMAT_WAVELET_RGB = 0x7, + IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, + IMG_FORMAT_WAVELET_LUMINANCE = 0x9, + IMG_FORMAT_WAVELET_ALPHA = 0xA, + IMG_FORMAT_DXT1 = 0xB, + IMG_FORMAT_DXT3 = 0xC, + IMG_FORMAT_DXT5 = 0xD, + IMG_FORMAT_DXN = 0xE, + + IMG_FORMAT_COUNT + }; + + enum IwiFlags + { + IMG_FLAG_NOPICMIP = 1 << 0, + IMG_FLAG_NOMIPMAPS = 1 << 1, + IMG_FLAG_CUBEMAP = 1 << 2, + IMG_FLAG_VOLMAP = 1 << 3, + IMG_FLAG_STREAMING = 1 << 4, + IMG_FLAG_LEGACY_NORMALS = 1 << 5, + IMG_FLAG_CLAMP_U = 1 << 6, + IMG_FLAG_CLAMP_V = 1 << 7, + IMG_FLAG_DYNAMIC = 1 << 16, + IMG_FLAG_RENDER_TARGET = 1 << 17, + IMG_FLAG_SYSTEMMEM = 1 << 18 + }; + } // namespace iwi6 + + namespace iwi8 { - uint32_t flags; - int8_t format; - int8_t unused; - uint16_t dimensions[3]; - uint32_t fileSizeForPicmip[4]; - }; + struct IwiHeader + { + uint32_t flags; + int8_t format; + int8_t unused; + uint16_t dimensions[3]; + uint32_t fileSizeForPicmip[4]; + }; - enum class IwiFormat + enum class IwiFormat + { + IMG_FORMAT_INVALID = 0x0, + IMG_FORMAT_BITMAP_RGBA = 0x1, + IMG_FORMAT_BITMAP_RGB = 0x2, + IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, + IMG_FORMAT_BITMAP_LUMINANCE = 0x4, + IMG_FORMAT_BITMAP_ALPHA = 0x5, + IMG_FORMAT_WAVELET_RGBA = 0x6, + IMG_FORMAT_WAVELET_RGB = 0x7, + IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, + IMG_FORMAT_WAVELET_LUMINANCE = 0x9, + IMG_FORMAT_WAVELET_ALPHA = 0xA, + IMG_FORMAT_DXT1 = 0xB, + IMG_FORMAT_DXT3 = 0xC, + IMG_FORMAT_DXT5 = 0xD, + IMG_FORMAT_DXN = 0xE, + IMG_FORMAT_DXT3A_AS_LUMINANCE = 0xF, + IMG_FORMAT_DXT5A_AS_LUMINANCE = 0x10, + IMG_FORMAT_DXT3A_AS_ALPHA = 0x11, + IMG_FORMAT_DXT5A_AS_ALPHA = 0x12, + IMG_FORMAT_DXT1_AS_LUMINANCE_ALPHA = 0x13, + IMG_FORMAT_DXN_AS_LUMINANCE_ALPHA = 0x14, + IMG_FORMAT_DXT1_AS_LUMINANCE = 0x15, + IMG_FORMAT_DXT1_AS_ALPHA = 0x16, + + IMG_FORMAT_COUNT + }; + + enum IwiFlags + { + IMG_FLAG_NOPICMIP = 1 << 0, + IMG_FLAG_NOMIPMAPS = 1 << 1, + IMG_FLAG_STREAMING = 1 << 2, + IMG_FLAG_LEGACY_NORMALS = 1 << 3, + IMG_FLAG_CLAMP_U = 1 << 4, + IMG_FLAG_CLAMP_V = 1 << 5, + IMG_FLAG_ALPHA_WEIGHTED_COLORS = 1 << 6, + IMG_FLAG_DXTC_APPROX_WEIGHTS = 1 << 7, + IMG_FLAG_GAMMA_NONE = 0, + IMG_FLAG_GAMMA_SRGB = 1 << 8, + IMG_FLAG_GAMMA_PWL = 1 << 9, + IMG_FLAG_GAMMA_2 = IMG_FLAG_GAMMA_SRGB | IMG_FLAG_GAMMA_PWL, + IMG_FLAG_MAPTYPE_2D = 0, + IMG_FLAG_MAPTYPE_CUBE = 1 << 16, + IMG_FLAG_MAPTYPE_3D = 1 << 17, + IMG_FLAG_MAPTYPE_1D = IMG_FLAG_MAPTYPE_CUBE | IMG_FLAG_MAPTYPE_3D, + IMG_FLAG_MAPTYPE_MASK = IMG_FLAG_MAPTYPE_2D | IMG_FLAG_MAPTYPE_CUBE | IMG_FLAG_MAPTYPE_3D | IMG_FLAG_MAPTYPE_1D, + IMG_FLAG_NORMALMAP = 1 << 18, + IMG_FLAG_INTENSITY_TO_ALPHA = 1 << 19, + IMG_FLAG_DYNAMIC = 1 << 24, + IMG_FLAG_RENDER_TARGET = 1 << 25, + IMG_FLAG_SYSTEMMEM = 1 << 26 + }; + } // namespace iwi8 + + namespace iwi13 { - IMG_FORMAT_INVALID = 0x0, - IMG_FORMAT_BITMAP_RGBA = 0x1, - IMG_FORMAT_BITMAP_RGB = 0x2, - IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, - IMG_FORMAT_BITMAP_LUMINANCE = 0x4, - IMG_FORMAT_BITMAP_ALPHA = 0x5, - IMG_FORMAT_WAVELET_RGBA = 0x6, - IMG_FORMAT_WAVELET_RGB = 0x7, - IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, - IMG_FORMAT_WAVELET_LUMINANCE = 0x9, - IMG_FORMAT_WAVELET_ALPHA = 0xA, - IMG_FORMAT_DXT1 = 0xB, - IMG_FORMAT_DXT3 = 0xC, - IMG_FORMAT_DXT5 = 0xD, - IMG_FORMAT_DXN = 0xE, - IMG_FORMAT_DXT3A_AS_LUMINANCE = 0xF, - IMG_FORMAT_DXT5A_AS_LUMINANCE = 0x10, - IMG_FORMAT_DXT3A_AS_ALPHA = 0x11, - IMG_FORMAT_DXT5A_AS_ALPHA = 0x12, - IMG_FORMAT_DXT1_AS_LUMINANCE_ALPHA = 0x13, - IMG_FORMAT_DXN_AS_LUMINANCE_ALPHA = 0x14, - IMG_FORMAT_DXT1_AS_LUMINANCE = 0x15, - IMG_FORMAT_DXT1_AS_ALPHA = 0x16, + struct IwiHeader + { + int8_t format; + int8_t flags; + uint16_t dimensions[3]; + float gamma; + uint32_t fileSizeForPicmip[8]; + }; - IMG_FORMAT_COUNT - }; + enum class IwiFormat + { + IMG_FORMAT_INVALID = 0x0, + IMG_FORMAT_BITMAP_RGBA = 0x1, + IMG_FORMAT_BITMAP_RGB = 0x2, + IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, + IMG_FORMAT_BITMAP_LUMINANCE = 0x4, + IMG_FORMAT_BITMAP_ALPHA = 0x5, + IMG_FORMAT_WAVELET_RGBA = 0x6, + IMG_FORMAT_WAVELET_RGB = 0x7, + IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, + IMG_FORMAT_WAVELET_LUMINANCE = 0x9, + IMG_FORMAT_WAVELET_ALPHA = 0xA, + IMG_FORMAT_DXT1 = 0xB, + IMG_FORMAT_DXT3 = 0xC, + IMG_FORMAT_DXT5 = 0xD, + IMG_FORMAT_DXN = 0xE, + IMG_FORMAT_BITMAP_RGB565 = 0xF, + IMG_FORMAT_BITMAP_RGB5A3 = 0x10, + IMG_FORMAT_BITMAP_C8 = 0x11, + IMG_FORMAT_BITMAP_RGBA8 = 0x12, + IMG_FORMAT_A16B16G16R16F = 0x13, + IMG_FORMAT_COUNT = 0x14, + }; - enum IwiFlags + enum IwiFlags + { + IMG_FLAG_NOPICMIP = 1 << 0, + IMG_FLAG_NOMIPMAPS = 1 << 1, + IMG_FLAG_CUBEMAP = 1 << 2, + IMG_FLAG_VOLMAP = 1 << 3, + IMG_FLAG_STREAMING = 1 << 4, + IMG_FLAG_LEGACY_NORMALS = 1 << 5, + IMG_FLAG_CLAMP_U = 1 << 6, + IMG_FLAG_CLAMP_V = 1 << 7, + IMG_FLAG_FORCE_SYSTEM = 1 << 8, + IMG_FLAG_DYNAMIC = 1 << 16, + IMG_FLAG_RENDER_TARGET = 1 << 17, + IMG_FLAG_SYSTEMMEM = 1 << 18, + }; + + } // namespace iwi13 + + namespace iwi27 { - IMG_FLAG_NOPICMIP = 1 << 0, - IMG_FLAG_NOMIPMAPS = 1 << 1, - IMG_FLAG_STREAMING = 1 << 2, - IMG_FLAG_LEGACY_NORMALS = 1 << 3, - IMG_FLAG_CLAMP_U = 1 << 4, - IMG_FLAG_CLAMP_V = 1 << 5, - IMG_FLAG_ALPHA_WEIGHTED_COLORS = 1 << 6, - IMG_FLAG_DXTC_APPROX_WEIGHTS = 1 << 7, - IMG_FLAG_GAMMA_NONE = 0, - IMG_FLAG_GAMMA_SRGB = 1 << 8, - IMG_FLAG_GAMMA_PWL = 1 << 9, - IMG_FLAG_GAMMA_2 = IMG_FLAG_GAMMA_SRGB | IMG_FLAG_GAMMA_PWL, - IMG_FLAG_MAPTYPE_2D = 0, - IMG_FLAG_MAPTYPE_CUBE = 1 << 16, - IMG_FLAG_MAPTYPE_3D = 1 << 17, - IMG_FLAG_MAPTYPE_1D = IMG_FLAG_MAPTYPE_CUBE | IMG_FLAG_MAPTYPE_3D, - IMG_FLAG_MAPTYPE_MASK = IMG_FLAG_MAPTYPE_2D | IMG_FLAG_MAPTYPE_CUBE | IMG_FLAG_MAPTYPE_3D | IMG_FLAG_MAPTYPE_1D, - IMG_FLAG_NORMALMAP = 1 << 18, - IMG_FLAG_INTENSITY_TO_ALPHA = 1 << 19, - IMG_FLAG_DYNAMIC = 1 << 24, - IMG_FLAG_RENDER_TARGET = 1 << 25, - IMG_FLAG_SYSTEMMEM = 1 << 26 - }; -} // namespace iwi8 + struct IwiHeader + { + int8_t format; + int8_t flags; + uint16_t dimensions[3]; + float gamma; + int8_t maxGlossForMip[16]; + uint32_t fileSizeForPicmip[8]; + }; -// T5 -namespace iwi13 -{ - struct IwiHeader - { - int8_t format; - int8_t flags; - uint16_t dimensions[3]; - float gamma; - uint32_t fileSizeForPicmip[8]; - }; + enum class IwiFormat + { + IMG_FORMAT_INVALID = 0x0, + IMG_FORMAT_BITMAP_RGBA = 0x1, + IMG_FORMAT_BITMAP_RGB = 0x2, + IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, + IMG_FORMAT_BITMAP_LUMINANCE = 0x4, + IMG_FORMAT_BITMAP_ALPHA = 0x5, + IMG_FORMAT_WAVELET_RGBA = 0x6, + IMG_FORMAT_WAVELET_RGB = 0x7, + IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, + IMG_FORMAT_WAVELET_LUMINANCE = 0x9, + IMG_FORMAT_WAVELET_ALPHA = 0xA, + IMG_FORMAT_DXT1 = 0xB, + IMG_FORMAT_DXT3 = 0xC, + IMG_FORMAT_DXT5 = 0xD, + IMG_FORMAT_DXN = 0xE, + IMG_FORMAT_BITMAP_RGB565 = 0xF, + IMG_FORMAT_BITMAP_RGB5A3 = 0x10, + IMG_FORMAT_BITMAP_C8 = 0x11, + IMG_FORMAT_BITMAP_RGBA8 = 0x12, + IMG_FORMAT_A16B16G16R16F = 0x13, + IMG_FORMAT_COUNT, + }; - enum class IwiFormat - { - IMG_FORMAT_INVALID = 0x0, - IMG_FORMAT_BITMAP_RGBA = 0x1, - IMG_FORMAT_BITMAP_RGB = 0x2, - IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, - IMG_FORMAT_BITMAP_LUMINANCE = 0x4, - IMG_FORMAT_BITMAP_ALPHA = 0x5, - IMG_FORMAT_WAVELET_RGBA = 0x6, - IMG_FORMAT_WAVELET_RGB = 0x7, - IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, - IMG_FORMAT_WAVELET_LUMINANCE = 0x9, - IMG_FORMAT_WAVELET_ALPHA = 0xA, - IMG_FORMAT_DXT1 = 0xB, - IMG_FORMAT_DXT3 = 0xC, - IMG_FORMAT_DXT5 = 0xD, - IMG_FORMAT_DXN = 0xE, - IMG_FORMAT_BITMAP_RGB565 = 0xF, - IMG_FORMAT_BITMAP_RGB5A3 = 0x10, - IMG_FORMAT_BITMAP_C8 = 0x11, - IMG_FORMAT_BITMAP_RGBA8 = 0x12, - IMG_FORMAT_A16B16G16R16F = 0x13, - IMG_FORMAT_COUNT = 0x14, - }; + enum IwiFlags + { + IMG_FLAG_NOPICMIP = 1 << 0, + IMG_FLAG_NOMIPMAPS = 1 << 1, + IMG_FLAG_CUBEMAP = 1 << 2, + IMG_FLAG_VOLMAP = 1 << 3, + IMG_FLAG_STREAMING = 1 << 4, + IMG_FLAG_CLAMP_U = 1 << 6, + IMG_FLAG_CLAMP_V = 1 << 7, + IMG_FLAG_FORCE_SYSTEM = 1 << 8, + IMG_FLAG_DYNAMIC = 1 << 16, + IMG_FLAG_RENDER_TARGET = 1 << 17, + IMG_FLAG_MULTISAMPLE = 1 << 18, + }; - enum IwiFlags - { - IMG_FLAG_NOPICMIP = 1 << 0, - IMG_FLAG_NOMIPMAPS = 1 << 1, - IMG_FLAG_CUBEMAP = 1 << 2, - IMG_FLAG_VOLMAP = 1 << 3, - IMG_FLAG_STREAMING = 1 << 4, - IMG_FLAG_LEGACY_NORMALS = 1 << 5, - IMG_FLAG_CLAMP_U = 1 << 6, - IMG_FLAG_CLAMP_V = 1 << 7, - IMG_FLAG_FORCE_SYSTEM = 1 << 8, - IMG_FLAG_DYNAMIC = 1 << 16, - IMG_FLAG_RENDER_TARGET = 1 << 17, - IMG_FLAG_SYSTEMMEM = 1 << 18, - }; - -} // namespace iwi13 - -// T6 -namespace iwi27 -{ - struct IwiHeader - { - int8_t format; - int8_t flags; - uint16_t dimensions[3]; - float gamma; - int8_t maxGlossForMip[16]; - uint32_t fileSizeForPicmip[8]; - }; - - enum class IwiFormat - { - IMG_FORMAT_INVALID = 0x0, - IMG_FORMAT_BITMAP_RGBA = 0x1, - IMG_FORMAT_BITMAP_RGB = 0x2, - IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3, - IMG_FORMAT_BITMAP_LUMINANCE = 0x4, - IMG_FORMAT_BITMAP_ALPHA = 0x5, - IMG_FORMAT_WAVELET_RGBA = 0x6, - IMG_FORMAT_WAVELET_RGB = 0x7, - IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8, - IMG_FORMAT_WAVELET_LUMINANCE = 0x9, - IMG_FORMAT_WAVELET_ALPHA = 0xA, - IMG_FORMAT_DXT1 = 0xB, - IMG_FORMAT_DXT3 = 0xC, - IMG_FORMAT_DXT5 = 0xD, - IMG_FORMAT_DXN = 0xE, - IMG_FORMAT_BITMAP_RGB565 = 0xF, - IMG_FORMAT_BITMAP_RGB5A3 = 0x10, - IMG_FORMAT_BITMAP_C8 = 0x11, - IMG_FORMAT_BITMAP_RGBA8 = 0x12, - IMG_FORMAT_A16B16G16R16F = 0x13, - IMG_FORMAT_COUNT, - }; - - enum IwiFlags - { - IMG_FLAG_NOPICMIP = 1 << 0, - IMG_FLAG_NOMIPMAPS = 1 << 1, - IMG_FLAG_CUBEMAP = 1 << 2, - IMG_FLAG_VOLMAP = 1 << 3, - IMG_FLAG_STREAMING = 1 << 4, - IMG_FLAG_CLAMP_U = 1 << 6, - IMG_FLAG_CLAMP_V = 1 << 7, - IMG_FLAG_FORCE_SYSTEM = 1 << 8, - IMG_FLAG_DYNAMIC = 1 << 16, - IMG_FLAG_RENDER_TARGET = 1 << 17, - IMG_FLAG_MULTISAMPLE = 1 << 18, - }; - -} // namespace iwi27 + } // namespace iwi27 +} // namespace image diff --git a/src/ObjImage/Image/IwiWriter13.cpp b/src/ObjImage/Image/IwiWriter13.cpp index 0ffc7953..05282d0b 100644 --- a/src/ObjImage/Image/IwiWriter13.cpp +++ b/src/ObjImage/Image/IwiWriter13.cpp @@ -3,7 +3,7 @@ #include #include -using namespace iwi13; +using namespace image::iwi13; IwiWriter::IwiWriter() = default; @@ -54,13 +54,13 @@ std::string IwiWriter::GetFileExtension() void IwiWriter::WriteVersion(std::ostream& stream) { - IwiVersion version{}; + IwiVersionHeader version{}; version.tag[0] = 'I'; version.tag[1] = 'W'; version.tag[2] = 'i'; version.version = 13; - stream.write(reinterpret_cast(&version), sizeof(IwiVersion)); + stream.write(reinterpret_cast(&version), sizeof(IwiVersionHeader)); } void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture) @@ -101,7 +101,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture) if (!texture->HasMipMaps()) header.flags |= IMG_FLAG_NOMIPMAPS; - auto currentFileSize = sizeof(IwiVersion) + sizeof(IwiHeader); + auto currentFileSize = sizeof(IwiVersionHeader) + sizeof(IwiHeader); const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--) diff --git a/src/ObjImage/Image/IwiWriter13.h b/src/ObjImage/Image/IwiWriter13.h index 4b8109b6..155393b6 100644 --- a/src/ObjImage/Image/IwiWriter13.h +++ b/src/ObjImage/Image/IwiWriter13.h @@ -1,11 +1,11 @@ #pragma once -#include "IImageWriter.h" #include "Image/IwiTypes.h" +#include "ImageWriter.h" -namespace iwi13 +namespace image::iwi13 { - class IwiWriter final : public IImageWriter + class IwiWriter final : public ImageWriter { static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat); @@ -27,4 +27,4 @@ namespace iwi13 std::string GetFileExtension() override; void DumpImage(std::ostream& stream, const Texture* texture) override; }; -} // namespace iwi13 +} // namespace image::iwi13 diff --git a/src/ObjImage/Image/IwiWriter27.cpp b/src/ObjImage/Image/IwiWriter27.cpp index bc31b97c..6f9a868e 100644 --- a/src/ObjImage/Image/IwiWriter27.cpp +++ b/src/ObjImage/Image/IwiWriter27.cpp @@ -3,7 +3,7 @@ #include #include -using namespace iwi27; +using namespace image::iwi27; IwiWriter::IwiWriter() = default; @@ -54,13 +54,13 @@ std::string IwiWriter::GetFileExtension() void IwiWriter::WriteVersion(std::ostream& stream) { - IwiVersion version{}; + IwiVersionHeader version{}; version.tag[0] = 'I'; version.tag[1] = 'W'; version.tag[2] = 'i'; version.version = 27; - stream.write(reinterpret_cast(&version), sizeof(IwiVersion)); + stream.write(reinterpret_cast(&version), sizeof(IwiVersionHeader)); } void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture) @@ -104,7 +104,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture) for (auto& i : header.maxGlossForMip) i = 0; - auto currentFileSize = sizeof(IwiVersion) + sizeof(IwiHeader); + auto currentFileSize = sizeof(IwiVersionHeader) + sizeof(IwiHeader); const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--) diff --git a/src/ObjImage/Image/IwiWriter27.h b/src/ObjImage/Image/IwiWriter27.h index 4f47dd1a..71facafc 100644 --- a/src/ObjImage/Image/IwiWriter27.h +++ b/src/ObjImage/Image/IwiWriter27.h @@ -1,11 +1,11 @@ #pragma once -#include "IImageWriter.h" #include "Image/IwiTypes.h" +#include "ImageWriter.h" -namespace iwi27 +namespace image::iwi27 { - class IwiWriter final : public IImageWriter + class IwiWriter final : public ImageWriter { static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat); @@ -27,4 +27,4 @@ namespace iwi27 std::string GetFileExtension() override; void DumpImage(std::ostream& stream, const Texture* texture) override; }; -} // namespace iwi27 +} // namespace image::iwi27 diff --git a/src/ObjImage/Image/IwiWriter6.cpp b/src/ObjImage/Image/IwiWriter6.cpp index 39f66f61..40d8a315 100644 --- a/src/ObjImage/Image/IwiWriter6.cpp +++ b/src/ObjImage/Image/IwiWriter6.cpp @@ -2,7 +2,7 @@ #include -using namespace iwi6; +using namespace image::iwi6; IwiWriter::IwiWriter() = default; @@ -40,13 +40,13 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat) void IwiWriter::WriteVersion(std::ostream& stream) { - IwiVersion version{}; + IwiVersionHeader version{}; version.tag[0] = 'I'; version.tag[1] = 'W'; version.tag[2] = 'i'; version.version = 6; - stream.write(reinterpret_cast(&version), sizeof(IwiVersion)); + stream.write(reinterpret_cast(&version), sizeof(IwiVersionHeader)); } void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture) @@ -96,7 +96,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture) if (!texture->HasMipMaps()) header.flags |= IMG_FLAG_NOMIPMAPS; - auto currentFileSize = sizeof(IwiVersion) + sizeof(IwiHeader); + auto currentFileSize = sizeof(IwiVersionHeader) + sizeof(IwiHeader); const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--) diff --git a/src/ObjImage/Image/IwiWriter6.h b/src/ObjImage/Image/IwiWriter6.h index 79f414dd..bc178eae 100644 --- a/src/ObjImage/Image/IwiWriter6.h +++ b/src/ObjImage/Image/IwiWriter6.h @@ -1,11 +1,11 @@ #pragma once -#include "IImageWriter.h" #include "Image/IwiTypes.h" +#include "ImageWriter.h" -namespace iwi6 +namespace image::iwi6 { - class IwiWriter final : public IImageWriter + class IwiWriter final : public ImageWriter { static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat); @@ -27,4 +27,4 @@ namespace iwi6 std::string GetFileExtension() override; void DumpImage(std::ostream& stream, const Texture* texture) override; }; -} // namespace iwi6 +} // namespace image::iwi6 diff --git a/src/ObjImage/Image/IwiWriter8.cpp b/src/ObjImage/Image/IwiWriter8.cpp index ea28f193..4b25a488 100644 --- a/src/ObjImage/Image/IwiWriter8.cpp +++ b/src/ObjImage/Image/IwiWriter8.cpp @@ -2,7 +2,7 @@ #include -using namespace iwi8; +using namespace image::iwi8; IwiWriter::IwiWriter() = default; @@ -40,13 +40,13 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat) void IwiWriter::WriteVersion(std::ostream& stream) { - IwiVersion version{}; + IwiVersionHeader version{}; version.tag[0] = 'I'; version.tag[1] = 'W'; version.tag[2] = 'i'; version.version = 8; - stream.write(reinterpret_cast(&version), sizeof(IwiVersion)); + stream.write(reinterpret_cast(&version), sizeof(IwiVersionHeader)); } void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture) @@ -96,7 +96,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture) if (!texture->HasMipMaps()) header.flags |= IMG_FLAG_NOMIPMAPS; - auto currentFileSize = sizeof(IwiVersion) + sizeof(IwiHeader); + auto currentFileSize = sizeof(IwiVersionHeader) + sizeof(IwiHeader); const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1; for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--) diff --git a/src/ObjImage/Image/IwiWriter8.h b/src/ObjImage/Image/IwiWriter8.h index 01892670..ed13f7bc 100644 --- a/src/ObjImage/Image/IwiWriter8.h +++ b/src/ObjImage/Image/IwiWriter8.h @@ -1,11 +1,11 @@ #pragma once -#include "IImageWriter.h" #include "Image/IwiTypes.h" +#include "ImageWriter.h" -namespace iwi8 +namespace image::iwi8 { - class IwiWriter final : public IImageWriter + class IwiWriter final : public ImageWriter { static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat); @@ -27,4 +27,4 @@ namespace iwi8 std::string GetFileExtension() override; void DumpImage(std::ostream& stream, const Texture* texture) override; }; -} // namespace iwi8 +} // namespace image::iwi8 diff --git a/src/ObjImage/Image/Texture.cpp b/src/ObjImage/Image/Texture.cpp index c9e76372..2b82fa9b 100644 --- a/src/ObjImage/Image/Texture.cpp +++ b/src/ObjImage/Image/Texture.cpp @@ -4,440 +4,443 @@ #include #include -// ============================================== -// ================= Texture ==================== -// ============================================== -Texture::Texture(const ImageFormat* format, const bool mipMaps) +namespace image { - m_format = format; - m_has_mip_maps = mipMaps; - m_data = nullptr; -} - -Texture::Texture(Texture&& other) noexcept -{ - m_format = other.m_format; - m_has_mip_maps = other.m_has_mip_maps; - m_data = other.m_data; - - other.m_data = nullptr; -} - -Texture& Texture::operator=(Texture&& other) noexcept -{ - m_format = other.m_format; - m_has_mip_maps = other.m_has_mip_maps; - m_data = other.m_data; - - other.m_data = nullptr; - - return *this; -} - -Texture::~Texture() -{ - delete[] m_data; - m_data = nullptr; -} - -const ImageFormat* Texture::GetFormat() const -{ - return m_format; -} - -void Texture::Allocate() -{ - size_t storageRequirement = 0; - const int mipLevelCount = m_has_mip_maps ? GetMipMapCount() : 1; - - for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) + // ============================================== + // ================= Texture ==================== + // ============================================== + Texture::Texture(const ImageFormat* format, const bool mipMaps) { - storageRequirement += GetSizeOfMipLevel(currentMipLevel) * GetFaceCount(); + m_format = format; + m_has_mip_maps = mipMaps; + m_data = nullptr; } - if (storageRequirement > 0) + Texture::Texture(Texture&& other) noexcept { - m_data = new uint8_t[storageRequirement]; - memset(m_data, 0, storageRequirement); + m_format = other.m_format; + m_has_mip_maps = other.m_has_mip_maps; + m_data = other.m_data; + + other.m_data = nullptr; } -} -bool Texture::Empty() const -{ - return m_data == nullptr; -} + Texture& Texture::operator=(Texture&& other) noexcept + { + m_format = other.m_format; + m_has_mip_maps = other.m_has_mip_maps; + m_data = other.m_data; -bool Texture::HasMipMaps() const -{ - return m_has_mip_maps; -} + other.m_data = nullptr; -uint8_t* Texture::GetBufferForMipLevel(const int mipLevel) -{ - return GetBufferForMipLevel(mipLevel, 0); -} - -const uint8_t* Texture::GetBufferForMipLevel(const int mipLevel) const -{ - return GetBufferForMipLevel(mipLevel, 0); -} - -// ============================================== -// ================ Texture2D =================== -// ============================================== -Texture2D::Texture2D(const ImageFormat* format, const unsigned width, const unsigned height) - : Texture2D(format, width, height, false) -{ -} - -Texture2D::Texture2D(const ImageFormat* format, const unsigned width, const unsigned height, const bool mipMaps) - : Texture(format, mipMaps) -{ - m_width = width; - m_height = height; -} - -Texture2D::Texture2D(Texture2D&& other) noexcept - : Texture(std::move(other)), - m_width(other.m_width), - m_height(other.m_height) -{ -} - -Texture2D::~Texture2D() = default; - -Texture2D& Texture2D::operator=(Texture2D&& other) noexcept -{ - if (this == &other) return *this; - - Texture::operator=(std::move(other)); - m_width = other.m_width; - m_height = other.m_height; - - return *this; -} - -TextureType Texture2D::GetTextureType() const -{ - return TextureType::T_2D; -} - -unsigned Texture2D::GetWidth() const -{ - return m_width; -} - -unsigned Texture2D::GetHeight() const -{ - return m_height; -} - -unsigned Texture2D::GetDepth() const -{ - return 1; -} - -int Texture2D::GetFaceCount() const -{ - return 1; -} - -size_t Texture2D::GetSizeOfMipLevel(const int mipLevel) const -{ - return m_format->GetSizeOfMipLevel(mipLevel, m_width, m_height, 1); -} - -int Texture2D::GetMipMapCount() const -{ - unsigned maxDimension = std::max(m_width, m_height); - - int mipMapCount = 0; - - while (maxDimension != 0) - { - maxDimension >>= 1; - mipMapCount++; } - return mipMapCount; -} - -uint8_t* Texture2D::GetBufferForMipLevel(const int mipLevel, const int face) -{ - assert(mipLevel >= 0); - assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); - assert(face == 0); - assert(m_data); - - if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) - return nullptr; - - if (face != 0) - return nullptr; - - if (!m_data) - return nullptr; - - size_t bufferOffset = 0; - for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + Texture::~Texture() { - bufferOffset += GetSizeOfMipLevel(previousMipLevel); + delete[] m_data; + m_data = nullptr; } - return &m_data[bufferOffset]; -} - -const uint8_t* Texture2D::GetBufferForMipLevel(const int mipLevel, const int face) const -{ - assert(mipLevel >= 0); - assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); - assert(face == 0); - assert(m_data); - - if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) - return nullptr; - - if (face != 0) - return nullptr; - - if (!m_data) - return nullptr; - - size_t bufferOffset = 0; - for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + const ImageFormat* Texture::GetFormat() const { - bufferOffset += GetSizeOfMipLevel(previousMipLevel); + return m_format; } - return &m_data[bufferOffset]; -} + void Texture::Allocate() + { + size_t storageRequirement = 0; + const int mipLevelCount = m_has_mip_maps ? GetMipMapCount() : 1; -// ============================================== -// =============== TextureCube ================== -// ============================================== -const int TextureCube::FACE_COUNT = 6; + for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) + { + storageRequirement += GetSizeOfMipLevel(currentMipLevel) * GetFaceCount(); + } -TextureCube::TextureCube(const ImageFormat* format, const unsigned width, const unsigned height) - : Texture2D(format, width, height) -{ -} + if (storageRequirement > 0) + { + m_data = new uint8_t[storageRequirement]; + memset(m_data, 0, storageRequirement); + } + } -TextureCube::TextureCube(const ImageFormat* format, const unsigned width, const unsigned height, const bool mipMaps) - : Texture2D(format, width, height, mipMaps) -{ -} + bool Texture::Empty() const + { + return m_data == nullptr; + } -TextureCube::TextureCube(TextureCube&& other) noexcept - : Texture2D(std::move(other)) -{ -} + bool Texture::HasMipMaps() const + { + return m_has_mip_maps; + } -TextureCube::~TextureCube() = default; + uint8_t* Texture::GetBufferForMipLevel(const int mipLevel) + { + return GetBufferForMipLevel(mipLevel, 0); + } + + const uint8_t* Texture::GetBufferForMipLevel(const int mipLevel) const + { + return GetBufferForMipLevel(mipLevel, 0); + } + + // ============================================== + // ================ Texture2D =================== + // ============================================== + Texture2D::Texture2D(const ImageFormat* format, const unsigned width, const unsigned height) + : Texture2D(format, width, height, false) + { + } + + Texture2D::Texture2D(const ImageFormat* format, const unsigned width, const unsigned height, const bool mipMaps) + : Texture(format, mipMaps) + { + m_width = width; + m_height = height; + } + + Texture2D::Texture2D(Texture2D&& other) noexcept + : Texture(std::move(other)), + m_width(other.m_width), + m_height(other.m_height) + { + } + + Texture2D::~Texture2D() = default; + + Texture2D& Texture2D::operator=(Texture2D&& other) noexcept + { + if (this == &other) + return *this; + + Texture::operator=(std::move(other)); + m_width = other.m_width; + m_height = other.m_height; -TextureCube& TextureCube::operator=(TextureCube&& other) noexcept -{ - if (this == &other) return *this; - - Texture2D::operator=(std::move(other)); - - return *this; -} - -TextureType TextureCube::GetTextureType() const -{ - return TextureType::T_CUBE; -} - -int TextureCube::GetFaceCount() const -{ - return FACE_COUNT; -} - -uint8_t* TextureCube::GetBufferForMipLevel(const int mipLevel, const int face) -{ - assert(mipLevel >= 0); - assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); - assert(face >= 0); - assert(face < FACE_COUNT); - assert(m_data); - - if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) - return nullptr; - - if (face < 0 || face >= FACE_COUNT) - return nullptr; - - if (!m_data) - return nullptr; - - size_t bufferOffset = 0; - for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) - { - bufferOffset += GetSizeOfMipLevel(previousMipLevel) * FACE_COUNT; } - return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face]; -} - -const uint8_t* TextureCube::GetBufferForMipLevel(const int mipLevel, const int face) const -{ - assert(mipLevel >= 0); - assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); - assert(face >= 0); - assert(face < FACE_COUNT); - assert(m_data); - - if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) - return nullptr; - - if (face < 0 || face >= FACE_COUNT) - return nullptr; - - if (!m_data) - return nullptr; - - size_t bufferOffset = 0; - for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + TextureType Texture2D::GetTextureType() const { - bufferOffset += GetSizeOfMipLevel(previousMipLevel) * FACE_COUNT; + return TextureType::T_2D; } - return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face]; -} + unsigned Texture2D::GetWidth() const + { + return m_width; + } -// ============================================== -// ================ Texture3D =================== -// ============================================== + unsigned Texture2D::GetHeight() const + { + return m_height; + } -Texture3D::Texture3D(const ImageFormat* format, const unsigned width, const unsigned height, const unsigned depth) - : Texture3D(format, width, height, depth, false) -{ -} + unsigned Texture2D::GetDepth() const + { + return 1; + } -Texture3D::Texture3D(const ImageFormat* format, const unsigned width, const unsigned height, const unsigned depth, const bool mipMaps) - : Texture(format, mipMaps) -{ - m_width = width; - m_height = height; - m_depth = depth; -} + int Texture2D::GetFaceCount() const + { + return 1; + } -Texture3D::Texture3D(Texture3D&& other) noexcept - : Texture(std::move(other)), - m_width(other.m_width), - m_height(other.m_height), - m_depth(other.m_depth) -{ -} + size_t Texture2D::GetSizeOfMipLevel(const int mipLevel) const + { + return m_format->GetSizeOfMipLevel(mipLevel, m_width, m_height, 1); + } -Texture3D::~Texture3D() = default; + int Texture2D::GetMipMapCount() const + { + unsigned maxDimension = std::max(m_width, m_height); + + int mipMapCount = 0; + + while (maxDimension != 0) + { + maxDimension >>= 1; + mipMapCount++; + } + + return mipMapCount; + } + + uint8_t* Texture2D::GetBufferForMipLevel(const int mipLevel, const int face) + { + assert(mipLevel >= 0); + assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); + assert(face == 0); + assert(m_data); + + if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) + return nullptr; + + if (face != 0) + return nullptr; + + if (!m_data) + return nullptr; + + size_t bufferOffset = 0; + for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + { + bufferOffset += GetSizeOfMipLevel(previousMipLevel); + } + + return &m_data[bufferOffset]; + } + + const uint8_t* Texture2D::GetBufferForMipLevel(const int mipLevel, const int face) const + { + assert(mipLevel >= 0); + assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); + assert(face == 0); + assert(m_data); + + if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) + return nullptr; + + if (face != 0) + return nullptr; + + if (!m_data) + return nullptr; + + size_t bufferOffset = 0; + for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + { + bufferOffset += GetSizeOfMipLevel(previousMipLevel); + } + + return &m_data[bufferOffset]; + } + + // ============================================== + // =============== TextureCube ================== + // ============================================== + const int TextureCube::FACE_COUNT = 6; + + TextureCube::TextureCube(const ImageFormat* format, const unsigned width, const unsigned height) + : Texture2D(format, width, height) + { + } + + TextureCube::TextureCube(const ImageFormat* format, const unsigned width, const unsigned height, const bool mipMaps) + : Texture2D(format, width, height, mipMaps) + { + } + + TextureCube::TextureCube(TextureCube&& other) noexcept + : Texture2D(std::move(other)) + { + } + + TextureCube::~TextureCube() = default; + + TextureCube& TextureCube::operator=(TextureCube&& other) noexcept + { + if (this == &other) + return *this; + + Texture2D::operator=(std::move(other)); -Texture3D& Texture3D::operator=(Texture3D&& other) noexcept -{ - if (this == &other) return *this; - - Texture::operator=(std::move(other)); - m_width = other.m_width; - m_height = other.m_height; - m_depth = other.m_depth; - - return *this; -} - -TextureType Texture3D::GetTextureType() const -{ - return TextureType::T_3D; -} - -unsigned Texture3D::GetWidth() const -{ - return m_width; -} - -unsigned Texture3D::GetHeight() const -{ - return m_height; -} - -unsigned Texture3D::GetDepth() const -{ - return m_depth; -} - -int Texture3D::GetFaceCount() const -{ - return 1; -} - -size_t Texture3D::GetSizeOfMipLevel(const int mipLevel) const -{ - return m_format->GetSizeOfMipLevel(mipLevel, m_width, m_height, m_depth); -} - -int Texture3D::GetMipMapCount() const -{ - unsigned maxDimension = std::max(std::max(m_width, m_height), m_depth); - - int mipMapCount = 0; - - while (maxDimension != 0) - { - maxDimension >>= 1; - mipMapCount++; } - return mipMapCount; -} - -uint8_t* Texture3D::GetBufferForMipLevel(const int mipLevel, const int face) -{ - assert(mipLevel >= 0); - assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); - assert(face == 0); - assert(m_data); - - if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) - return nullptr; - - if (face != 0) - return nullptr; - - if (!m_data) - return nullptr; - - size_t bufferOffset = 0; - for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + TextureType TextureCube::GetTextureType() const { - bufferOffset += GetSizeOfMipLevel(previousMipLevel); + return TextureType::T_CUBE; } - return &m_data[bufferOffset]; -} - -const uint8_t* Texture3D::GetBufferForMipLevel(const int mipLevel, const int face) const -{ - assert(mipLevel >= 0); - assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); - assert(face == 0); - assert(m_data); - - if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) - return nullptr; - - if (face != 0) - return nullptr; - - if (!m_data) - return nullptr; - - size_t bufferOffset = 0; - for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + int TextureCube::GetFaceCount() const { - bufferOffset += GetSizeOfMipLevel(previousMipLevel); + return FACE_COUNT; } - return &m_data[bufferOffset]; -} + uint8_t* TextureCube::GetBufferForMipLevel(const int mipLevel, const int face) + { + assert(mipLevel >= 0); + assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); + assert(face >= 0); + assert(face < FACE_COUNT); + assert(m_data); + + if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) + return nullptr; + + if (face < 0 || face >= FACE_COUNT) + return nullptr; + + if (!m_data) + return nullptr; + + size_t bufferOffset = 0; + for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + { + bufferOffset += GetSizeOfMipLevel(previousMipLevel) * FACE_COUNT; + } + + return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face]; + } + + const uint8_t* TextureCube::GetBufferForMipLevel(const int mipLevel, const int face) const + { + assert(mipLevel >= 0); + assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); + assert(face >= 0); + assert(face < FACE_COUNT); + assert(m_data); + + if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) + return nullptr; + + if (face < 0 || face >= FACE_COUNT) + return nullptr; + + if (!m_data) + return nullptr; + + size_t bufferOffset = 0; + for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + { + bufferOffset += GetSizeOfMipLevel(previousMipLevel) * FACE_COUNT; + } + + return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face]; + } + + // ============================================== + // ================ Texture3D =================== + // ============================================== + + Texture3D::Texture3D(const ImageFormat* format, const unsigned width, const unsigned height, const unsigned depth) + : Texture3D(format, width, height, depth, false) + { + } + + Texture3D::Texture3D(const ImageFormat* format, const unsigned width, const unsigned height, const unsigned depth, const bool mipMaps) + : Texture(format, mipMaps) + { + m_width = width; + m_height = height; + m_depth = depth; + } + + Texture3D::Texture3D(Texture3D&& other) noexcept + : Texture(std::move(other)), + m_width(other.m_width), + m_height(other.m_height), + m_depth(other.m_depth) + { + } + + Texture3D::~Texture3D() = default; + + Texture3D& Texture3D::operator=(Texture3D&& other) noexcept + { + if (this == &other) + return *this; + + Texture::operator=(std::move(other)); + m_width = other.m_width; + m_height = other.m_height; + m_depth = other.m_depth; + + return *this; + } + + TextureType Texture3D::GetTextureType() const + { + return TextureType::T_3D; + } + + unsigned Texture3D::GetWidth() const + { + return m_width; + } + + unsigned Texture3D::GetHeight() const + { + return m_height; + } + + unsigned Texture3D::GetDepth() const + { + return m_depth; + } + + int Texture3D::GetFaceCount() const + { + return 1; + } + + size_t Texture3D::GetSizeOfMipLevel(const int mipLevel) const + { + return m_format->GetSizeOfMipLevel(mipLevel, m_width, m_height, m_depth); + } + + int Texture3D::GetMipMapCount() const + { + unsigned maxDimension = std::max(std::max(m_width, m_height), m_depth); + + int mipMapCount = 0; + + while (maxDimension != 0) + { + maxDimension >>= 1; + mipMapCount++; + } + + return mipMapCount; + } + + uint8_t* Texture3D::GetBufferForMipLevel(const int mipLevel, const int face) + { + assert(mipLevel >= 0); + assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); + assert(face == 0); + assert(m_data); + + if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) + return nullptr; + + if (face != 0) + return nullptr; + + if (!m_data) + return nullptr; + + size_t bufferOffset = 0; + for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + { + bufferOffset += GetSizeOfMipLevel(previousMipLevel); + } + + return &m_data[bufferOffset]; + } + + const uint8_t* Texture3D::GetBufferForMipLevel(const int mipLevel, const int face) const + { + assert(mipLevel >= 0); + assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1)); + assert(face == 0); + assert(m_data); + + if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1)) + return nullptr; + + if (face != 0) + return nullptr; + + if (!m_data) + return nullptr; + + size_t bufferOffset = 0; + for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++) + { + bufferOffset += GetSizeOfMipLevel(previousMipLevel); + } + + return &m_data[bufferOffset]; + } +} // namespace image diff --git a/src/ObjImage/Image/Texture.h b/src/ObjImage/Image/Texture.h index 6f518551..3ce0b9f6 100644 --- a/src/ObjImage/Image/Texture.h +++ b/src/ObjImage/Image/Texture.h @@ -3,130 +3,133 @@ #include -enum class TextureType : std::uint8_t +namespace image { - T_2D, - T_CUBE, - T_3D -}; + enum class TextureType : std::uint8_t + { + T_2D, + T_CUBE, + T_3D + }; -class Texture -{ -protected: - const ImageFormat* m_format; - bool m_has_mip_maps; - uint8_t* m_data; + class Texture + { + protected: + const ImageFormat* m_format; + bool m_has_mip_maps; + uint8_t* m_data; - Texture(const ImageFormat* format, bool mipMaps); - Texture(Texture&& other) noexcept; + Texture(const ImageFormat* format, bool mipMaps); + Texture(Texture&& other) noexcept; - Texture& operator=(Texture&& other) noexcept; + Texture& operator=(Texture&& other) noexcept; -public: - Texture(const Texture& other) = delete; - virtual ~Texture(); + public: + Texture(const Texture& other) = delete; + virtual ~Texture(); - Texture& operator=(const Texture& other) = delete; + Texture& operator=(const Texture& other) = delete; - [[nodiscard]] virtual TextureType GetTextureType() const = 0; - [[nodiscard]] const ImageFormat* GetFormat() const; + [[nodiscard]] virtual TextureType GetTextureType() const = 0; + [[nodiscard]] const ImageFormat* GetFormat() const; - [[nodiscard]] virtual unsigned GetWidth() const = 0; - [[nodiscard]] virtual unsigned GetHeight() const = 0; - [[nodiscard]] virtual unsigned GetDepth() const = 0; - [[nodiscard]] virtual int GetFaceCount() const = 0; + [[nodiscard]] virtual unsigned GetWidth() const = 0; + [[nodiscard]] virtual unsigned GetHeight() const = 0; + [[nodiscard]] virtual unsigned GetDepth() const = 0; + [[nodiscard]] virtual int GetFaceCount() const = 0; - void Allocate(); - [[nodiscard]] bool Empty() const; + void Allocate(); + [[nodiscard]] bool Empty() const; - [[nodiscard]] virtual size_t GetSizeOfMipLevel(int mipLevel) const = 0; - [[nodiscard]] virtual uint8_t* GetBufferForMipLevel(int mipLevel, int face) = 0; - [[nodiscard]] virtual const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const = 0; - [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel); - [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel) const; + [[nodiscard]] virtual size_t GetSizeOfMipLevel(int mipLevel) const = 0; + [[nodiscard]] virtual uint8_t* GetBufferForMipLevel(int mipLevel, int face) = 0; + [[nodiscard]] virtual const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const = 0; + [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel); + [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel) const; - [[nodiscard]] bool HasMipMaps() const; - [[nodiscard]] virtual int GetMipMapCount() const = 0; -}; + [[nodiscard]] bool HasMipMaps() const; + [[nodiscard]] virtual int GetMipMapCount() const = 0; + }; -class Texture2D : public Texture -{ -protected: - unsigned m_width; - unsigned m_height; + class Texture2D : public Texture + { + protected: + unsigned m_width; + unsigned m_height; -public: - Texture2D(const ImageFormat* format, unsigned width, unsigned height); - Texture2D(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps); - Texture2D(const Texture2D& other) = delete; - Texture2D(Texture2D&& other) noexcept; - ~Texture2D() override; + public: + Texture2D(const ImageFormat* format, unsigned width, unsigned height); + Texture2D(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps); + Texture2D(const Texture2D& other) = delete; + Texture2D(Texture2D&& other) noexcept; + ~Texture2D() override; - Texture2D& operator=(const Texture2D& other) = delete; - Texture2D& operator=(Texture2D&& other) noexcept; + Texture2D& operator=(const Texture2D& other) = delete; + Texture2D& operator=(Texture2D&& other) noexcept; - [[nodiscard]] TextureType GetTextureType() const override; + [[nodiscard]] TextureType GetTextureType() const override; - [[nodiscard]] unsigned GetWidth() const override; - [[nodiscard]] unsigned GetHeight() const override; - [[nodiscard]] unsigned GetDepth() const override; - [[nodiscard]] int GetFaceCount() const override; + [[nodiscard]] unsigned GetWidth() const override; + [[nodiscard]] unsigned GetHeight() const override; + [[nodiscard]] unsigned GetDepth() const override; + [[nodiscard]] int GetFaceCount() const override; - [[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override; - [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override; - [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override; + [[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override; + [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override; + [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override; - [[nodiscard]] int GetMipMapCount() const override; -}; + [[nodiscard]] int GetMipMapCount() const override; + }; -class TextureCube final : public Texture2D -{ - static const int FACE_COUNT; + class TextureCube final : public Texture2D + { + static const int FACE_COUNT; -public: - TextureCube(const ImageFormat* format, unsigned width, unsigned height); - TextureCube(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps); - TextureCube(const TextureCube& other) = delete; - TextureCube(TextureCube&& other) noexcept; - ~TextureCube() override; + public: + TextureCube(const ImageFormat* format, unsigned width, unsigned height); + TextureCube(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps); + TextureCube(const TextureCube& other) = delete; + TextureCube(TextureCube&& other) noexcept; + ~TextureCube() override; - TextureCube& operator=(const TextureCube& other) = delete; - TextureCube& operator=(TextureCube&& other) noexcept; + TextureCube& operator=(const TextureCube& other) = delete; + TextureCube& operator=(TextureCube&& other) noexcept; - [[nodiscard]] TextureType GetTextureType() const override; + [[nodiscard]] TextureType GetTextureType() const override; - [[nodiscard]] int GetFaceCount() const override; + [[nodiscard]] int GetFaceCount() const override; - [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override; - [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override; -}; + [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override; + [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override; + }; -class Texture3D final : public Texture -{ - unsigned m_width; - unsigned m_height; - unsigned m_depth; + class Texture3D final : public Texture + { + unsigned m_width; + unsigned m_height; + unsigned m_depth; -public: - Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth); - Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth, bool mipMaps); - Texture3D(const Texture3D& other) = delete; - Texture3D(Texture3D&& other) noexcept; - ~Texture3D() override; + public: + Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth); + Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth, bool mipMaps); + Texture3D(const Texture3D& other) = delete; + Texture3D(Texture3D&& other) noexcept; + ~Texture3D() override; - Texture3D& operator=(const Texture3D& other) = delete; - Texture3D& operator=(Texture3D&& other) noexcept; + Texture3D& operator=(const Texture3D& other) = delete; + Texture3D& operator=(Texture3D&& other) noexcept; - [[nodiscard]] TextureType GetTextureType() const override; + [[nodiscard]] TextureType GetTextureType() const override; - [[nodiscard]] unsigned GetWidth() const override; - [[nodiscard]] unsigned GetHeight() const override; - [[nodiscard]] unsigned GetDepth() const override; - [[nodiscard]] int GetFaceCount() const override; + [[nodiscard]] unsigned GetWidth() const override; + [[nodiscard]] unsigned GetHeight() const override; + [[nodiscard]] unsigned GetDepth() const override; + [[nodiscard]] int GetFaceCount() const override; - [[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override; - [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override; - [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override; + [[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override; + [[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override; + [[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override; - [[nodiscard]] int GetMipMapCount() const override; -}; + [[nodiscard]] int GetMipMapCount() const override; + }; +} // namespace image diff --git a/src/ObjImage/Image/TextureConverter.cpp b/src/ObjImage/Image/TextureConverter.cpp index 109aaf73..b848be0a 100644 --- a/src/ObjImage/Image/TextureConverter.cpp +++ b/src/ObjImage/Image/TextureConverter.cpp @@ -2,221 +2,224 @@ #include -constexpr uint64_t TextureConverter::Mask1(const unsigned length) +namespace image { - if (length >= sizeof(uint64_t) * 8) - return UINT64_MAX; - - return UINT64_MAX >> (sizeof(uint64_t) * 8 - length); -} - -void TextureConverter::SetPixelFunctions(const unsigned inBitCount, const unsigned outBitCount) -{ - switch (inBitCount) + constexpr uint64_t TextureConverter::Mask1(const unsigned length) { - case 16: - m_read_pixel_func = [](const void* offset, unsigned bitCount) - { - return static_cast(*static_cast(offset)); - }; - break; + if (length >= sizeof(uint64_t) * 8) + return UINT64_MAX; - case 32: - m_read_pixel_func = [](const void* offset, unsigned bitCount) - { - return static_cast(*static_cast(offset)); - }; - break; + return UINT64_MAX >> (sizeof(uint64_t) * 8 - length); + } - case 64: - m_read_pixel_func = [](const void* offset, unsigned bitCount) + void TextureConverter::SetPixelFunctions(const unsigned inBitCount, const unsigned outBitCount) + { + switch (inBitCount) { - return *static_cast(offset); - }; - break; - - default: - if (inBitCount <= 64) - { - m_read_pixel_func = [](const void* offset, const unsigned bitCount) - { - uint64_t result = 0; - - for (auto pixelOffset = 0u; pixelOffset < bitCount; pixelOffset += 8) - { - result |= (static_cast(*(static_cast(offset) + (pixelOffset / 8))) << pixelOffset); - } - - return result; - }; - } - else - { - assert(false); + case 16: m_read_pixel_func = [](const void* offset, unsigned bitCount) { - return 0ull; + return static_cast(*static_cast(offset)); }; + break; + + case 32: + m_read_pixel_func = [](const void* offset, unsigned bitCount) + { + return static_cast(*static_cast(offset)); + }; + break; + + case 64: + m_read_pixel_func = [](const void* offset, unsigned bitCount) + { + return *static_cast(offset); + }; + break; + + default: + if (inBitCount <= 64) + { + m_read_pixel_func = [](const void* offset, const unsigned bitCount) + { + uint64_t result = 0; + + for (auto pixelOffset = 0u; pixelOffset < bitCount; pixelOffset += 8) + { + result |= (static_cast(*(static_cast(offset) + (pixelOffset / 8))) << pixelOffset); + } + + return result; + }; + } + else + { + assert(false); + m_read_pixel_func = [](const void* offset, unsigned bitCount) + { + return 0ull; + }; + } + break; + } + + switch (outBitCount) + { + case 16: + m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount) + { + *static_cast(offset) = static_cast(pixel); + }; + break; + + case 32: + m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount) + { + *static_cast(offset) = static_cast(pixel); + }; + break; + + case 64: + m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount) + { + *static_cast(offset) = pixel; + }; + break; + + default: + if (inBitCount <= 64) + { + m_write_pixel_func = [](void* offset, const uint64_t pixel, const unsigned bitCount) + { + for (auto pixelOffset = 0u; pixelOffset < bitCount; pixelOffset += 8) + { + *(static_cast(offset) + (pixelOffset / 8)) = static_cast(pixel >> pixelOffset); + } + }; + } + else + { + assert(false); + m_write_pixel_func = [](void* offset, uint64_t pixel, unsigned bitCount) {}; + } + break; } - break; } - switch (outBitCount) + TextureConverter::TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat) + : m_input_texture(inputTexture), + m_output_texture(nullptr), + m_input_format(inputTexture->GetFormat()), + m_output_format(targetFormat) { - case 16: - m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount) - { - *static_cast(offset) = static_cast(pixel); - }; - break; + } - case 32: - m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount) + void TextureConverter::CreateOutputTexture() + { + switch (m_input_texture->GetTextureType()) { - *static_cast(offset) = static_cast(pixel); - }; - break; + case TextureType::T_2D: + m_output_texture = + std::make_unique(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps()); + break; - case 64: - m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount) - { - *static_cast(offset) = pixel; - }; - break; + case TextureType::T_CUBE: + m_output_texture = + std::make_unique(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps()); + break; - default: - if (inBitCount <= 64) + case TextureType::T_3D: + m_output_texture = std::make_unique( + m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->GetDepth(), m_input_texture->HasMipMaps()); + break; + default: + assert(false); + break; + } + + m_output_texture->Allocate(); + } + + void TextureConverter::ReorderUnsignedToUnsigned() const + { + const auto* inputFormat = dynamic_cast(m_input_format); + const auto* outputFormat = dynamic_cast(m_output_format); + const auto mipCount = m_input_texture->HasMipMaps() ? m_input_texture->GetMipMapCount() : 1; + + const auto rInputMask = inputFormat->HasR() ? Mask1(inputFormat->m_r_size) << inputFormat->m_r_offset : 0; + const auto gInputMask = inputFormat->HasG() ? Mask1(inputFormat->m_g_size) << inputFormat->m_g_offset : 0; + const auto bInputMask = inputFormat->HasB() ? Mask1(inputFormat->m_b_size) << inputFormat->m_b_offset : 0; + const auto aInputMask = inputFormat->HasA() ? Mask1(inputFormat->m_a_size) << inputFormat->m_a_offset : 0; + const bool rConvert = rInputMask != 0 && outputFormat->m_r_size > 0; + const bool gConvert = gInputMask != 0 && outputFormat->m_g_size > 0; + const bool bConvert = bInputMask != 0 && outputFormat->m_b_size > 0; + const bool aConvert = aInputMask != 0 && outputFormat->m_a_size > 0; + + for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) { - m_write_pixel_func = [](void* offset, const uint64_t pixel, const unsigned bitCount) + const auto mipLevelSize = m_input_texture->GetSizeOfMipLevel(mipLevel) * m_input_texture->GetFaceCount(); + const auto* inputBuffer = m_input_texture->GetBufferForMipLevel(mipLevel); + auto* outputBuffer = m_output_texture->GetBufferForMipLevel(mipLevel); + + const auto inputBytePerPixel = inputFormat->m_bits_per_pixel / 8; + const auto outputBytePerPixel = outputFormat->m_bits_per_pixel / 8; + + auto outputOffset = 0u; + for (auto inputOffset = 0u; inputOffset < mipLevelSize; inputOffset += inputBytePerPixel, outputOffset += outputBytePerPixel) { - for (auto pixelOffset = 0u; pixelOffset < bitCount; pixelOffset += 8) - { - *(static_cast(offset) + (pixelOffset / 8)) = static_cast(pixel >> pixelOffset); - } - }; + uint64_t outPixel = 0; + const auto inPixel = m_read_pixel_func(&inputBuffer[inputOffset], inputFormat->m_bits_per_pixel); + + if (rConvert) + outPixel |= (inPixel & rInputMask) >> inputFormat->m_r_offset << outputFormat->m_r_offset; + if (gConvert) + outPixel |= (inPixel & gInputMask) >> inputFormat->m_g_offset << outputFormat->m_g_offset; + if (bConvert) + outPixel |= (inPixel & bInputMask) >> inputFormat->m_b_offset << outputFormat->m_b_offset; + if (aConvert) + outPixel |= (inPixel & aInputMask) >> inputFormat->m_a_offset << outputFormat->m_a_offset; + + m_write_pixel_func(&outputBuffer[outputOffset], outPixel, outputFormat->m_bits_per_pixel); + } + } + } + + void TextureConverter::ConvertUnsignedToUnsigned() + { + const auto* inputFormat = dynamic_cast(m_input_format); + const auto* outputFormat = dynamic_cast(m_output_format); + + assert(inputFormat->m_bits_per_pixel <= 64); + assert(outputFormat->m_bits_per_pixel <= 64); + + SetPixelFunctions(inputFormat->m_bits_per_pixel, outputFormat->m_bits_per_pixel); + + if (inputFormat->m_r_size == outputFormat->m_r_size && inputFormat->m_g_size == outputFormat->m_g_size + && inputFormat->m_b_size == outputFormat->m_b_size && inputFormat->m_a_size == outputFormat->m_a_size) + { + ReorderUnsignedToUnsigned(); } else { + // Unsupported as of now assert(false); - m_write_pixel_func = [](void* offset, uint64_t pixel, unsigned bitCount) {}; } - break; - } -} - -TextureConverter::TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat) - : m_input_texture(inputTexture), - m_output_texture(nullptr), - m_input_format(inputTexture->GetFormat()), - m_output_format(targetFormat) -{ -} - -void TextureConverter::CreateOutputTexture() -{ - switch (m_input_texture->GetTextureType()) - { - case TextureType::T_2D: - m_output_texture = - std::make_unique(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps()); - break; - - case TextureType::T_CUBE: - m_output_texture = - std::make_unique(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps()); - break; - - case TextureType::T_3D: - m_output_texture = std::make_unique( - m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->GetDepth(), m_input_texture->HasMipMaps()); - break; - default: - assert(false); - break; } - m_output_texture->Allocate(); -} - -void TextureConverter::ReorderUnsignedToUnsigned() const -{ - const auto* inputFormat = dynamic_cast(m_input_format); - const auto* outputFormat = dynamic_cast(m_output_format); - const auto mipCount = m_input_texture->HasMipMaps() ? m_input_texture->GetMipMapCount() : 1; - - const auto rInputMask = inputFormat->HasR() ? Mask1(inputFormat->m_r_size) << inputFormat->m_r_offset : 0; - const auto gInputMask = inputFormat->HasG() ? Mask1(inputFormat->m_g_size) << inputFormat->m_g_offset : 0; - const auto bInputMask = inputFormat->HasB() ? Mask1(inputFormat->m_b_size) << inputFormat->m_b_offset : 0; - const auto aInputMask = inputFormat->HasA() ? Mask1(inputFormat->m_a_size) << inputFormat->m_a_offset : 0; - const bool rConvert = rInputMask != 0 && outputFormat->m_r_size > 0; - const bool gConvert = gInputMask != 0 && outputFormat->m_g_size > 0; - const bool bConvert = bInputMask != 0 && outputFormat->m_b_size > 0; - const bool aConvert = aInputMask != 0 && outputFormat->m_a_size > 0; - - for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) + std::unique_ptr TextureConverter::Convert() { - const auto mipLevelSize = m_input_texture->GetSizeOfMipLevel(mipLevel) * m_input_texture->GetFaceCount(); - const auto* inputBuffer = m_input_texture->GetBufferForMipLevel(mipLevel); - auto* outputBuffer = m_output_texture->GetBufferForMipLevel(mipLevel); + CreateOutputTexture(); - const auto inputBytePerPixel = inputFormat->m_bits_per_pixel / 8; - const auto outputBytePerPixel = outputFormat->m_bits_per_pixel / 8; - - auto outputOffset = 0u; - for (auto inputOffset = 0u; inputOffset < mipLevelSize; inputOffset += inputBytePerPixel, outputOffset += outputBytePerPixel) + if (m_input_format->GetType() == ImageFormatType::UNSIGNED && m_output_format->GetType() == ImageFormatType::UNSIGNED) { - uint64_t outPixel = 0; - const auto inPixel = m_read_pixel_func(&inputBuffer[inputOffset], inputFormat->m_bits_per_pixel); - - if (rConvert) - outPixel |= (inPixel & rInputMask) >> inputFormat->m_r_offset << outputFormat->m_r_offset; - if (gConvert) - outPixel |= (inPixel & gInputMask) >> inputFormat->m_g_offset << outputFormat->m_g_offset; - if (bConvert) - outPixel |= (inPixel & bInputMask) >> inputFormat->m_b_offset << outputFormat->m_b_offset; - if (aConvert) - outPixel |= (inPixel & aInputMask) >> inputFormat->m_a_offset << outputFormat->m_a_offset; - - m_write_pixel_func(&outputBuffer[outputOffset], outPixel, outputFormat->m_bits_per_pixel); + ConvertUnsignedToUnsigned(); } + else + { + // Unsupported as of now + assert(false); + } + + return std::move(m_output_texture); } -} - -void TextureConverter::ConvertUnsignedToUnsigned() -{ - const auto* inputFormat = dynamic_cast(m_input_format); - const auto* outputFormat = dynamic_cast(m_output_format); - - assert(inputFormat->m_bits_per_pixel <= 64); - assert(outputFormat->m_bits_per_pixel <= 64); - - SetPixelFunctions(inputFormat->m_bits_per_pixel, outputFormat->m_bits_per_pixel); - - if (inputFormat->m_r_size == outputFormat->m_r_size && inputFormat->m_g_size == outputFormat->m_g_size && inputFormat->m_b_size == outputFormat->m_b_size - && inputFormat->m_a_size == outputFormat->m_a_size) - { - ReorderUnsignedToUnsigned(); - } - else - { - // Unsupported as of now - assert(false); - } -} - -std::unique_ptr TextureConverter::Convert() -{ - CreateOutputTexture(); - - if (m_input_format->GetType() == ImageFormatType::UNSIGNED && m_output_format->GetType() == ImageFormatType::UNSIGNED) - { - ConvertUnsignedToUnsigned(); - } - else - { - // Unsupported as of now - assert(false); - } - - return std::move(m_output_texture); -} +} // namespace image diff --git a/src/ObjImage/Image/TextureConverter.h b/src/ObjImage/Image/TextureConverter.h index 30bc382d..eefc9ae6 100644 --- a/src/ObjImage/Image/TextureConverter.h +++ b/src/ObjImage/Image/TextureConverter.h @@ -5,27 +5,30 @@ #include #include -class TextureConverter +namespace image { -public: - TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat); + class TextureConverter + { + public: + TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat); - std::unique_ptr Convert(); + std::unique_ptr Convert(); -private: - static constexpr uint64_t Mask1(unsigned length); - void SetPixelFunctions(unsigned inBitCount, unsigned outBitCount); + private: + static constexpr uint64_t Mask1(unsigned length); + void SetPixelFunctions(unsigned inBitCount, unsigned outBitCount); - void CreateOutputTexture(); + void CreateOutputTexture(); - void ReorderUnsignedToUnsigned() const; - void ConvertUnsignedToUnsigned(); + void ReorderUnsignedToUnsigned() const; + void ConvertUnsignedToUnsigned(); - std::function m_read_pixel_func; - std::function m_write_pixel_func; + std::function m_read_pixel_func; + std::function m_write_pixel_func; - const Texture* m_input_texture; - std::unique_ptr m_output_texture; - const ImageFormat* m_input_format; - const ImageFormat* m_output_format; -}; + const Texture* m_input_texture; + std::unique_ptr m_output_texture; + const ImageFormat* m_input_format; + const ImageFormat* m_output_format; + }; +} // namespace image diff --git a/src/ObjLoading/Game/IW3/Image/AssetLoaderImageIW3.cpp b/src/ObjLoading/Game/IW3/Image/AssetLoaderImageIW3.cpp index 8e876432..d8ceb88f 100644 --- a/src/ObjLoading/Game/IW3/Image/AssetLoaderImageIW3.cpp +++ b/src/ObjLoading/Game/IW3/Image/AssetLoaderImageIW3.cpp @@ -12,6 +12,7 @@ #include using namespace IW3; +using namespace image; namespace { @@ -38,7 +39,7 @@ namespace if (!file.IsOpen()) return AssetCreationResult::NoAction(); - const auto texture = dds::LoadDds(*file.m_stream); + const auto texture = image::LoadDds(*file.m_stream); if (!texture) { con::error("Failed to load dds file for image asset \"{}\"", assetName); @@ -91,11 +92,11 @@ namespace loadDef->levelCount = static_cast(mipCount); loadDef->flags = 0; if (!texture->HasMipMaps()) - loadDef->flags |= iwi6::IMG_FLAG_NOMIPMAPS; + loadDef->flags |= image::iwi6::IMG_FLAG_NOMIPMAPS; if (texture->GetTextureType() == TextureType::T_CUBE) - loadDef->flags |= iwi6::IMG_FLAG_CUBEMAP; + loadDef->flags |= image::iwi6::IMG_FLAG_CUBEMAP; if (texture->GetTextureType() == TextureType::T_3D) - loadDef->flags |= iwi6::IMG_FLAG_VOLMAP; + loadDef->flags |= image::iwi6::IMG_FLAG_VOLMAP; loadDef->dimensions[0] = image->width; loadDef->dimensions[1] = image->height; loadDef->dimensions[2] = image->depth; diff --git a/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp b/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp index a7f68cf4..d51d670b 100644 --- a/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp +++ b/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp @@ -37,7 +37,7 @@ namespace file.m_stream->read(fileData.get(), fileSize); std::istringstream ss(std::string(fileData.get(), fileSize)); - const auto texture = iwi::LoadIwi(ss); + const auto texture = image::LoadIwi(ss); if (!texture) { con::error("Failed to load texture from: {}", fileName); diff --git a/src/ObjLoading/Game/T6/Image/LoaderImageT6.cpp b/src/ObjLoading/Game/T6/Image/LoaderImageT6.cpp index e870761c..81ffbf7c 100644 --- a/src/ObjLoading/Game/T6/Image/LoaderImageT6.cpp +++ b/src/ObjLoading/Game/T6/Image/LoaderImageT6.cpp @@ -38,7 +38,7 @@ namespace const auto dataHash = static_cast(crc32(0u, reinterpret_cast(fileData.get()), static_cast(fileSize))); std::istringstream ss(std::string(fileData.get(), fileSize)); - const auto texture = iwi::LoadIwi(ss); + const auto texture = image::LoadIwi(ss); if (!texture) { con::error("Failed to load texture from: {}", fileName); diff --git a/src/ObjLoading/Image/ImageLoaderCommon.cpp b/src/ObjLoading/Image/ImageLoaderCommon.cpp new file mode 100644 index 00000000..6f0c3339 --- /dev/null +++ b/src/ObjLoading/Image/ImageLoaderCommon.cpp @@ -0,0 +1,15 @@ +#include "ImageLoaderCommon.h" + +namespace image +{ + std::optional CommonImageLoaderResult::GetResultIfCancelled() const + { + if (m_failure) + return AssetCreationResult::Failure(); + + if (!m_texture) + return AssetCreationResult::NoAction(); + + return std::nullopt; + } +} // namespace image diff --git a/src/ObjLoading/Image/ImageLoaderCommon.h b/src/ObjLoading/Image/ImageLoaderCommon.h new file mode 100644 index 00000000..57744ae2 --- /dev/null +++ b/src/ObjLoading/Image/ImageLoaderCommon.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Asset/AssetCreationResult.h" +#include "Image/IwiTypes.h" +#include "Image/Texture.h" + +#include +#include +#include + +namespace image +{ + struct CommonImageLoaderResult + { + std::optional GetResultIfCancelled() const; + + bool m_failure; + std::string m_iwi_path; + std::unique_ptr m_texture; + }; + + CommonImageLoaderResult LoadImageCommon(); +} // namespace image diff --git a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp index 06d0b422..3e9d81f9 100644 --- a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp @@ -16,6 +16,7 @@ #include using namespace IW3; +using namespace image; namespace { @@ -26,15 +27,15 @@ namespace const auto& loadDef = *image.texture.loadDef; textureLoader.Width(loadDef.dimensions[0]).Height(loadDef.dimensions[1]).Depth(loadDef.dimensions[2]); - if (loadDef.flags & iwi6::IMG_FLAG_VOLMAP) + if (loadDef.flags & image::iwi6::IMG_FLAG_VOLMAP) textureLoader.Type(TextureType::T_3D); - else if (loadDef.flags & iwi6::IMG_FLAG_CUBEMAP) + else if (loadDef.flags & image::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)); + textureLoader.HasMipMaps(!(loadDef.flags & image::iwi6::IMG_FLAG_NOMIPMAPS)); return textureLoader.LoadTexture(loadDef.data); } @@ -48,7 +49,7 @@ namespace return nullptr; } - return iwi::LoadIwi(*filePathImage.m_stream); + return image::LoadIwi(*filePathImage.m_stream); } std::unique_ptr LoadImageData(ISearchPath& searchPath, const GfxImage& image) diff --git a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h index 32fdf23e..e8c9665c 100644 --- a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h +++ b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h @@ -2,7 +2,7 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW3/IW3.h" -#include "Image/IImageWriter.h" +#include "Image/ImageWriter.h" #include @@ -17,6 +17,6 @@ namespace image void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: - std::unique_ptr m_writer; + std::unique_ptr m_writer; }; } // namespace image diff --git a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp index d921581c..1327e43a 100644 --- a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp @@ -13,6 +13,7 @@ #include using namespace IW4; +using namespace image; namespace { @@ -23,15 +24,15 @@ namespace const auto& loadDef = *image.texture.loadDef; textureLoader.Width(image.width).Height(image.height).Depth(image.depth); - if ((loadDef.flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_3D) + if ((loadDef.flags & image::iwi8::IMG_FLAG_MAPTYPE_MASK) == image::iwi8::IMG_FLAG_MAPTYPE_3D) textureLoader.Type(TextureType::T_3D); - else if ((loadDef.flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_CUBE) + 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(loadDef.format)); - textureLoader.HasMipMaps(!(loadDef.flags & iwi8::IMG_FLAG_NOMIPMAPS)); + textureLoader.HasMipMaps(!(loadDef.flags & image::iwi8::IMG_FLAG_NOMIPMAPS)); return textureLoader.LoadTexture(loadDef.data); } @@ -45,7 +46,7 @@ namespace return nullptr; } - return iwi::LoadIwi(*filePathImage.m_stream); + return image::LoadIwi(*filePathImage.m_stream); } std::unique_ptr LoadImageData(ISearchPath& searchPath, const GfxImage& image) diff --git a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h index e87e71a9..80239cbc 100644 --- a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h @@ -2,7 +2,7 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "Image/IImageWriter.h" +#include "Image/ImageWriter.h" #include @@ -17,6 +17,6 @@ namespace image void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: - std::unique_ptr m_writer; + std::unique_ptr m_writer; }; } // namespace image diff --git a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp index 6a219864..71f2f69e 100644 --- a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp @@ -13,6 +13,7 @@ #include using namespace IW5; +using namespace image; namespace { @@ -24,15 +25,15 @@ namespace textureLoader.Width(image.width).Height(image.height).Depth(image.depth); - if ((loadDef.flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_3D) + if ((loadDef.flags & image::iwi8::IMG_FLAG_MAPTYPE_MASK) == image::iwi8::IMG_FLAG_MAPTYPE_3D) textureLoader.Type(TextureType::T_3D); - else if ((loadDef.flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_CUBE) + 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(loadDef.format)); - textureLoader.HasMipMaps(!(loadDef.flags & iwi8::IMG_FLAG_NOMIPMAPS)); + textureLoader.HasMipMaps(!(loadDef.flags & image::iwi8::IMG_FLAG_NOMIPMAPS)); return textureLoader.LoadTexture(loadDef.data); } @@ -46,7 +47,7 @@ namespace return nullptr; } - return iwi::LoadIwi(*filePathImage.m_stream); + return image::LoadIwi(*filePathImage.m_stream); } std::unique_ptr LoadImageData(ISearchPath& searchPath, const GfxImage& image) diff --git a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h index 7c4f8200..064991cc 100644 --- a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h @@ -2,7 +2,7 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW5/IW5.h" -#include "Image/IImageWriter.h" +#include "Image/ImageWriter.h" #include @@ -17,6 +17,6 @@ namespace image void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: - std::unique_ptr m_writer; + std::unique_ptr m_writer; }; } // namespace image diff --git a/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp b/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp index 27fe8f03..88a9cdd8 100644 --- a/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp +++ b/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp @@ -13,6 +13,7 @@ #include using namespace T5; +using namespace image; namespace { @@ -23,15 +24,15 @@ namespace const auto& loadDef = *image.texture.loadDef; textureLoader.Width(image.width).Height(image.height).Depth(image.depth); - if (loadDef.flags & iwi13::IMG_FLAG_VOLMAP) + if (loadDef.flags & image::iwi13::IMG_FLAG_VOLMAP) textureLoader.Type(TextureType::T_3D); - else if (loadDef.flags & iwi13::IMG_FLAG_CUBEMAP) + else if (loadDef.flags & image::iwi13::IMG_FLAG_CUBEMAP) textureLoader.Type(TextureType::T_CUBE); else textureLoader.Type(TextureType::T_2D); textureLoader.Format(static_cast(loadDef.format)); - textureLoader.HasMipMaps(!(loadDef.flags & iwi13::IMG_FLAG_NOMIPMAPS)); + textureLoader.HasMipMaps(!(loadDef.flags & image::iwi13::IMG_FLAG_NOMIPMAPS)); return textureLoader.LoadTexture(loadDef.data); } @@ -45,7 +46,7 @@ namespace return nullptr; } - return iwi::LoadIwi(*filePathImage.m_stream); + return image::LoadIwi(*filePathImage.m_stream); } std::unique_ptr LoadImageData(ISearchPath& searchPath, const GfxImage& image) diff --git a/src/ObjWriting/Game/T5/Image/ImageDumperT5.h b/src/ObjWriting/Game/T5/Image/ImageDumperT5.h index 109758e5..43cb41df 100644 --- a/src/ObjWriting/Game/T5/Image/ImageDumperT5.h +++ b/src/ObjWriting/Game/T5/Image/ImageDumperT5.h @@ -2,7 +2,7 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T5/T5.h" -#include "Image/IImageWriter.h" +#include "Image/ImageWriter.h" #include @@ -17,6 +17,6 @@ namespace image void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: - std::unique_ptr m_writer; + std::unique_ptr m_writer; }; } // namespace image diff --git a/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp b/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp index 3566f780..29b64061 100644 --- a/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp @@ -14,6 +14,7 @@ #include using namespace T6; +using namespace image; namespace { @@ -24,15 +25,15 @@ namespace const auto& loadDef = *image.texture.loadDef; textureLoader.Width(image.width).Height(image.height).Depth(image.depth); - if (loadDef.flags & iwi27::IMG_FLAG_VOLMAP) + if (loadDef.flags & image::iwi27::IMG_FLAG_VOLMAP) textureLoader.Type(TextureType::T_3D); - else if (loadDef.flags & iwi27::IMG_FLAG_CUBEMAP) + else if (loadDef.flags & image::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)); + textureLoader.HasMipMaps(!(loadDef.flags & image::iwi27::IMG_FLAG_NOMIPMAPS)); return textureLoader.LoadTexture(loadDef.data); } @@ -46,7 +47,7 @@ namespace if (ipakStream) { - auto loadedTexture = iwi::LoadIwi(*ipakStream); + auto loadedTexture = image::LoadIwi(*ipakStream); ipakStream->close(); if (loadedTexture != nullptr) @@ -63,7 +64,7 @@ namespace return nullptr; } - return iwi::LoadIwi(*filePathImage.m_stream); + return image::LoadIwi(*filePathImage.m_stream); } std::unique_ptr LoadImageData(ISearchPath& searchPath, const GfxImage& image) diff --git a/src/ObjWriting/Game/T6/Image/ImageDumperT6.h b/src/ObjWriting/Game/T6/Image/ImageDumperT6.h index 81dc2e93..a52d497d 100644 --- a/src/ObjWriting/Game/T6/Image/ImageDumperT6.h +++ b/src/ObjWriting/Game/T6/Image/ImageDumperT6.h @@ -2,7 +2,7 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "Image/IImageWriter.h" +#include "Image/ImageWriter.h" #include @@ -17,6 +17,6 @@ namespace image void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: - std::unique_ptr m_writer; + std::unique_ptr m_writer; }; } // namespace image