mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-01-07 17:31:49 +00:00
chore: update image namespacing
This commit is contained in:
@@ -38,11 +38,13 @@ function ImageConverter:project()
|
|||||||
|
|
||||||
self:include(includes)
|
self:include(includes)
|
||||||
Utils:include(includes)
|
Utils:include(includes)
|
||||||
|
Common:include(includes)
|
||||||
ObjImage:include(includes)
|
ObjImage:include(includes)
|
||||||
|
|
||||||
Raw:use()
|
Raw:use()
|
||||||
|
|
||||||
links:linkto(Utils)
|
links:linkto(Utils)
|
||||||
|
links:linkto(Common)
|
||||||
links:linkto(ObjImage)
|
links:linkto(ObjImage)
|
||||||
links:linkall()
|
links:linkall()
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "ImageConverter.h"
|
#include "ImageConverter.h"
|
||||||
|
|
||||||
|
#include "Game/IGame.h"
|
||||||
#include "Image/DdsLoader.h"
|
#include "Image/DdsLoader.h"
|
||||||
#include "Image/DdsWriter.h"
|
#include "Image/DdsWriter.h"
|
||||||
#include "Image/IwiLoader.h"
|
#include "Image/IwiLoader.h"
|
||||||
@@ -17,10 +18,12 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace image_converter
|
namespace
|
||||||
{
|
{
|
||||||
constexpr auto EXTENSION_IWI = ".iwi";
|
constexpr auto EXTENSION_IWI = ".iwi";
|
||||||
constexpr auto EXTENSION_DDS = ".dds";
|
constexpr auto EXTENSION_DDS = ".dds";
|
||||||
@@ -29,7 +32,7 @@ namespace image_converter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageConverterImpl()
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto texture = iwi::LoadIwi(file);
|
const auto texture = image::LoadIwi(file);
|
||||||
if (!texture)
|
if (!texture)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -103,7 +106,7 @@ namespace image_converter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto texture = dds::LoadDds(file);
|
const auto texture = image::LoadDds(file);
|
||||||
if (!texture)
|
if (!texture)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -129,23 +132,23 @@ namespace image_converter
|
|||||||
if (m_iwi_writer)
|
if (m_iwi_writer)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_game_to_convert_to == Game::UNKNOWN && !ShowGameTui())
|
if (!m_game_to_convert_to && !ShowGameTui())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (m_game_to_convert_to)
|
switch (*m_game_to_convert_to)
|
||||||
{
|
{
|
||||||
case Game::IW3:
|
case GameId::IW3:
|
||||||
m_iwi_writer = std::make_unique<iwi6::IwiWriter>();
|
m_iwi_writer = std::make_unique<image::iwi6::IwiWriter>();
|
||||||
break;
|
break;
|
||||||
case Game::IW4:
|
case GameId::IW4:
|
||||||
case Game::IW5:
|
case GameId::IW5:
|
||||||
m_iwi_writer = std::make_unique<iwi8::IwiWriter>();
|
m_iwi_writer = std::make_unique<image::iwi8::IwiWriter>();
|
||||||
break;
|
break;
|
||||||
case Game::T5:
|
case GameId::T5:
|
||||||
m_iwi_writer = std::make_unique<iwi13::IwiWriter>();
|
m_iwi_writer = std::make_unique<image::iwi13::IwiWriter>();
|
||||||
break;
|
break;
|
||||||
case Game::T6:
|
case GameId::T6:
|
||||||
m_iwi_writer = std::make_unique<iwi27::IwiWriter>();
|
m_iwi_writer = std::make_unique<image::iwi27::IwiWriter>();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -170,19 +173,19 @@ namespace image_converter
|
|||||||
switch (num)
|
switch (num)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
m_game_to_convert_to = Game::IW3;
|
m_game_to_convert_to = GameId::IW3;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_game_to_convert_to = Game::IW4;
|
m_game_to_convert_to = GameId::IW4;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
m_game_to_convert_to = Game::IW5;
|
m_game_to_convert_to = GameId::IW5;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
m_game_to_convert_to = Game::T5;
|
m_game_to_convert_to = GameId::T5;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
m_game_to_convert_to = Game::T6;
|
m_game_to_convert_to = GameId::T6;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
con::error("Invalid input");
|
con::error("Invalid input");
|
||||||
@@ -193,13 +196,13 @@ namespace image_converter
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImageConverterArgs m_args;
|
ImageConverterArgs m_args;
|
||||||
image_converter::Game m_game_to_convert_to;
|
std::optional<GameId> m_game_to_convert_to;
|
||||||
DdsWriter m_dds_writer;
|
DdsWriter m_dds_writer;
|
||||||
std::unique_ptr<IImageWriter> m_iwi_writer;
|
std::unique_ptr<ImageWriter> m_iwi_writer;
|
||||||
};
|
};
|
||||||
} // namespace image_converter
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<ImageConverter> ImageConverter::Create()
|
std::unique_ptr<ImageConverter> ImageConverter::Create()
|
||||||
{
|
{
|
||||||
return std::make_unique<image_converter::ImageConverterImpl>();
|
return std::make_unique<ImageConverterImpl>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
|||||||
};
|
};
|
||||||
|
|
||||||
ImageConverterArgs::ImageConverterArgs()
|
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<decltype(COMMAND_LINE_OPTIONS)>)
|
m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Game/IGame.h"
|
||||||
#include "Utils/Arguments/ArgumentParser.h"
|
#include "Utils/Arguments/ArgumentParser.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace image_converter
|
|
||||||
{
|
|
||||||
enum class Game : std::uint8_t
|
|
||||||
{
|
|
||||||
UNKNOWN,
|
|
||||||
IW3,
|
|
||||||
IW4,
|
|
||||||
IW5,
|
|
||||||
T5,
|
|
||||||
T6
|
|
||||||
};
|
|
||||||
} // namespace image_converter
|
|
||||||
|
|
||||||
class ImageConverterArgs
|
class ImageConverterArgs
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -26,7 +15,7 @@ public:
|
|||||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
||||||
|
|
||||||
std::vector<std::string> m_files_to_convert;
|
std::vector<std::string> m_files_to_convert;
|
||||||
image_converter::Game m_game_to_convert_to;
|
std::optional<GameId> m_game_to_convert_to;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace dds
|
using namespace image;
|
||||||
|
|
||||||
|
namespace
|
||||||
{
|
{
|
||||||
class DdsLoaderInternal
|
class DdsLoaderInternal
|
||||||
{
|
{
|
||||||
@@ -193,7 +195,7 @@ namespace dds
|
|||||||
return ReadPixelFormatUnsigned(pf);
|
return ReadPixelFormatUnsigned(pf);
|
||||||
}
|
}
|
||||||
|
|
||||||
_NODISCARD bool ReadHeader()
|
[[nodiscard]] bool ReadHeader()
|
||||||
{
|
{
|
||||||
DDS_HEADER header{};
|
DDS_HEADER header{};
|
||||||
m_stream.read(reinterpret_cast<char*>(&header), sizeof(header));
|
m_stream.read(reinterpret_cast<char*>(&header), sizeof(header));
|
||||||
@@ -277,10 +279,13 @@ namespace dds
|
|||||||
unsigned m_depth;
|
unsigned m_depth;
|
||||||
const ImageFormat* m_format;
|
const ImageFormat* m_format;
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace image
|
||||||
|
{
|
||||||
std::unique_ptr<Texture> LoadDds(std::istream& stream)
|
std::unique_ptr<Texture> LoadDds(std::istream& stream)
|
||||||
{
|
{
|
||||||
DdsLoaderInternal internal(stream);
|
DdsLoaderInternal internal(stream);
|
||||||
return internal.LoadDds();
|
return internal.LoadDds();
|
||||||
}
|
}
|
||||||
} // namespace dds
|
} // namespace image
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <istream>
|
#include <istream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace dds
|
namespace image
|
||||||
{
|
{
|
||||||
std::unique_ptr<Texture> LoadDds(std::istream& stream);
|
std::unique_ptr<Texture> LoadDds(std::istream& stream);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,110 +2,114 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
constexpr uint32_t MakeFourCc(const char ch0, const char ch1, const char ch2, const char ch3)
|
namespace image
|
||||||
{
|
{
|
||||||
return static_cast<uint32_t>(ch0) | static_cast<uint32_t>(ch1) << 8 | static_cast<uint32_t>(ch2) << 16 | static_cast<uint32_t>(ch3) << 24;
|
constexpr uint32_t MakeFourCc(const char ch0, const char ch1, const char ch2, const char ch3)
|
||||||
}
|
{
|
||||||
|
return static_cast<uint32_t>(ch0) | static_cast<uint32_t>(ch1) << 8 | static_cast<uint32_t>(ch2) << 16 | static_cast<uint32_t>(ch3) << 24;
|
||||||
|
}
|
||||||
|
|
||||||
enum DDP_FLAGS
|
enum DDP_FLAGS
|
||||||
{
|
{
|
||||||
DDPF_ALPHAPIXELS = 0x1,
|
DDPF_ALPHAPIXELS = 0x1,
|
||||||
DDPF_ALPHA = 0x2,
|
DDPF_ALPHA = 0x2,
|
||||||
DDPF_FOURCC = 0x4,
|
DDPF_FOURCC = 0x4,
|
||||||
DDPF_RGB = 0x40,
|
DDPF_RGB = 0x40,
|
||||||
DDPF_YUV = 0x200,
|
DDPF_YUV = 0x200,
|
||||||
DDPF_LUMINANCE = 0x20000
|
DDPF_LUMINANCE = 0x20000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DDS_HEADER_FLAGS
|
enum DDS_HEADER_FLAGS
|
||||||
{
|
{
|
||||||
DDSD_CAPS = 0x1,
|
DDSD_CAPS = 0x1,
|
||||||
DDSD_HEIGHT = 0x2,
|
DDSD_HEIGHT = 0x2,
|
||||||
DDSD_WIDTH = 0x4,
|
DDSD_WIDTH = 0x4,
|
||||||
DDSD_PITCH = 0x8,
|
DDSD_PITCH = 0x8,
|
||||||
DDSD_PIXELFORMAT = 0x1000,
|
DDSD_PIXELFORMAT = 0x1000,
|
||||||
DDSD_MIPMAPCOUNT = 0x20000,
|
DDSD_MIPMAPCOUNT = 0x20000,
|
||||||
DDSD_LINEARSIZE = 0x80000,
|
DDSD_LINEARSIZE = 0x80000,
|
||||||
DDSD_DEPTH = 0x800000,
|
DDSD_DEPTH = 0x800000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DDS_HEADER_CAPS
|
enum DDS_HEADER_CAPS
|
||||||
{
|
{
|
||||||
DDSCAPS_COMPLEX = 0x8,
|
DDSCAPS_COMPLEX = 0x8,
|
||||||
DDSCAPS_TEXTURE = 0x1000,
|
DDSCAPS_TEXTURE = 0x1000,
|
||||||
DDSCAPS_MIPMAP = 0x400000,
|
DDSCAPS_MIPMAP = 0x400000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DDS_HEADER_CAPS2
|
enum DDS_HEADER_CAPS2
|
||||||
{
|
{
|
||||||
DDSCAPS2_CUBEMAP = 0x200,
|
DDSCAPS2_CUBEMAP = 0x200,
|
||||||
DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
|
DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
|
||||||
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
|
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
|
||||||
DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
|
DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
|
||||||
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
|
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
|
||||||
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
|
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
|
||||||
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
|
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
|
||||||
DDSCAPS2_VOLUME = 0x200000,
|
DDSCAPS2_VOLUME = 0x200000,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DDS_PIXELFORMAT
|
struct DDS_PIXELFORMAT
|
||||||
{
|
{
|
||||||
uint32_t dwSize;
|
uint32_t dwSize;
|
||||||
uint32_t dwFlags;
|
uint32_t dwFlags;
|
||||||
uint32_t dwFourCC;
|
uint32_t dwFourCC;
|
||||||
uint32_t dwRGBBitCount;
|
uint32_t dwRGBBitCount;
|
||||||
uint32_t dwRBitMask;
|
uint32_t dwRBitMask;
|
||||||
uint32_t dwGBitMask;
|
uint32_t dwGBitMask;
|
||||||
uint32_t dwBBitMask;
|
uint32_t dwBBitMask;
|
||||||
uint32_t dwABitMask;
|
uint32_t dwABitMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DDS_HEADER
|
struct DDS_HEADER
|
||||||
{
|
{
|
||||||
uint32_t dwSize;
|
uint32_t dwSize;
|
||||||
uint32_t dwFlags;
|
uint32_t dwFlags;
|
||||||
uint32_t dwHeight;
|
uint32_t dwHeight;
|
||||||
uint32_t dwWidth;
|
uint32_t dwWidth;
|
||||||
uint32_t dwPitchOrLinearSize;
|
uint32_t dwPitchOrLinearSize;
|
||||||
uint32_t dwDepth;
|
uint32_t dwDepth;
|
||||||
uint32_t dwMipMapCount;
|
uint32_t dwMipMapCount;
|
||||||
uint32_t dwReserved1[11];
|
uint32_t dwReserved1[11];
|
||||||
DDS_PIXELFORMAT ddspf;
|
DDS_PIXELFORMAT ddspf;
|
||||||
uint32_t dwCaps;
|
uint32_t dwCaps;
|
||||||
uint32_t dwCaps2;
|
uint32_t dwCaps2;
|
||||||
uint32_t dwCaps3;
|
uint32_t dwCaps3;
|
||||||
uint32_t dwCaps4;
|
uint32_t dwCaps4;
|
||||||
uint32_t dwReserved2;
|
uint32_t dwReserved2;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum D3D10_RESOURCE_DIMENSION
|
enum D3D10_RESOURCE_DIMENSION
|
||||||
{
|
{
|
||||||
D3D10_RESOURCE_DIMENSION_UNKNOWN,
|
D3D10_RESOURCE_DIMENSION_UNKNOWN,
|
||||||
D3D10_RESOURCE_DIMENSION_BUFFER,
|
D3D10_RESOURCE_DIMENSION_BUFFER,
|
||||||
D3D10_RESOURCE_DIMENSION_TEXTURE1D,
|
D3D10_RESOURCE_DIMENSION_TEXTURE1D,
|
||||||
D3D10_RESOURCE_DIMENSION_TEXTURE2D,
|
D3D10_RESOURCE_DIMENSION_TEXTURE2D,
|
||||||
D3D10_RESOURCE_DIMENSION_TEXTURE3D
|
D3D10_RESOURCE_DIMENSION_TEXTURE3D
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DDS_HEADER_DXT10_MISC
|
enum DDS_HEADER_DXT10_MISC
|
||||||
{
|
{
|
||||||
DDS_RESOURCE_MISC_TEXTURECUBE = 0x4
|
DDS_RESOURCE_MISC_TEXTURECUBE = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DDS_HEADER_DXT10_MISC2
|
enum DDS_HEADER_DXT10_MISC2
|
||||||
{
|
{
|
||||||
DDS_ALPHA_MODE_UNKNOWN = 0x0,
|
DDS_ALPHA_MODE_UNKNOWN = 0x0,
|
||||||
DDS_ALPHA_MODE_STRAIGHT = 0x1,
|
DDS_ALPHA_MODE_STRAIGHT = 0x1,
|
||||||
DDS_ALPHA_MODE_PREMULTIPLIED = 0x2,
|
DDS_ALPHA_MODE_PREMULTIPLIED = 0x2,
|
||||||
DDS_ALPHA_MODE_OPAQUE = 0x3,
|
DDS_ALPHA_MODE_OPAQUE = 0x3,
|
||||||
DDS_ALPHA_MODE_CUSTOM = 0x4,
|
DDS_ALPHA_MODE_CUSTOM = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DDS_HEADER_DXT10
|
struct DDS_HEADER_DXT10
|
||||||
{
|
{
|
||||||
oat::DXGI_FORMAT dxgiFormat;
|
oat::DXGI_FORMAT dxgiFormat;
|
||||||
D3D10_RESOURCE_DIMENSION resourceDimension;
|
D3D10_RESOURCE_DIMENSION resourceDimension;
|
||||||
uint32_t miscFlag;
|
uint32_t miscFlag;
|
||||||
uint32_t arraySize;
|
uint32_t arraySize;
|
||||||
uint32_t miscFlags2;
|
uint32_t miscFlags2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -7,234 +7,242 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
const std::map<ImageFormatId, ImageFormatId> DDS_CONVERSION_TABLE{
|
using namespace image;
|
||||||
{ImageFormatId::R8_G8_B8, ImageFormatId::B8_G8_R8_X8},
|
|
||||||
};
|
|
||||||
|
|
||||||
class DdsWriterInternal
|
namespace
|
||||||
{
|
{
|
||||||
public:
|
const std::map<ImageFormatId, ImageFormatId> DDS_CONVERSION_TABLE{
|
||||||
static bool SupportsImageFormat(const ImageFormat* imageFormat)
|
{ImageFormatId::R8_G8_B8, ImageFormatId::B8_G8_R8_X8},
|
||||||
|
};
|
||||||
|
|
||||||
|
class DdsWriterInternal
|
||||||
{
|
{
|
||||||
return true;
|
public:
|
||||||
}
|
static bool SupportsImageFormat(const ImageFormat* imageFormat)
|
||||||
|
|
||||||
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<const char*>(&magic), sizeof(magic));
|
|
||||||
m_stream.write(reinterpret_cast<const char*>(&header), sizeof(header));
|
|
||||||
|
|
||||||
if (m_use_dx10_extension)
|
|
||||||
{
|
{
|
||||||
DDS_HEADER_DXT10 dxt10{};
|
return true;
|
||||||
PopulateDxt10Header(dxt10);
|
|
||||||
m_stream.write(reinterpret_cast<const char*>(&dxt10), sizeof(dxt10));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto mipCount = m_texture->HasMipMaps() ? m_texture->GetMipMapCount() : 1;
|
static std::string GetFileExtension()
|
||||||
for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++)
|
|
||||||
{
|
{
|
||||||
const auto* buffer = m_texture->GetBufferForMipLevel(mipLevel);
|
return ".dds";
|
||||||
const auto mipLevelSize = m_texture->GetSizeOfMipLevel(mipLevel) * m_texture->GetFaceCount();
|
|
||||||
m_stream.write(reinterpret_cast<const char*>(buffer), static_cast<std::streamsize>(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<const ImageFormatBlockCompressed*>(format));
|
|
||||||
break;
|
|
||||||
case ImageFormatType::UNSIGNED:
|
|
||||||
PopulatePixelFormatUnsigned(pf, dynamic_cast<const ImageFormatUnsigned*>(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<uint32_t>(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;
|
DdsWriterInternal(std::ostream& stream, const Texture* texture)
|
||||||
header.dwCaps4 = 0;
|
: m_stream(stream),
|
||||||
header.dwReserved2 = 0;
|
m_texture(texture),
|
||||||
}
|
m_use_dx10_extension(false)
|
||||||
|
|
||||||
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()
|
void DumpImage()
|
||||||
{
|
|
||||||
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<unsigned>(entry->second)]);
|
ConvertTextureIfNecessary();
|
||||||
m_converted_texture = converter.Convert();
|
|
||||||
m_texture = m_converted_texture.get();
|
DDS_HEADER header{};
|
||||||
|
PopulateDdsHeader(header);
|
||||||
|
|
||||||
|
constexpr auto magic = MakeFourCc('D', 'D', 'S', ' ');
|
||||||
|
|
||||||
|
m_stream.write(reinterpret_cast<const char*>(&magic), sizeof(magic));
|
||||||
|
m_stream.write(reinterpret_cast<const char*>(&header), sizeof(header));
|
||||||
|
|
||||||
|
if (m_use_dx10_extension)
|
||||||
|
{
|
||||||
|
DDS_HEADER_DXT10 dxt10{};
|
||||||
|
PopulateDxt10Header(dxt10);
|
||||||
|
m_stream.write(reinterpret_cast<const char*>(&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<const char*>(buffer), static_cast<std::streamsize>(mipLevelSize));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& m_stream;
|
static constexpr unsigned Mask1(const unsigned length)
|
||||||
const Texture* m_texture;
|
{
|
||||||
std::unique_ptr<Texture> m_converted_texture;
|
if (length >= sizeof(unsigned) * 8)
|
||||||
bool m_use_dx10_extension;
|
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<const ImageFormatBlockCompressed*>(format));
|
||||||
|
break;
|
||||||
|
case ImageFormatType::UNSIGNED:
|
||||||
|
PopulatePixelFormatUnsigned(pf, dynamic_cast<const ImageFormatUnsigned*>(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<uint32_t>(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<unsigned>(entry->second)]);
|
||||||
|
m_converted_texture = converter.Convert();
|
||||||
|
m_texture = m_converted_texture.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& m_stream;
|
||||||
|
const Texture* m_texture;
|
||||||
|
std::unique_ptr<Texture> m_converted_texture;
|
||||||
|
bool m_use_dx10_extension;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace image
|
||||||
{
|
{
|
||||||
return DdsWriterInternal::SupportsImageFormat(imageFormat);
|
DdsWriter::~DdsWriter() = default;
|
||||||
}
|
|
||||||
|
|
||||||
std::string DdsWriter::GetFileExtension()
|
bool DdsWriter::SupportsImageFormat(const ImageFormat* imageFormat)
|
||||||
{
|
{
|
||||||
return DdsWriterInternal::GetFileExtension();
|
return DdsWriterInternal::SupportsImageFormat(imageFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DdsWriter::DumpImage(std::ostream& stream, const Texture* texture)
|
std::string DdsWriter::GetFileExtension()
|
||||||
{
|
{
|
||||||
DdsWriterInternal internal(stream, texture);
|
return DdsWriterInternal::GetFileExtension();
|
||||||
internal.DumpImage();
|
}
|
||||||
}
|
|
||||||
|
void DdsWriter::DumpImage(std::ostream& stream, const Texture* texture)
|
||||||
|
{
|
||||||
|
DdsWriterInternal internal(stream, texture);
|
||||||
|
internal.DumpImage();
|
||||||
|
}
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "IImageWriter.h"
|
|
||||||
|
|
||||||
class DdsWriter final : public IImageWriter
|
#include "ImageWriter.h"
|
||||||
|
|
||||||
|
namespace image
|
||||||
{
|
{
|
||||||
public:
|
class DdsWriter final : public ImageWriter
|
||||||
~DdsWriter() override;
|
{
|
||||||
|
public:
|
||||||
|
~DdsWriter() override;
|
||||||
|
|
||||||
bool SupportsImageFormat(const ImageFormat* imageFormat) override;
|
bool SupportsImageFormat(const ImageFormat* imageFormat) override;
|
||||||
std::string GetFileExtension() override;
|
std::string GetFileExtension() override;
|
||||||
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -2,103 +2,106 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
Dx12TextureLoader::Dx12TextureLoader()
|
namespace image
|
||||||
: 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)
|
|
||||||
{
|
{
|
||||||
}
|
Dx12TextureLoader::Dx12TextureLoader()
|
||||||
|
: m_format(oat::DXGI_FORMAT_UNKNOWN),
|
||||||
const ImageFormat* Dx12TextureLoader::GetFormatForDx12Format() const
|
m_type(TextureType::T_2D),
|
||||||
{
|
m_has_mip_maps(false),
|
||||||
for (const auto* i : ImageFormat::ALL_FORMATS)
|
m_width(1u),
|
||||||
|
m_height(1u),
|
||||||
|
m_depth(1u)
|
||||||
{
|
{
|
||||||
if (i->GetDxgiFormat() == m_format)
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
const ImageFormat* Dx12TextureLoader::GetFormatForDx12Format() const
|
||||||
}
|
|
||||||
|
|
||||||
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<Texture> Dx12TextureLoader::LoadTexture(const void* data)
|
|
||||||
{
|
|
||||||
const auto* format = GetFormatForDx12Format();
|
|
||||||
|
|
||||||
if (format == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
std::unique_ptr<Texture> texture;
|
|
||||||
switch (m_type)
|
|
||||||
{
|
{
|
||||||
case TextureType::T_2D:
|
for (const auto* i : ImageFormat::ALL_FORMATS)
|
||||||
texture = std::make_unique<Texture2D>(format, m_width, m_height, m_has_mip_maps);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TextureType::T_3D:
|
|
||||||
texture = std::make_unique<Texture3D>(format, m_width, m_height, m_depth, m_has_mip_maps);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TextureType::T_CUBE:
|
|
||||||
texture = std::make_unique<TextureCube>(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);
|
if (i->GetDxgiFormat() == m_format)
|
||||||
memcpy(texture->GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize);
|
return i;
|
||||||
currentDataOffset = reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(currentDataOffset) + mipSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<Texture> Dx12TextureLoader::LoadTexture(const void* data)
|
||||||
|
{
|
||||||
|
const auto* format = GetFormatForDx12Format();
|
||||||
|
|
||||||
|
if (format == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<Texture> texture;
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case TextureType::T_2D:
|
||||||
|
texture = std::make_unique<Texture2D>(format, m_width, m_height, m_has_mip_maps);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureType::T_3D:
|
||||||
|
texture = std::make_unique<Texture3D>(format, m_width, m_height, m_depth, m_has_mip_maps);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureType::T_CUBE:
|
||||||
|
texture = std::make_unique<TextureCube>(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<const void*>(reinterpret_cast<uintptr_t>(currentDataOffset) + mipSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -6,29 +6,32 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
class Dx12TextureLoader
|
namespace image
|
||||||
{
|
{
|
||||||
public:
|
class Dx12TextureLoader
|
||||||
Dx12TextureLoader();
|
{
|
||||||
|
public:
|
||||||
|
Dx12TextureLoader();
|
||||||
|
|
||||||
Dx12TextureLoader& Format(oat::DXGI_FORMAT format);
|
Dx12TextureLoader& Format(oat::DXGI_FORMAT format);
|
||||||
Dx12TextureLoader& Type(TextureType textureType);
|
Dx12TextureLoader& Type(TextureType textureType);
|
||||||
Dx12TextureLoader& HasMipMaps(bool hasMipMaps);
|
Dx12TextureLoader& HasMipMaps(bool hasMipMaps);
|
||||||
Dx12TextureLoader& Width(unsigned width);
|
Dx12TextureLoader& Width(unsigned width);
|
||||||
Dx12TextureLoader& Height(unsigned height);
|
Dx12TextureLoader& Height(unsigned height);
|
||||||
Dx12TextureLoader& Depth(unsigned depth);
|
Dx12TextureLoader& Depth(unsigned depth);
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadTexture(const void* data);
|
std::unique_ptr<Texture> LoadTexture(const void* data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] const ImageFormat* GetFormatForDx12Format() const;
|
[[nodiscard]] const ImageFormat* GetFormatForDx12Format() const;
|
||||||
|
|
||||||
static std::unordered_map<ImageFormatId, ImageFormatId> m_conversion_table;
|
static std::unordered_map<ImageFormatId, ImageFormatId> m_conversion_table;
|
||||||
|
|
||||||
oat::DXGI_FORMAT m_format;
|
oat::DXGI_FORMAT m_format;
|
||||||
TextureType m_type;
|
TextureType m_type;
|
||||||
bool m_has_mip_maps;
|
bool m_has_mip_maps;
|
||||||
unsigned m_width;
|
unsigned m_width;
|
||||||
unsigned m_height;
|
unsigned m_height;
|
||||||
unsigned m_depth;
|
unsigned m_depth;
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -2,103 +2,106 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
Dx9TextureLoader::Dx9TextureLoader()
|
namespace image
|
||||||
: m_format(oat::D3DFMT_UNKNOWN),
|
|
||||||
m_type(TextureType::T_2D),
|
|
||||||
m_has_mip_maps(false),
|
|
||||||
m_width(1u),
|
|
||||||
m_height(1u),
|
|
||||||
m_depth(1u)
|
|
||||||
{
|
{
|
||||||
}
|
Dx9TextureLoader::Dx9TextureLoader()
|
||||||
|
: m_format(oat::D3DFMT_UNKNOWN),
|
||||||
const ImageFormat* Dx9TextureLoader::GetFormatForDx9Format() const
|
m_type(TextureType::T_2D),
|
||||||
{
|
m_has_mip_maps(false),
|
||||||
for (const auto* i : ImageFormat::ALL_FORMATS)
|
m_width(1u),
|
||||||
|
m_height(1u),
|
||||||
|
m_depth(1u)
|
||||||
{
|
{
|
||||||
if (i->GetD3DFormat() == m_format)
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
const ImageFormat* Dx9TextureLoader::GetFormatForDx9Format() const
|
||||||
}
|
|
||||||
|
|
||||||
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<Texture> Dx9TextureLoader::LoadTexture(const void* data)
|
|
||||||
{
|
|
||||||
const auto* format = GetFormatForDx9Format();
|
|
||||||
|
|
||||||
if (format == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
std::unique_ptr<Texture> texture;
|
|
||||||
switch (m_type)
|
|
||||||
{
|
{
|
||||||
case TextureType::T_2D:
|
for (const auto* i : ImageFormat::ALL_FORMATS)
|
||||||
texture = std::make_unique<Texture2D>(format, m_width, m_height, m_has_mip_maps);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TextureType::T_3D:
|
|
||||||
texture = std::make_unique<Texture3D>(format, m_width, m_height, m_depth, m_has_mip_maps);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TextureType::T_CUBE:
|
|
||||||
texture = std::make_unique<TextureCube>(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);
|
if (i->GetD3DFormat() == m_format)
|
||||||
memcpy(texture->GetBufferForMipLevel(currentMipLevel, currentFace), currentDataOffset, mipSize);
|
return i;
|
||||||
currentDataOffset = reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(currentDataOffset) + mipSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<Texture> Dx9TextureLoader::LoadTexture(const void* data)
|
||||||
|
{
|
||||||
|
const auto* format = GetFormatForDx9Format();
|
||||||
|
|
||||||
|
if (format == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<Texture> texture;
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case TextureType::T_2D:
|
||||||
|
texture = std::make_unique<Texture2D>(format, m_width, m_height, m_has_mip_maps);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureType::T_3D:
|
||||||
|
texture = std::make_unique<Texture3D>(format, m_width, m_height, m_depth, m_has_mip_maps);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureType::T_CUBE:
|
||||||
|
texture = std::make_unique<TextureCube>(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<const void*>(reinterpret_cast<uintptr_t>(currentDataOffset) + mipSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -5,27 +5,30 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class Dx9TextureLoader
|
namespace image
|
||||||
{
|
{
|
||||||
public:
|
class Dx9TextureLoader
|
||||||
Dx9TextureLoader();
|
{
|
||||||
|
public:
|
||||||
|
Dx9TextureLoader();
|
||||||
|
|
||||||
Dx9TextureLoader& Format(oat::D3DFORMAT format);
|
Dx9TextureLoader& Format(oat::D3DFORMAT format);
|
||||||
Dx9TextureLoader& Type(TextureType textureType);
|
Dx9TextureLoader& Type(TextureType textureType);
|
||||||
Dx9TextureLoader& HasMipMaps(bool hasMipMaps);
|
Dx9TextureLoader& HasMipMaps(bool hasMipMaps);
|
||||||
Dx9TextureLoader& Width(unsigned width);
|
Dx9TextureLoader& Width(unsigned width);
|
||||||
Dx9TextureLoader& Height(unsigned height);
|
Dx9TextureLoader& Height(unsigned height);
|
||||||
Dx9TextureLoader& Depth(unsigned depth);
|
Dx9TextureLoader& Depth(unsigned depth);
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadTexture(const void* data);
|
std::unique_ptr<Texture> LoadTexture(const void* data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] const ImageFormat* GetFormatForDx9Format() const;
|
[[nodiscard]] const ImageFormat* GetFormatForDx9Format() const;
|
||||||
|
|
||||||
oat::D3DFORMAT m_format;
|
oat::D3DFORMAT m_format;
|
||||||
TextureType m_type;
|
TextureType m_type;
|
||||||
bool m_has_mip_maps;
|
bool m_has_mip_maps;
|
||||||
unsigned m_width;
|
unsigned m_width;
|
||||||
unsigned m_height;
|
unsigned m_height;
|
||||||
unsigned m_depth;
|
unsigned m_depth;
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Image/Texture.h"
|
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
@@ -1,175 +1,178 @@
|
|||||||
#include "ImageFormat.h"
|
#include "ImageFormat.h"
|
||||||
|
|
||||||
ImageFormat::ImageFormat(const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat)
|
namespace image
|
||||||
: m_id(id),
|
|
||||||
m_d3d_format(d3dFormat),
|
|
||||||
m_dxgi_format(dxgiFormat)
|
|
||||||
{
|
{
|
||||||
}
|
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
|
ImageFormatId ImageFormat::GetId() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
oat::D3DFORMAT ImageFormat::GetD3DFormat() const
|
oat::D3DFORMAT ImageFormat::GetD3DFormat() const
|
||||||
{
|
{
|
||||||
return m_d3d_format;
|
return m_d3d_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
oat::DXGI_FORMAT ImageFormat::GetDxgiFormat() const
|
oat::DXGI_FORMAT ImageFormat::GetDxgiFormat() const
|
||||||
{
|
{
|
||||||
return m_dxgi_format;
|
return m_dxgi_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFormatUnsigned::ImageFormatUnsigned(const ImageFormatId id,
|
ImageFormatUnsigned::ImageFormatUnsigned(const ImageFormatId id,
|
||||||
const oat::D3DFORMAT d3dFormat,
|
const oat::D3DFORMAT d3dFormat,
|
||||||
const oat::DXGI_FORMAT dxgiFormat,
|
const oat::DXGI_FORMAT dxgiFormat,
|
||||||
const unsigned bitsPerPixel,
|
const unsigned bitsPerPixel,
|
||||||
const unsigned rOffset,
|
const unsigned rOffset,
|
||||||
const unsigned rSize,
|
const unsigned rSize,
|
||||||
const unsigned gOffset,
|
const unsigned gOffset,
|
||||||
const unsigned gSize,
|
const unsigned gSize,
|
||||||
const unsigned bOffset,
|
const unsigned bOffset,
|
||||||
const unsigned bSize,
|
const unsigned bSize,
|
||||||
const unsigned aOffset,
|
const unsigned aOffset,
|
||||||
const unsigned aSize)
|
const unsigned aSize)
|
||||||
: ImageFormat(id, d3dFormat, dxgiFormat),
|
: ImageFormat(id, d3dFormat, dxgiFormat),
|
||||||
m_bits_per_pixel(bitsPerPixel),
|
m_bits_per_pixel(bitsPerPixel),
|
||||||
m_r_offset(rOffset),
|
m_r_offset(rOffset),
|
||||||
m_r_size(rSize),
|
m_r_size(rSize),
|
||||||
m_g_offset(gOffset),
|
m_g_offset(gOffset),
|
||||||
m_g_size(gSize),
|
m_g_size(gSize),
|
||||||
m_b_offset(bOffset),
|
m_b_offset(bOffset),
|
||||||
m_b_size(bSize),
|
m_b_size(bSize),
|
||||||
m_a_offset(aOffset),
|
m_a_offset(aOffset),
|
||||||
m_a_size(aSize)
|
m_a_size(aSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFormatType ImageFormatUnsigned::GetType() const
|
ImageFormatType ImageFormatUnsigned::GetType() const
|
||||||
{
|
{
|
||||||
return ImageFormatType::UNSIGNED;
|
return ImageFormatType::UNSIGNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ImageFormatUnsigned::GetPitch(const unsigned mipLevel, const unsigned width) const
|
size_t ImageFormatUnsigned::GetPitch(const unsigned mipLevel, const unsigned width) const
|
||||||
{
|
{
|
||||||
unsigned mipWidth = width >> mipLevel;
|
unsigned mipWidth = width >> mipLevel;
|
||||||
if (mipWidth == 0)
|
if (mipWidth == 0)
|
||||||
mipWidth = 1;
|
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
|
size_t ImageFormatUnsigned::GetSizeOfMipLevel(const unsigned mipLevel, const unsigned width, const unsigned height, const unsigned depth) const
|
||||||
{
|
{
|
||||||
unsigned mipWidth = width >> mipLevel;
|
unsigned mipWidth = width >> mipLevel;
|
||||||
unsigned mipHeight = height >> mipLevel;
|
unsigned mipHeight = height >> mipLevel;
|
||||||
unsigned mipDepth = depth >> mipLevel;
|
unsigned mipDepth = depth >> mipLevel;
|
||||||
|
|
||||||
if (mipWidth == 0)
|
if (mipWidth == 0)
|
||||||
mipWidth = 1;
|
mipWidth = 1;
|
||||||
if (mipHeight == 0)
|
if (mipHeight == 0)
|
||||||
mipHeight = 1;
|
mipHeight = 1;
|
||||||
if (mipDepth == 0)
|
if (mipDepth == 0)
|
||||||
mipDepth = 1;
|
mipDepth = 1;
|
||||||
|
|
||||||
return mipWidth * mipHeight * mipDepth * m_bits_per_pixel / 8;
|
return mipWidth * mipHeight * mipDepth * m_bits_per_pixel / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFormatBlockCompressed::ImageFormatBlockCompressed(
|
ImageFormatBlockCompressed::ImageFormatBlockCompressed(
|
||||||
const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat, const unsigned blockSize, const unsigned bitsPerBlock)
|
const ImageFormatId id, const oat::D3DFORMAT d3dFormat, const oat::DXGI_FORMAT dxgiFormat, const unsigned blockSize, const unsigned bitsPerBlock)
|
||||||
: ImageFormat(id, d3dFormat, dxgiFormat),
|
: ImageFormat(id, d3dFormat, dxgiFormat),
|
||||||
m_block_size(blockSize),
|
m_block_size(blockSize),
|
||||||
m_bits_per_block(bitsPerBlock)
|
m_bits_per_block(bitsPerBlock)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFormatType ImageFormatBlockCompressed::GetType() const
|
ImageFormatType ImageFormatBlockCompressed::GetType() const
|
||||||
{
|
{
|
||||||
return ImageFormatType::BLOCK_COMPRESSED;
|
return ImageFormatType::BLOCK_COMPRESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ImageFormatBlockCompressed::GetPitch(const unsigned mipLevel, const unsigned width) const
|
size_t ImageFormatBlockCompressed::GetPitch(const unsigned mipLevel, const unsigned width) const
|
||||||
{
|
{
|
||||||
unsigned mipWidth = width >> mipLevel;
|
unsigned mipWidth = width >> mipLevel;
|
||||||
|
|
||||||
if (mipWidth == 0)
|
if (mipWidth == 0)
|
||||||
mipWidth = 1;
|
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
|
size_t ImageFormatBlockCompressed::GetSizeOfMipLevel(const unsigned mipLevel, const unsigned width, const unsigned height, const unsigned depth) const
|
||||||
{
|
{
|
||||||
unsigned mipWidth = width >> mipLevel;
|
unsigned mipWidth = width >> mipLevel;
|
||||||
unsigned mipHeight = height >> mipLevel;
|
unsigned mipHeight = height >> mipLevel;
|
||||||
unsigned mipDepth = depth >> mipLevel;
|
unsigned mipDepth = depth >> mipLevel;
|
||||||
|
|
||||||
if (mipWidth == 0)
|
if (mipWidth == 0)
|
||||||
mipWidth = 1;
|
mipWidth = 1;
|
||||||
if (mipHeight == 0)
|
if (mipHeight == 0)
|
||||||
mipHeight = 1;
|
mipHeight = 1;
|
||||||
if (mipDepth == 0)
|
if (mipDepth == 0)
|
||||||
mipDepth = 1;
|
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
|
bool ImageFormatUnsigned::HasR() const
|
||||||
{
|
{
|
||||||
return m_r_size > 0;
|
return m_r_size > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageFormatUnsigned::HasG() const
|
bool ImageFormatUnsigned::HasG() const
|
||||||
{
|
{
|
||||||
return m_g_size > 0;
|
return m_g_size > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageFormatUnsigned::HasB() const
|
bool ImageFormatUnsigned::HasB() const
|
||||||
{
|
{
|
||||||
return m_b_size > 0;
|
return m_b_size > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageFormatUnsigned::HasA() const
|
bool ImageFormatUnsigned::HasA() const
|
||||||
{
|
{
|
||||||
return m_a_size > 0;
|
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_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
|
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);
|
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
|
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);
|
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
|
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);
|
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_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(
|
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);
|
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(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 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_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_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_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_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 ImageFormatBlockCompressed ImageFormat::FORMAT_BC5(ImageFormatId::BC5, oat::D3DFMT_UNKNOWN, oat::DXGI_FORMAT_BC5_UNORM, 4, 128);
|
||||||
|
|
||||||
const ImageFormat* const ImageFormat::ALL_FORMATS[static_cast<unsigned>(ImageFormatId::MAX)]{
|
const ImageFormat* const ImageFormat::ALL_FORMATS[static_cast<unsigned>(ImageFormatId::MAX)]{
|
||||||
&FORMAT_R8_G8_B8,
|
&FORMAT_R8_G8_B8,
|
||||||
&FORMAT_B8_G8_R8_X8,
|
&FORMAT_B8_G8_R8_X8,
|
||||||
&FORMAT_R8_G8_B8_A8,
|
&FORMAT_R8_G8_B8_A8,
|
||||||
&FORMAT_B8_G8_R8_A8,
|
&FORMAT_B8_G8_R8_A8,
|
||||||
&FORMAT_A8,
|
&FORMAT_A8,
|
||||||
&FORMAT_R16_G16_B16_A16_FLOAT,
|
&FORMAT_R16_G16_B16_A16_FLOAT,
|
||||||
&FORMAT_R8,
|
&FORMAT_R8,
|
||||||
&FORMAT_R8_A8,
|
&FORMAT_R8_A8,
|
||||||
&FORMAT_BC1,
|
&FORMAT_BC1,
|
||||||
&FORMAT_BC2,
|
&FORMAT_BC2,
|
||||||
&FORMAT_BC3,
|
&FORMAT_BC3,
|
||||||
&FORMAT_BC4,
|
&FORMAT_BC4,
|
||||||
&FORMAT_BC5,
|
&FORMAT_BC5,
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -6,117 +6,120 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
enum class ImageFormatId
|
namespace image
|
||||||
{
|
{
|
||||||
UNKNOWN = -1,
|
enum class ImageFormatId
|
||||||
R8_G8_B8,
|
{
|
||||||
B8_G8_R8_X8,
|
UNKNOWN = -1,
|
||||||
R8_G8_B8_A8,
|
R8_G8_B8,
|
||||||
B8_G8_R8_A8,
|
B8_G8_R8_X8,
|
||||||
A8,
|
R8_G8_B8_A8,
|
||||||
R16_G16_B16_A16_FLOAT,
|
B8_G8_R8_A8,
|
||||||
R8,
|
A8,
|
||||||
R8_A8,
|
R16_G16_B16_A16_FLOAT,
|
||||||
BC1,
|
R8,
|
||||||
BC2,
|
R8_A8,
|
||||||
BC3,
|
BC1,
|
||||||
BC4,
|
BC2,
|
||||||
BC5,
|
BC3,
|
||||||
|
BC4,
|
||||||
|
BC5,
|
||||||
|
|
||||||
MAX
|
MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ImageFormatType
|
enum class ImageFormatType
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
UNSIGNED,
|
UNSIGNED,
|
||||||
BLOCK_COMPRESSED
|
BLOCK_COMPRESSED
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImageFormatUnsigned;
|
class ImageFormatUnsigned;
|
||||||
class ImageFormatBlockCompressed;
|
class ImageFormatBlockCompressed;
|
||||||
|
|
||||||
class ImageFormat
|
class ImageFormat
|
||||||
{
|
{
|
||||||
ImageFormatId m_id;
|
ImageFormatId m_id;
|
||||||
oat::D3DFORMAT m_d3d_format;
|
oat::D3DFORMAT m_d3d_format;
|
||||||
oat::DXGI_FORMAT m_dxgi_format;
|
oat::DXGI_FORMAT m_dxgi_format;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ImageFormat(ImageFormatId id, oat::D3DFORMAT d3dFormat, oat::DXGI_FORMAT dxgiFormat);
|
ImageFormat(ImageFormatId id, oat::D3DFORMAT d3dFormat, oat::DXGI_FORMAT dxgiFormat);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~ImageFormat() = default;
|
virtual ~ImageFormat() = default;
|
||||||
|
|
||||||
[[nodiscard]] ImageFormatId GetId() const;
|
[[nodiscard]] ImageFormatId GetId() const;
|
||||||
[[nodiscard]] oat::D3DFORMAT GetD3DFormat() const;
|
[[nodiscard]] oat::D3DFORMAT GetD3DFormat() const;
|
||||||
[[nodiscard]] oat::DXGI_FORMAT GetDxgiFormat() const;
|
[[nodiscard]] oat::DXGI_FORMAT GetDxgiFormat() const;
|
||||||
|
|
||||||
[[nodiscard]] virtual ImageFormatType GetType() const = 0;
|
[[nodiscard]] virtual ImageFormatType GetType() const = 0;
|
||||||
[[nodiscard]] virtual size_t GetPitch(unsigned mipLevel, unsigned width) 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 size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const = 0;
|
||||||
|
|
||||||
static const ImageFormatUnsigned FORMAT_R8_G8_B8;
|
static const ImageFormatUnsigned FORMAT_R8_G8_B8;
|
||||||
static const ImageFormatUnsigned FORMAT_B8_G8_R8_X8;
|
static const ImageFormatUnsigned FORMAT_B8_G8_R8_X8;
|
||||||
static const ImageFormatUnsigned FORMAT_R8_G8_B8_A8;
|
static const ImageFormatUnsigned FORMAT_R8_G8_B8_A8;
|
||||||
static const ImageFormatUnsigned FORMAT_B8_G8_R8_A8;
|
static const ImageFormatUnsigned FORMAT_B8_G8_R8_A8;
|
||||||
static const ImageFormatUnsigned FORMAT_A8;
|
static const ImageFormatUnsigned FORMAT_A8;
|
||||||
static const ImageFormatUnsigned FORMAT_R16_G16_B16_A16_FLOAT; // TODO: Float not unsigned
|
static const ImageFormatUnsigned FORMAT_R16_G16_B16_A16_FLOAT; // TODO: Float not unsigned
|
||||||
static const ImageFormatUnsigned FORMAT_R8;
|
static const ImageFormatUnsigned FORMAT_R8;
|
||||||
static const ImageFormatUnsigned FORMAT_R8_A8;
|
static const ImageFormatUnsigned FORMAT_R8_A8;
|
||||||
static const ImageFormatBlockCompressed FORMAT_BC1;
|
static const ImageFormatBlockCompressed FORMAT_BC1;
|
||||||
static const ImageFormatBlockCompressed FORMAT_BC2;
|
static const ImageFormatBlockCompressed FORMAT_BC2;
|
||||||
static const ImageFormatBlockCompressed FORMAT_BC3;
|
static const ImageFormatBlockCompressed FORMAT_BC3;
|
||||||
static const ImageFormatBlockCompressed FORMAT_BC4;
|
static const ImageFormatBlockCompressed FORMAT_BC4;
|
||||||
static const ImageFormatBlockCompressed FORMAT_BC5;
|
static const ImageFormatBlockCompressed FORMAT_BC5;
|
||||||
static const ImageFormat* const ALL_FORMATS[static_cast<unsigned>(ImageFormatId::MAX)];
|
static const ImageFormat* const ALL_FORMATS[static_cast<unsigned>(ImageFormatId::MAX)];
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImageFormatUnsigned final : public ImageFormat
|
class ImageFormatUnsigned final : public ImageFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned m_bits_per_pixel;
|
unsigned m_bits_per_pixel;
|
||||||
unsigned m_r_offset;
|
unsigned m_r_offset;
|
||||||
unsigned m_r_size;
|
unsigned m_r_size;
|
||||||
unsigned m_g_offset;
|
unsigned m_g_offset;
|
||||||
unsigned m_g_size;
|
unsigned m_g_size;
|
||||||
unsigned m_b_offset;
|
unsigned m_b_offset;
|
||||||
unsigned m_b_size;
|
unsigned m_b_size;
|
||||||
unsigned m_a_offset;
|
unsigned m_a_offset;
|
||||||
unsigned m_a_size;
|
unsigned m_a_size;
|
||||||
|
|
||||||
ImageFormatUnsigned(ImageFormatId id,
|
ImageFormatUnsigned(ImageFormatId id,
|
||||||
oat::D3DFORMAT d3dFormat,
|
oat::D3DFORMAT d3dFormat,
|
||||||
oat::DXGI_FORMAT dxgiFormat,
|
oat::DXGI_FORMAT dxgiFormat,
|
||||||
unsigned bitsPerPixel,
|
unsigned bitsPerPixel,
|
||||||
unsigned rOffset,
|
unsigned rOffset,
|
||||||
unsigned rSize,
|
unsigned rSize,
|
||||||
unsigned gOffset,
|
unsigned gOffset,
|
||||||
unsigned gSize,
|
unsigned gSize,
|
||||||
unsigned bOffset,
|
unsigned bOffset,
|
||||||
unsigned bSize,
|
unsigned bSize,
|
||||||
unsigned aOffset,
|
unsigned aOffset,
|
||||||
unsigned aSize);
|
unsigned aSize);
|
||||||
|
|
||||||
[[nodiscard]] ImageFormatType GetType() const override;
|
[[nodiscard]] ImageFormatType GetType() const override;
|
||||||
[[nodiscard]] size_t GetPitch(unsigned mipLevel, unsigned width) 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]] size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const override;
|
||||||
|
|
||||||
[[nodiscard]] bool HasR() const;
|
[[nodiscard]] bool HasR() const;
|
||||||
[[nodiscard]] bool HasG() const;
|
[[nodiscard]] bool HasG() const;
|
||||||
[[nodiscard]] bool HasB() const;
|
[[nodiscard]] bool HasB() const;
|
||||||
[[nodiscard]] bool HasA() const;
|
[[nodiscard]] bool HasA() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImageFormatBlockCompressed final : public ImageFormat
|
class ImageFormatBlockCompressed final : public ImageFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned m_block_size;
|
unsigned m_block_size;
|
||||||
unsigned m_bits_per_block;
|
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]] ImageFormatType GetType() const override;
|
||||||
[[nodiscard]] size_t GetPitch(unsigned mipLevel, unsigned width) 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]] size_t GetSizeOfMipLevel(unsigned mipLevel, unsigned width, unsigned height, unsigned depth) const override;
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
24
src/ObjImage/Image/ImageWriter.h
Normal file
24
src/ObjImage/Image/ImageWriter.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
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
|
||||||
@@ -8,7 +8,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace iwi
|
using namespace image;
|
||||||
|
|
||||||
|
namespace
|
||||||
{
|
{
|
||||||
const ImageFormat* GetFormat6(int8_t format)
|
const ImageFormat* GetFormat6(int8_t format)
|
||||||
{
|
{
|
||||||
@@ -74,7 +76,7 @@ namespace iwi
|
|||||||
|
|
||||||
texture->Allocate();
|
texture->Allocate();
|
||||||
|
|
||||||
auto currentFileSize = sizeof(iwi6::IwiHeader) + sizeof(IwiVersion);
|
auto currentFileSize = sizeof(iwi6::IwiHeader) + sizeof(IwiVersionHeader);
|
||||||
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||||
|
|
||||||
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
@@ -188,7 +190,7 @@ namespace iwi
|
|||||||
|
|
||||||
texture->Allocate();
|
texture->Allocate();
|
||||||
|
|
||||||
auto currentFileSize = sizeof(iwi8::IwiHeader) + sizeof(IwiVersion);
|
auto currentFileSize = sizeof(iwi8::IwiHeader) + sizeof(IwiVersionHeader);
|
||||||
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||||
|
|
||||||
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
@@ -283,7 +285,7 @@ namespace iwi
|
|||||||
|
|
||||||
texture->Allocate();
|
texture->Allocate();
|
||||||
|
|
||||||
auto currentFileSize = sizeof(iwi13::IwiHeader) + sizeof(IwiVersion);
|
auto currentFileSize = sizeof(iwi13::IwiHeader) + sizeof(IwiVersionHeader);
|
||||||
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||||
|
|
||||||
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
@@ -380,7 +382,7 @@ namespace iwi
|
|||||||
|
|
||||||
texture->Allocate();
|
texture->Allocate();
|
||||||
|
|
||||||
auto currentFileSize = sizeof(iwi27::IwiHeader) + sizeof(IwiVersion);
|
auto currentFileSize = sizeof(iwi27::IwiHeader) + sizeof(IwiVersionHeader);
|
||||||
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
const auto mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||||
|
|
||||||
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
@@ -405,22 +407,25 @@ namespace iwi
|
|||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace image
|
||||||
|
{
|
||||||
std::unique_ptr<Texture> LoadIwi(std::istream& stream)
|
std::unique_ptr<Texture> LoadIwi(std::istream& stream)
|
||||||
{
|
{
|
||||||
IwiVersion iwiVersion{};
|
IwiVersionHeader iwiVersionHeader{};
|
||||||
|
|
||||||
stream.read(reinterpret_cast<char*>(&iwiVersion), sizeof(iwiVersion));
|
stream.read(reinterpret_cast<char*>(&iwiVersionHeader), sizeof(iwiVersionHeader));
|
||||||
if (stream.gcount() != sizeof(iwiVersion))
|
if (stream.gcount() != sizeof(iwiVersionHeader))
|
||||||
return nullptr;
|
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");
|
con::error("Invalid IWI magic");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (iwiVersion.version)
|
switch (iwiVersionHeader.version)
|
||||||
{
|
{
|
||||||
case 6:
|
case 6:
|
||||||
return LoadIwi6(stream);
|
return LoadIwi6(stream);
|
||||||
@@ -438,7 +443,7 @@ namespace iwi
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
con::error("Unknown IWI version {}", iwiVersion.version);
|
con::error("Unknown IWI version {}", iwiVersionHeader.version);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} // namespace iwi
|
} // namespace image
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <istream>
|
#include <istream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace iwi
|
namespace image
|
||||||
{
|
{
|
||||||
std::unique_ptr<Texture> LoadIwi(std::istream& stream);
|
std::unique_ptr<Texture> LoadIwi(std::istream& stream);
|
||||||
}; // namespace iwi
|
}; // namespace image
|
||||||
|
|||||||
@@ -2,234 +2,245 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
struct IwiVersion
|
namespace image
|
||||||
{
|
{
|
||||||
char tag[3];
|
enum class IwiVersion : std::uint8_t
|
||||||
char version;
|
|
||||||
};
|
|
||||||
|
|
||||||
// IW3
|
|
||||||
namespace iwi6
|
|
||||||
{
|
|
||||||
struct IwiHeader
|
|
||||||
{
|
{
|
||||||
int8_t format;
|
// IW3
|
||||||
int8_t flags;
|
IWI_6 = 6,
|
||||||
uint16_t dimensions[3];
|
// IW4, IW5
|
||||||
uint32_t fileSizeForPicmip[4];
|
IWI_8 = 8,
|
||||||
|
// T5
|
||||||
|
IWI_13 = 13,
|
||||||
|
// T6
|
||||||
|
IWI_27 = 27
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class IwiFormat
|
struct IwiVersionHeader
|
||||||
{
|
{
|
||||||
IMG_FORMAT_INVALID = 0x0,
|
char tag[3];
|
||||||
IMG_FORMAT_BITMAP_RGBA = 0x1,
|
char version;
|
||||||
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
|
namespace iwi6
|
||||||
{
|
{
|
||||||
IMG_FLAG_NOPICMIP = 1 << 0,
|
struct IwiHeader
|
||||||
IMG_FLAG_NOMIPMAPS = 1 << 1,
|
{
|
||||||
IMG_FLAG_CUBEMAP = 1 << 2,
|
int8_t format;
|
||||||
IMG_FLAG_VOLMAP = 1 << 3,
|
int8_t flags;
|
||||||
IMG_FLAG_STREAMING = 1 << 4,
|
uint16_t dimensions[3];
|
||||||
IMG_FLAG_LEGACY_NORMALS = 1 << 5,
|
uint32_t fileSizeForPicmip[4];
|
||||||
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
|
|
||||||
|
|
||||||
// IW4
|
enum class IwiFormat
|
||||||
namespace iwi8
|
{
|
||||||
{
|
IMG_FORMAT_INVALID = 0x0,
|
||||||
struct IwiHeader
|
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;
|
struct IwiHeader
|
||||||
int8_t format;
|
{
|
||||||
int8_t unused;
|
uint32_t flags;
|
||||||
uint16_t dimensions[3];
|
int8_t format;
|
||||||
uint32_t fileSizeForPicmip[4];
|
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,
|
struct IwiHeader
|
||||||
IMG_FORMAT_BITMAP_RGBA = 0x1,
|
{
|
||||||
IMG_FORMAT_BITMAP_RGB = 0x2,
|
int8_t format;
|
||||||
IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3,
|
int8_t flags;
|
||||||
IMG_FORMAT_BITMAP_LUMINANCE = 0x4,
|
uint16_t dimensions[3];
|
||||||
IMG_FORMAT_BITMAP_ALPHA = 0x5,
|
float gamma;
|
||||||
IMG_FORMAT_WAVELET_RGBA = 0x6,
|
uint32_t fileSizeForPicmip[8];
|
||||||
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 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,
|
struct IwiHeader
|
||||||
IMG_FLAG_NOMIPMAPS = 1 << 1,
|
{
|
||||||
IMG_FLAG_STREAMING = 1 << 2,
|
int8_t format;
|
||||||
IMG_FLAG_LEGACY_NORMALS = 1 << 3,
|
int8_t flags;
|
||||||
IMG_FLAG_CLAMP_U = 1 << 4,
|
uint16_t dimensions[3];
|
||||||
IMG_FLAG_CLAMP_V = 1 << 5,
|
float gamma;
|
||||||
IMG_FLAG_ALPHA_WEIGHTED_COLORS = 1 << 6,
|
int8_t maxGlossForMip[16];
|
||||||
IMG_FLAG_DXTC_APPROX_WEIGHTS = 1 << 7,
|
uint32_t fileSizeForPicmip[8];
|
||||||
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
|
|
||||||
|
|
||||||
// T5
|
enum class IwiFormat
|
||||||
namespace iwi13
|
{
|
||||||
{
|
IMG_FORMAT_INVALID = 0x0,
|
||||||
struct IwiHeader
|
IMG_FORMAT_BITMAP_RGBA = 0x1,
|
||||||
{
|
IMG_FORMAT_BITMAP_RGB = 0x2,
|
||||||
int8_t format;
|
IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3,
|
||||||
int8_t flags;
|
IMG_FORMAT_BITMAP_LUMINANCE = 0x4,
|
||||||
uint16_t dimensions[3];
|
IMG_FORMAT_BITMAP_ALPHA = 0x5,
|
||||||
float gamma;
|
IMG_FORMAT_WAVELET_RGBA = 0x6,
|
||||||
uint32_t fileSizeForPicmip[8];
|
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
|
enum IwiFlags
|
||||||
{
|
{
|
||||||
IMG_FORMAT_INVALID = 0x0,
|
IMG_FLAG_NOPICMIP = 1 << 0,
|
||||||
IMG_FORMAT_BITMAP_RGBA = 0x1,
|
IMG_FLAG_NOMIPMAPS = 1 << 1,
|
||||||
IMG_FORMAT_BITMAP_RGB = 0x2,
|
IMG_FLAG_CUBEMAP = 1 << 2,
|
||||||
IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3,
|
IMG_FLAG_VOLMAP = 1 << 3,
|
||||||
IMG_FORMAT_BITMAP_LUMINANCE = 0x4,
|
IMG_FLAG_STREAMING = 1 << 4,
|
||||||
IMG_FORMAT_BITMAP_ALPHA = 0x5,
|
IMG_FLAG_CLAMP_U = 1 << 6,
|
||||||
IMG_FORMAT_WAVELET_RGBA = 0x6,
|
IMG_FLAG_CLAMP_V = 1 << 7,
|
||||||
IMG_FORMAT_WAVELET_RGB = 0x7,
|
IMG_FLAG_FORCE_SYSTEM = 1 << 8,
|
||||||
IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8,
|
IMG_FLAG_DYNAMIC = 1 << 16,
|
||||||
IMG_FORMAT_WAVELET_LUMINANCE = 0x9,
|
IMG_FLAG_RENDER_TARGET = 1 << 17,
|
||||||
IMG_FORMAT_WAVELET_ALPHA = 0xA,
|
IMG_FLAG_MULTISAMPLE = 1 << 18,
|
||||||
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
|
} // namespace iwi27
|
||||||
{
|
} // namespace image
|
||||||
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
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
using namespace iwi13;
|
using namespace image::iwi13;
|
||||||
|
|
||||||
IwiWriter::IwiWriter() = default;
|
IwiWriter::IwiWriter() = default;
|
||||||
|
|
||||||
@@ -54,13 +54,13 @@ std::string IwiWriter::GetFileExtension()
|
|||||||
|
|
||||||
void IwiWriter::WriteVersion(std::ostream& stream)
|
void IwiWriter::WriteVersion(std::ostream& stream)
|
||||||
{
|
{
|
||||||
IwiVersion version{};
|
IwiVersionHeader version{};
|
||||||
version.tag[0] = 'I';
|
version.tag[0] = 'I';
|
||||||
version.tag[1] = 'W';
|
version.tag[1] = 'W';
|
||||||
version.tag[2] = 'i';
|
version.tag[2] = 'i';
|
||||||
version.version = 13;
|
version.version = 13;
|
||||||
|
|
||||||
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersion));
|
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersionHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
||||||
@@ -101,7 +101,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture)
|
|||||||
if (!texture->HasMipMaps())
|
if (!texture->HasMipMaps())
|
||||||
header.flags |= IMG_FLAG_NOMIPMAPS;
|
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;
|
const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
|
||||||
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IImageWriter.h"
|
|
||||||
#include "Image/IwiTypes.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);
|
static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat);
|
||||||
|
|
||||||
@@ -27,4 +27,4 @@ namespace iwi13
|
|||||||
std::string GetFileExtension() override;
|
std::string GetFileExtension() override;
|
||||||
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
||||||
};
|
};
|
||||||
} // namespace iwi13
|
} // namespace image::iwi13
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
using namespace iwi27;
|
using namespace image::iwi27;
|
||||||
|
|
||||||
IwiWriter::IwiWriter() = default;
|
IwiWriter::IwiWriter() = default;
|
||||||
|
|
||||||
@@ -54,13 +54,13 @@ std::string IwiWriter::GetFileExtension()
|
|||||||
|
|
||||||
void IwiWriter::WriteVersion(std::ostream& stream)
|
void IwiWriter::WriteVersion(std::ostream& stream)
|
||||||
{
|
{
|
||||||
IwiVersion version{};
|
IwiVersionHeader version{};
|
||||||
version.tag[0] = 'I';
|
version.tag[0] = 'I';
|
||||||
version.tag[1] = 'W';
|
version.tag[1] = 'W';
|
||||||
version.tag[2] = 'i';
|
version.tag[2] = 'i';
|
||||||
version.version = 27;
|
version.version = 27;
|
||||||
|
|
||||||
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersion));
|
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersionHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
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)
|
for (auto& i : header.maxGlossForMip)
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
auto currentFileSize = sizeof(IwiVersion) + sizeof(IwiHeader);
|
auto currentFileSize = sizeof(IwiVersionHeader) + sizeof(IwiHeader);
|
||||||
|
|
||||||
const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
|
const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
|
||||||
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IImageWriter.h"
|
|
||||||
#include "Image/IwiTypes.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);
|
static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat);
|
||||||
|
|
||||||
@@ -27,4 +27,4 @@ namespace iwi27
|
|||||||
std::string GetFileExtension() override;
|
std::string GetFileExtension() override;
|
||||||
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
||||||
};
|
};
|
||||||
} // namespace iwi27
|
} // namespace image::iwi27
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
using namespace iwi6;
|
using namespace image::iwi6;
|
||||||
|
|
||||||
IwiWriter::IwiWriter() = default;
|
IwiWriter::IwiWriter() = default;
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
|
|||||||
|
|
||||||
void IwiWriter::WriteVersion(std::ostream& stream)
|
void IwiWriter::WriteVersion(std::ostream& stream)
|
||||||
{
|
{
|
||||||
IwiVersion version{};
|
IwiVersionHeader version{};
|
||||||
version.tag[0] = 'I';
|
version.tag[0] = 'I';
|
||||||
version.tag[1] = 'W';
|
version.tag[1] = 'W';
|
||||||
version.tag[2] = 'i';
|
version.tag[2] = 'i';
|
||||||
version.version = 6;
|
version.version = 6;
|
||||||
|
|
||||||
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersion));
|
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersionHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
||||||
@@ -96,7 +96,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture)
|
|||||||
if (!texture->HasMipMaps())
|
if (!texture->HasMipMaps())
|
||||||
header.flags |= IMG_FLAG_NOMIPMAPS;
|
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;
|
const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
|
||||||
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IImageWriter.h"
|
|
||||||
#include "Image/IwiTypes.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);
|
static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat);
|
||||||
|
|
||||||
@@ -27,4 +27,4 @@ namespace iwi6
|
|||||||
std::string GetFileExtension() override;
|
std::string GetFileExtension() override;
|
||||||
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
||||||
};
|
};
|
||||||
} // namespace iwi6
|
} // namespace image::iwi6
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
using namespace iwi8;
|
using namespace image::iwi8;
|
||||||
|
|
||||||
IwiWriter::IwiWriter() = default;
|
IwiWriter::IwiWriter() = default;
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ IwiFormat IwiWriter::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
|
|||||||
|
|
||||||
void IwiWriter::WriteVersion(std::ostream& stream)
|
void IwiWriter::WriteVersion(std::ostream& stream)
|
||||||
{
|
{
|
||||||
IwiVersion version{};
|
IwiVersionHeader version{};
|
||||||
version.tag[0] = 'I';
|
version.tag[0] = 'I';
|
||||||
version.tag[1] = 'W';
|
version.tag[1] = 'W';
|
||||||
version.tag[2] = 'i';
|
version.tag[2] = 'i';
|
||||||
version.version = 8;
|
version.version = 8;
|
||||||
|
|
||||||
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersion));
|
stream.write(reinterpret_cast<char*>(&version), sizeof(IwiVersionHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
void IwiWriter::FillHeader2D(IwiHeader& header, const Texture2D& texture)
|
||||||
@@ -96,7 +96,7 @@ void IwiWriter::DumpImage(std::ostream& stream, const Texture* texture)
|
|||||||
if (!texture->HasMipMaps())
|
if (!texture->HasMipMaps())
|
||||||
header.flags |= IMG_FLAG_NOMIPMAPS;
|
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;
|
const auto textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
|
||||||
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
for (auto currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IImageWriter.h"
|
|
||||||
#include "Image/IwiTypes.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);
|
static IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat);
|
||||||
|
|
||||||
@@ -27,4 +27,4 @@ namespace iwi8
|
|||||||
std::string GetFileExtension() override;
|
std::string GetFileExtension() override;
|
||||||
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
void DumpImage(std::ostream& stream, const Texture* texture) override;
|
||||||
};
|
};
|
||||||
} // namespace iwi8
|
} // namespace image::iwi8
|
||||||
|
|||||||
@@ -4,440 +4,443 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
// ==============================================
|
namespace image
|
||||||
// ================= Texture ====================
|
|
||||||
// ==============================================
|
|
||||||
Texture::Texture(const ImageFormat* format, const bool mipMaps)
|
|
||||||
{
|
{
|
||||||
m_format = format;
|
// ==============================================
|
||||||
m_has_mip_maps = mipMaps;
|
// ================= Texture ====================
|
||||||
m_data = nullptr;
|
// ==============================================
|
||||||
}
|
Texture::Texture(const ImageFormat* format, const bool mipMaps)
|
||||||
|
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
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];
|
m_format = other.m_format;
|
||||||
memset(m_data, 0, storageRequirement);
|
m_has_mip_maps = other.m_has_mip_maps;
|
||||||
|
m_data = other.m_data;
|
||||||
|
|
||||||
|
other.m_data = nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool Texture::Empty() const
|
Texture& Texture::operator=(Texture&& other) noexcept
|
||||||
{
|
{
|
||||||
return m_data == nullptr;
|
m_format = other.m_format;
|
||||||
}
|
m_has_mip_maps = other.m_has_mip_maps;
|
||||||
|
m_data = other.m_data;
|
||||||
|
|
||||||
bool Texture::HasMipMaps() const
|
other.m_data = nullptr;
|
||||||
{
|
|
||||||
return m_has_mip_maps;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
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;
|
Texture::~Texture()
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
delete[] m_data;
|
||||||
|
m_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_data[bufferOffset];
|
const ImageFormat* Texture::GetFormat() const
|
||||||
}
|
|
||||||
|
|
||||||
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_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_data[bufferOffset];
|
void Texture::Allocate()
|
||||||
}
|
{
|
||||||
|
size_t storageRequirement = 0;
|
||||||
|
const int mipLevelCount = m_has_mip_maps ? GetMipMapCount() : 1;
|
||||||
|
|
||||||
// ==============================================
|
for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++)
|
||||||
// =============== TextureCube ==================
|
{
|
||||||
// ==============================================
|
storageRequirement += GetSizeOfMipLevel(currentMipLevel) * GetFaceCount();
|
||||||
const int TextureCube::FACE_COUNT = 6;
|
}
|
||||||
|
|
||||||
TextureCube::TextureCube(const ImageFormat* format, const unsigned width, const unsigned height)
|
if (storageRequirement > 0)
|
||||||
: Texture2D(format, width, height)
|
{
|
||||||
{
|
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)
|
bool Texture::Empty() const
|
||||||
: Texture2D(format, width, height, mipMaps)
|
{
|
||||||
{
|
return m_data == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCube::TextureCube(TextureCube&& other) noexcept
|
bool Texture::HasMipMaps() const
|
||||||
: Texture2D(std::move(other))
|
{
|
||||||
{
|
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;
|
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];
|
TextureType Texture2D::GetTextureType() const
|
||||||
}
|
|
||||||
|
|
||||||
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 TextureType::T_2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face];
|
unsigned Texture2D::GetWidth() const
|
||||||
}
|
{
|
||||||
|
return m_width;
|
||||||
|
}
|
||||||
|
|
||||||
// ==============================================
|
unsigned Texture2D::GetHeight() const
|
||||||
// ================ Texture3D ===================
|
{
|
||||||
// ==============================================
|
return m_height;
|
||||||
|
}
|
||||||
|
|
||||||
Texture3D::Texture3D(const ImageFormat* format, const unsigned width, const unsigned height, const unsigned depth)
|
unsigned Texture2D::GetDepth() const
|
||||||
: Texture3D(format, width, height, depth, false)
|
{
|
||||||
{
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture3D::Texture3D(const ImageFormat* format, const unsigned width, const unsigned height, const unsigned depth, const bool mipMaps)
|
int Texture2D::GetFaceCount() const
|
||||||
: Texture(format, mipMaps)
|
{
|
||||||
{
|
return 1;
|
||||||
m_width = width;
|
}
|
||||||
m_height = height;
|
|
||||||
m_depth = depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture3D::Texture3D(Texture3D&& other) noexcept
|
size_t Texture2D::GetSizeOfMipLevel(const int mipLevel) const
|
||||||
: Texture(std::move(other)),
|
{
|
||||||
m_width(other.m_width),
|
return m_format->GetSizeOfMipLevel(mipLevel, m_width, m_height, 1);
|
||||||
m_height(other.m_height),
|
}
|
||||||
m_depth(other.m_depth)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
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;
|
TextureType TextureCube::GetTextureType() const
|
||||||
}
|
|
||||||
|
|
||||||
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 TextureType::T_CUBE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_data[bufferOffset];
|
int TextureCube::GetFaceCount() const
|
||||||
}
|
|
||||||
|
|
||||||
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 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
|
||||||
|
|||||||
@@ -3,130 +3,133 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
enum class TextureType : std::uint8_t
|
namespace image
|
||||||
{
|
{
|
||||||
T_2D,
|
enum class TextureType : std::uint8_t
|
||||||
T_CUBE,
|
{
|
||||||
T_3D
|
T_2D,
|
||||||
};
|
T_CUBE,
|
||||||
|
T_3D
|
||||||
|
};
|
||||||
|
|
||||||
class Texture
|
class Texture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const ImageFormat* m_format;
|
const ImageFormat* m_format;
|
||||||
bool m_has_mip_maps;
|
bool m_has_mip_maps;
|
||||||
uint8_t* m_data;
|
uint8_t* m_data;
|
||||||
|
|
||||||
Texture(const ImageFormat* format, bool mipMaps);
|
Texture(const ImageFormat* format, bool mipMaps);
|
||||||
Texture(Texture&& other) noexcept;
|
Texture(Texture&& other) noexcept;
|
||||||
|
|
||||||
Texture& operator=(Texture&& other) noexcept;
|
Texture& operator=(Texture&& other) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Texture(const Texture& other) = delete;
|
Texture(const Texture& other) = delete;
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
Texture& operator=(const Texture& other) = delete;
|
Texture& operator=(const Texture& other) = delete;
|
||||||
|
|
||||||
[[nodiscard]] virtual TextureType GetTextureType() const = 0;
|
[[nodiscard]] virtual TextureType GetTextureType() const = 0;
|
||||||
[[nodiscard]] const ImageFormat* GetFormat() const;
|
[[nodiscard]] const ImageFormat* GetFormat() const;
|
||||||
|
|
||||||
[[nodiscard]] virtual unsigned GetWidth() const = 0;
|
[[nodiscard]] virtual unsigned GetWidth() const = 0;
|
||||||
[[nodiscard]] virtual unsigned GetHeight() const = 0;
|
[[nodiscard]] virtual unsigned GetHeight() const = 0;
|
||||||
[[nodiscard]] virtual unsigned GetDepth() const = 0;
|
[[nodiscard]] virtual unsigned GetDepth() const = 0;
|
||||||
[[nodiscard]] virtual int GetFaceCount() const = 0;
|
[[nodiscard]] virtual int GetFaceCount() const = 0;
|
||||||
|
|
||||||
void Allocate();
|
void Allocate();
|
||||||
[[nodiscard]] bool Empty() const;
|
[[nodiscard]] bool Empty() const;
|
||||||
|
|
||||||
[[nodiscard]] virtual size_t GetSizeOfMipLevel(int mipLevel) const = 0;
|
[[nodiscard]] virtual size_t GetSizeOfMipLevel(int mipLevel) const = 0;
|
||||||
[[nodiscard]] virtual uint8_t* GetBufferForMipLevel(int mipLevel, int face) = 0;
|
[[nodiscard]] virtual uint8_t* GetBufferForMipLevel(int mipLevel, int face) = 0;
|
||||||
[[nodiscard]] virtual const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const = 0;
|
[[nodiscard]] virtual const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const = 0;
|
||||||
[[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel);
|
[[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel);
|
||||||
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel) const;
|
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel) const;
|
||||||
|
|
||||||
[[nodiscard]] bool HasMipMaps() const;
|
[[nodiscard]] bool HasMipMaps() const;
|
||||||
[[nodiscard]] virtual int GetMipMapCount() const = 0;
|
[[nodiscard]] virtual int GetMipMapCount() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture2D : public Texture
|
class Texture2D : public Texture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
unsigned m_width;
|
unsigned m_width;
|
||||||
unsigned m_height;
|
unsigned m_height;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Texture2D(const ImageFormat* format, unsigned width, unsigned height);
|
Texture2D(const ImageFormat* format, unsigned width, unsigned height);
|
||||||
Texture2D(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps);
|
Texture2D(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps);
|
||||||
Texture2D(const Texture2D& other) = delete;
|
Texture2D(const Texture2D& other) = delete;
|
||||||
Texture2D(Texture2D&& other) noexcept;
|
Texture2D(Texture2D&& other) noexcept;
|
||||||
~Texture2D() override;
|
~Texture2D() override;
|
||||||
|
|
||||||
Texture2D& operator=(const Texture2D& other) = delete;
|
Texture2D& operator=(const Texture2D& other) = delete;
|
||||||
Texture2D& operator=(Texture2D&& other) noexcept;
|
Texture2D& operator=(Texture2D&& other) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TextureType GetTextureType() const override;
|
[[nodiscard]] TextureType GetTextureType() const override;
|
||||||
|
|
||||||
[[nodiscard]] unsigned GetWidth() const override;
|
[[nodiscard]] unsigned GetWidth() const override;
|
||||||
[[nodiscard]] unsigned GetHeight() const override;
|
[[nodiscard]] unsigned GetHeight() const override;
|
||||||
[[nodiscard]] unsigned GetDepth() const override;
|
[[nodiscard]] unsigned GetDepth() const override;
|
||||||
[[nodiscard]] int GetFaceCount() const override;
|
[[nodiscard]] int GetFaceCount() const override;
|
||||||
|
|
||||||
[[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override;
|
[[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override;
|
||||||
[[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
[[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
||||||
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const 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
|
class TextureCube final : public Texture2D
|
||||||
{
|
{
|
||||||
static const int FACE_COUNT;
|
static const int FACE_COUNT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureCube(const ImageFormat* format, unsigned width, unsigned height);
|
TextureCube(const ImageFormat* format, unsigned width, unsigned height);
|
||||||
TextureCube(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps);
|
TextureCube(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps);
|
||||||
TextureCube(const TextureCube& other) = delete;
|
TextureCube(const TextureCube& other) = delete;
|
||||||
TextureCube(TextureCube&& other) noexcept;
|
TextureCube(TextureCube&& other) noexcept;
|
||||||
~TextureCube() override;
|
~TextureCube() override;
|
||||||
|
|
||||||
TextureCube& operator=(const TextureCube& other) = delete;
|
TextureCube& operator=(const TextureCube& other) = delete;
|
||||||
TextureCube& operator=(TextureCube&& other) noexcept;
|
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]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
||||||
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override;
|
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture3D final : public Texture
|
class Texture3D final : public Texture
|
||||||
{
|
{
|
||||||
unsigned m_width;
|
unsigned m_width;
|
||||||
unsigned m_height;
|
unsigned m_height;
|
||||||
unsigned m_depth;
|
unsigned m_depth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth);
|
Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth);
|
||||||
Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth, bool mipMaps);
|
Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth, bool mipMaps);
|
||||||
Texture3D(const Texture3D& other) = delete;
|
Texture3D(const Texture3D& other) = delete;
|
||||||
Texture3D(Texture3D&& other) noexcept;
|
Texture3D(Texture3D&& other) noexcept;
|
||||||
~Texture3D() override;
|
~Texture3D() override;
|
||||||
|
|
||||||
Texture3D& operator=(const Texture3D& other) = delete;
|
Texture3D& operator=(const Texture3D& other) = delete;
|
||||||
Texture3D& operator=(Texture3D&& other) noexcept;
|
Texture3D& operator=(Texture3D&& other) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TextureType GetTextureType() const override;
|
[[nodiscard]] TextureType GetTextureType() const override;
|
||||||
|
|
||||||
[[nodiscard]] unsigned GetWidth() const override;
|
[[nodiscard]] unsigned GetWidth() const override;
|
||||||
[[nodiscard]] unsigned GetHeight() const override;
|
[[nodiscard]] unsigned GetHeight() const override;
|
||||||
[[nodiscard]] unsigned GetDepth() const override;
|
[[nodiscard]] unsigned GetDepth() const override;
|
||||||
[[nodiscard]] int GetFaceCount() const override;
|
[[nodiscard]] int GetFaceCount() const override;
|
||||||
|
|
||||||
[[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override;
|
[[nodiscard]] size_t GetSizeOfMipLevel(int mipLevel) const override;
|
||||||
[[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
[[nodiscard]] uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
||||||
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override;
|
[[nodiscard]] const uint8_t* GetBufferForMipLevel(int mipLevel, int face) const override;
|
||||||
|
|
||||||
[[nodiscard]] int GetMipMapCount() const override;
|
[[nodiscard]] int GetMipMapCount() const override;
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -2,221 +2,224 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
constexpr uint64_t TextureConverter::Mask1(const unsigned length)
|
namespace image
|
||||||
{
|
{
|
||||||
if (length >= sizeof(uint64_t) * 8)
|
constexpr uint64_t TextureConverter::Mask1(const unsigned length)
|
||||||
return UINT64_MAX;
|
|
||||||
|
|
||||||
return UINT64_MAX >> (sizeof(uint64_t) * 8 - length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureConverter::SetPixelFunctions(const unsigned inBitCount, const unsigned outBitCount)
|
|
||||||
{
|
|
||||||
switch (inBitCount)
|
|
||||||
{
|
{
|
||||||
case 16:
|
if (length >= sizeof(uint64_t) * 8)
|
||||||
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
return UINT64_MAX;
|
||||||
{
|
|
||||||
return static_cast<uint64_t>(*static_cast<const uint16_t*>(offset));
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 32:
|
return UINT64_MAX >> (sizeof(uint64_t) * 8 - length);
|
||||||
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
}
|
||||||
{
|
|
||||||
return static_cast<uint64_t>(*static_cast<const uint32_t*>(offset));
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 64:
|
void TextureConverter::SetPixelFunctions(const unsigned inBitCount, const unsigned outBitCount)
|
||||||
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
{
|
||||||
|
switch (inBitCount)
|
||||||
{
|
{
|
||||||
return *static_cast<const uint64_t*>(offset);
|
case 16:
|
||||||
};
|
|
||||||
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<uint64_t>(*(static_cast<const uint8_t*>(offset) + (pixelOffset / 8))) << pixelOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
||||||
{
|
{
|
||||||
return 0ull;
|
return static_cast<uint64_t>(*static_cast<const uint16_t*>(offset));
|
||||||
};
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
||||||
|
{
|
||||||
|
return static_cast<uint64_t>(*static_cast<const uint32_t*>(offset));
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 64:
|
||||||
|
m_read_pixel_func = [](const void* offset, unsigned bitCount)
|
||||||
|
{
|
||||||
|
return *static_cast<const uint64_t*>(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<uint64_t>(*(static_cast<const uint8_t*>(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<uint16_t*>(offset) = static_cast<uint16_t>(pixel);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount)
|
||||||
|
{
|
||||||
|
*static_cast<uint32_t*>(offset) = static_cast<uint32_t>(pixel);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 64:
|
||||||
|
m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount)
|
||||||
|
{
|
||||||
|
*static_cast<uint64_t*>(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<uint8_t*>(offset) + (pixelOffset / 8)) = static_cast<uint8_t>(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<uint16_t*>(offset) = static_cast<uint16_t>(pixel);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 32:
|
void TextureConverter::CreateOutputTexture()
|
||||||
m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount)
|
{
|
||||||
|
switch (m_input_texture->GetTextureType())
|
||||||
{
|
{
|
||||||
*static_cast<uint32_t*>(offset) = static_cast<uint32_t>(pixel);
|
case TextureType::T_2D:
|
||||||
};
|
m_output_texture =
|
||||||
break;
|
std::make_unique<Texture2D>(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps());
|
||||||
|
break;
|
||||||
|
|
||||||
case 64:
|
case TextureType::T_CUBE:
|
||||||
m_write_pixel_func = [](void* offset, const uint64_t pixel, unsigned bitCount)
|
m_output_texture =
|
||||||
{
|
std::make_unique<TextureCube>(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps());
|
||||||
*static_cast<uint64_t*>(offset) = pixel;
|
break;
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
case TextureType::T_3D:
|
||||||
if (inBitCount <= 64)
|
m_output_texture = std::make_unique<Texture3D>(
|
||||||
|
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<const ImageFormatUnsigned*>(m_input_format);
|
||||||
|
const auto* outputFormat = dynamic_cast<const ImageFormatUnsigned*>(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)
|
uint64_t outPixel = 0;
|
||||||
{
|
const auto inPixel = m_read_pixel_func(&inputBuffer[inputOffset], inputFormat->m_bits_per_pixel);
|
||||||
*(static_cast<uint8_t*>(offset) + (pixelOffset / 8)) = static_cast<uint8_t>(pixel >> pixelOffset);
|
|
||||||
}
|
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<const ImageFormatUnsigned*>(m_input_format);
|
||||||
|
const auto* outputFormat = dynamic_cast<const ImageFormatUnsigned*>(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
|
else
|
||||||
{
|
{
|
||||||
|
// Unsupported as of now
|
||||||
assert(false);
|
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<Texture2D>(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<TextureCube>(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<Texture3D>(
|
|
||||||
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();
|
std::unique_ptr<Texture> TextureConverter::Convert()
|
||||||
}
|
|
||||||
|
|
||||||
void TextureConverter::ReorderUnsignedToUnsigned() const
|
|
||||||
{
|
|
||||||
const auto* inputFormat = dynamic_cast<const ImageFormatUnsigned*>(m_input_format);
|
|
||||||
const auto* outputFormat = dynamic_cast<const ImageFormatUnsigned*>(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++)
|
|
||||||
{
|
{
|
||||||
const auto mipLevelSize = m_input_texture->GetSizeOfMipLevel(mipLevel) * m_input_texture->GetFaceCount();
|
CreateOutputTexture();
|
||||||
const auto* inputBuffer = m_input_texture->GetBufferForMipLevel(mipLevel);
|
|
||||||
auto* outputBuffer = m_output_texture->GetBufferForMipLevel(mipLevel);
|
|
||||||
|
|
||||||
const auto inputBytePerPixel = inputFormat->m_bits_per_pixel / 8;
|
if (m_input_format->GetType() == ImageFormatType::UNSIGNED && m_output_format->GetType() == ImageFormatType::UNSIGNED)
|
||||||
const auto outputBytePerPixel = outputFormat->m_bits_per_pixel / 8;
|
|
||||||
|
|
||||||
auto outputOffset = 0u;
|
|
||||||
for (auto inputOffset = 0u; inputOffset < mipLevelSize; inputOffset += inputBytePerPixel, outputOffset += outputBytePerPixel)
|
|
||||||
{
|
{
|
||||||
uint64_t outPixel = 0;
|
ConvertUnsignedToUnsigned();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unsupported as of now
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(m_output_texture);
|
||||||
}
|
}
|
||||||
}
|
} // namespace image
|
||||||
|
|
||||||
void TextureConverter::ConvertUnsignedToUnsigned()
|
|
||||||
{
|
|
||||||
const auto* inputFormat = dynamic_cast<const ImageFormatUnsigned*>(m_input_format);
|
|
||||||
const auto* outputFormat = dynamic_cast<const ImageFormatUnsigned*>(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<Texture> 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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,27 +5,30 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class TextureConverter
|
namespace image
|
||||||
{
|
{
|
||||||
public:
|
class TextureConverter
|
||||||
TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat);
|
{
|
||||||
|
public:
|
||||||
|
TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat);
|
||||||
|
|
||||||
std::unique_ptr<Texture> Convert();
|
std::unique_ptr<Texture> Convert();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint64_t Mask1(unsigned length);
|
static constexpr uint64_t Mask1(unsigned length);
|
||||||
void SetPixelFunctions(unsigned inBitCount, unsigned outBitCount);
|
void SetPixelFunctions(unsigned inBitCount, unsigned outBitCount);
|
||||||
|
|
||||||
void CreateOutputTexture();
|
void CreateOutputTexture();
|
||||||
|
|
||||||
void ReorderUnsignedToUnsigned() const;
|
void ReorderUnsignedToUnsigned() const;
|
||||||
void ConvertUnsignedToUnsigned();
|
void ConvertUnsignedToUnsigned();
|
||||||
|
|
||||||
std::function<uint64_t(const void* offset, unsigned bitCount)> m_read_pixel_func;
|
std::function<uint64_t(const void* offset, unsigned bitCount)> m_read_pixel_func;
|
||||||
std::function<void(void* offset, uint64_t pixel, unsigned bitCount)> m_write_pixel_func;
|
std::function<void(void* offset, uint64_t pixel, unsigned bitCount)> m_write_pixel_func;
|
||||||
|
|
||||||
const Texture* m_input_texture;
|
const Texture* m_input_texture;
|
||||||
std::unique_ptr<Texture> m_output_texture;
|
std::unique_ptr<Texture> m_output_texture;
|
||||||
const ImageFormat* m_input_format;
|
const ImageFormat* m_input_format;
|
||||||
const ImageFormat* m_output_format;
|
const ImageFormat* m_output_format;
|
||||||
};
|
};
|
||||||
|
} // namespace image
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace IW3;
|
using namespace IW3;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -38,7 +39,7 @@ namespace
|
|||||||
if (!file.IsOpen())
|
if (!file.IsOpen())
|
||||||
return AssetCreationResult::NoAction();
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
const auto texture = dds::LoadDds(*file.m_stream);
|
const auto texture = image::LoadDds(*file.m_stream);
|
||||||
if (!texture)
|
if (!texture)
|
||||||
{
|
{
|
||||||
con::error("Failed to load dds file for image asset \"{}\"", assetName);
|
con::error("Failed to load dds file for image asset \"{}\"", assetName);
|
||||||
@@ -91,11 +92,11 @@ namespace
|
|||||||
loadDef->levelCount = static_cast<char>(mipCount);
|
loadDef->levelCount = static_cast<char>(mipCount);
|
||||||
loadDef->flags = 0;
|
loadDef->flags = 0;
|
||||||
if (!texture->HasMipMaps())
|
if (!texture->HasMipMaps())
|
||||||
loadDef->flags |= iwi6::IMG_FLAG_NOMIPMAPS;
|
loadDef->flags |= image::iwi6::IMG_FLAG_NOMIPMAPS;
|
||||||
if (texture->GetTextureType() == TextureType::T_CUBE)
|
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)
|
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[0] = image->width;
|
||||||
loadDef->dimensions[1] = image->height;
|
loadDef->dimensions[1] = image->height;
|
||||||
loadDef->dimensions[2] = image->depth;
|
loadDef->dimensions[2] = image->depth;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace
|
|||||||
file.m_stream->read(fileData.get(), fileSize);
|
file.m_stream->read(fileData.get(), fileSize);
|
||||||
|
|
||||||
std::istringstream ss(std::string(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)
|
if (!texture)
|
||||||
{
|
{
|
||||||
con::error("Failed to load texture from: {}", fileName);
|
con::error("Failed to load texture from: {}", fileName);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace
|
|||||||
const auto dataHash = static_cast<unsigned>(crc32(0u, reinterpret_cast<const Bytef*>(fileData.get()), static_cast<unsigned>(fileSize)));
|
const auto dataHash = static_cast<unsigned>(crc32(0u, reinterpret_cast<const Bytef*>(fileData.get()), static_cast<unsigned>(fileSize)));
|
||||||
|
|
||||||
std::istringstream ss(std::string(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)
|
if (!texture)
|
||||||
{
|
{
|
||||||
con::error("Failed to load texture from: {}", fileName);
|
con::error("Failed to load texture from: {}", fileName);
|
||||||
|
|||||||
15
src/ObjLoading/Image/ImageLoaderCommon.cpp
Normal file
15
src/ObjLoading/Image/ImageLoaderCommon.cpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "ImageLoaderCommon.h"
|
||||||
|
|
||||||
|
namespace image
|
||||||
|
{
|
||||||
|
std::optional<AssetCreationResult> CommonImageLoaderResult::GetResultIfCancelled() const
|
||||||
|
{
|
||||||
|
if (m_failure)
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
|
||||||
|
if (!m_texture)
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
} // namespace image
|
||||||
23
src/ObjLoading/Image/ImageLoaderCommon.h
Normal file
23
src/ObjLoading/Image/ImageLoaderCommon.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/AssetCreationResult.h"
|
||||||
|
#include "Image/IwiTypes.h"
|
||||||
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace image
|
||||||
|
{
|
||||||
|
struct CommonImageLoaderResult
|
||||||
|
{
|
||||||
|
std::optional<AssetCreationResult> GetResultIfCancelled() const;
|
||||||
|
|
||||||
|
bool m_failure;
|
||||||
|
std::string m_iwi_path;
|
||||||
|
std::unique_ptr<Texture> m_texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
CommonImageLoaderResult LoadImageCommon();
|
||||||
|
} // namespace image
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
using namespace IW3;
|
using namespace IW3;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -26,15 +27,15 @@ namespace
|
|||||||
const auto& loadDef = *image.texture.loadDef;
|
const auto& loadDef = *image.texture.loadDef;
|
||||||
textureLoader.Width(loadDef.dimensions[0]).Height(loadDef.dimensions[1]).Depth(loadDef.dimensions[2]);
|
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);
|
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);
|
textureLoader.Type(TextureType::T_CUBE);
|
||||||
else
|
else
|
||||||
textureLoader.Type(TextureType::T_2D);
|
textureLoader.Type(TextureType::T_2D);
|
||||||
|
|
||||||
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
||||||
textureLoader.HasMipMaps(!(loadDef.flags & iwi6::IMG_FLAG_NOMIPMAPS));
|
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi6::IMG_FLAG_NOMIPMAPS));
|
||||||
return textureLoader.LoadTexture(loadDef.data);
|
return textureLoader.LoadTexture(loadDef.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ namespace
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iwi::LoadIwi(*filePathImage.m_stream);
|
return image::LoadIwi(*filePathImage.m_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/IW3/IW3.h"
|
#include "Game/IW3/IW3.h"
|
||||||
#include "Image/IImageWriter.h"
|
#include "Image/ImageWriter.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -17,6 +17,6 @@ namespace image
|
|||||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW3::AssetImage::Type>& asset) override;
|
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW3::AssetImage::Type>& asset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IImageWriter> m_writer;
|
std::unique_ptr<ImageWriter> m_writer;
|
||||||
};
|
};
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -23,15 +24,15 @@ namespace
|
|||||||
const auto& loadDef = *image.texture.loadDef;
|
const auto& loadDef = *image.texture.loadDef;
|
||||||
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
|
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);
|
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);
|
textureLoader.Type(TextureType::T_CUBE);
|
||||||
else
|
else
|
||||||
textureLoader.Type(TextureType::T_2D);
|
textureLoader.Type(TextureType::T_2D);
|
||||||
|
|
||||||
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
||||||
textureLoader.HasMipMaps(!(loadDef.flags & iwi8::IMG_FLAG_NOMIPMAPS));
|
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi8::IMG_FLAG_NOMIPMAPS));
|
||||||
return textureLoader.LoadTexture(loadDef.data);
|
return textureLoader.LoadTexture(loadDef.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ namespace
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iwi::LoadIwi(*filePathImage.m_stream);
|
return image::LoadIwi(*filePathImage.m_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Image/IImageWriter.h"
|
#include "Image/ImageWriter.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -17,6 +17,6 @@ namespace image
|
|||||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW4::AssetImage::Type>& asset) override;
|
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW4::AssetImage::Type>& asset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IImageWriter> m_writer;
|
std::unique_ptr<ImageWriter> m_writer;
|
||||||
};
|
};
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
using namespace IW5;
|
using namespace IW5;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -24,15 +25,15 @@ namespace
|
|||||||
|
|
||||||
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
|
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);
|
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);
|
textureLoader.Type(TextureType::T_CUBE);
|
||||||
else
|
else
|
||||||
textureLoader.Type(TextureType::T_2D);
|
textureLoader.Type(TextureType::T_2D);
|
||||||
|
|
||||||
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
||||||
textureLoader.HasMipMaps(!(loadDef.flags & iwi8::IMG_FLAG_NOMIPMAPS));
|
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi8::IMG_FLAG_NOMIPMAPS));
|
||||||
return textureLoader.LoadTexture(loadDef.data);
|
return textureLoader.LoadTexture(loadDef.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ namespace
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iwi::LoadIwi(*filePathImage.m_stream);
|
return image::LoadIwi(*filePathImage.m_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/IW5/IW5.h"
|
#include "Game/IW5/IW5.h"
|
||||||
#include "Image/IImageWriter.h"
|
#include "Image/ImageWriter.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -17,6 +17,6 @@ namespace image
|
|||||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW5::AssetImage::Type>& asset) override;
|
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW5::AssetImage::Type>& asset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IImageWriter> m_writer;
|
std::unique_ptr<ImageWriter> m_writer;
|
||||||
};
|
};
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
using namespace T5;
|
using namespace T5;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -23,15 +24,15 @@ namespace
|
|||||||
const auto& loadDef = *image.texture.loadDef;
|
const auto& loadDef = *image.texture.loadDef;
|
||||||
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
|
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);
|
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);
|
textureLoader.Type(TextureType::T_CUBE);
|
||||||
else
|
else
|
||||||
textureLoader.Type(TextureType::T_2D);
|
textureLoader.Type(TextureType::T_2D);
|
||||||
|
|
||||||
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
||||||
textureLoader.HasMipMaps(!(loadDef.flags & iwi13::IMG_FLAG_NOMIPMAPS));
|
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi13::IMG_FLAG_NOMIPMAPS));
|
||||||
return textureLoader.LoadTexture(loadDef.data);
|
return textureLoader.LoadTexture(loadDef.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ namespace
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iwi::LoadIwi(*filePathImage.m_stream);
|
return image::LoadIwi(*filePathImage.m_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T5/T5.h"
|
#include "Game/T5/T5.h"
|
||||||
#include "Image/IImageWriter.h"
|
#include "Image/ImageWriter.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -17,6 +17,6 @@ namespace image
|
|||||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T5::AssetImage::Type>& asset) override;
|
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T5::AssetImage::Type>& asset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IImageWriter> m_writer;
|
std::unique_ptr<ImageWriter> m_writer;
|
||||||
};
|
};
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
using namespace image;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -24,15 +25,15 @@ namespace
|
|||||||
const auto& loadDef = *image.texture.loadDef;
|
const auto& loadDef = *image.texture.loadDef;
|
||||||
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
|
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);
|
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);
|
textureLoader.Type(TextureType::T_CUBE);
|
||||||
else
|
else
|
||||||
textureLoader.Type(TextureType::T_2D);
|
textureLoader.Type(TextureType::T_2D);
|
||||||
|
|
||||||
textureLoader.Format(static_cast<oat::DXGI_FORMAT>(loadDef.format));
|
textureLoader.Format(static_cast<oat::DXGI_FORMAT>(loadDef.format));
|
||||||
textureLoader.HasMipMaps(!(loadDef.flags & iwi27::IMG_FLAG_NOMIPMAPS));
|
textureLoader.HasMipMaps(!(loadDef.flags & image::iwi27::IMG_FLAG_NOMIPMAPS));
|
||||||
return textureLoader.LoadTexture(loadDef.data);
|
return textureLoader.LoadTexture(loadDef.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ namespace
|
|||||||
|
|
||||||
if (ipakStream)
|
if (ipakStream)
|
||||||
{
|
{
|
||||||
auto loadedTexture = iwi::LoadIwi(*ipakStream);
|
auto loadedTexture = image::LoadIwi(*ipakStream);
|
||||||
ipakStream->close();
|
ipakStream->close();
|
||||||
|
|
||||||
if (loadedTexture != nullptr)
|
if (loadedTexture != nullptr)
|
||||||
@@ -63,7 +64,7 @@ namespace
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iwi::LoadIwi(*filePathImage.m_stream);
|
return image::LoadIwi(*filePathImage.m_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
std::unique_ptr<Texture> LoadImageData(ISearchPath& searchPath, const GfxImage& image)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Image/IImageWriter.h"
|
#include "Image/ImageWriter.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -17,6 +17,6 @@ namespace image
|
|||||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T6::AssetImage::Type>& asset) override;
|
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T6::AssetImage::Type>& asset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IImageWriter> m_writer;
|
std::unique_ptr<ImageWriter> m_writer;
|
||||||
};
|
};
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|||||||
Reference in New Issue
Block a user