2#pragma clang diagnostic ignored "-Wformat"
4#include "GliTextureLoader.h"
8#include "Resources/TextureManager.h"
9#include "Resources/ResourceStore.h"
11#include "Foundation/Logging/Logger.h"
12#include "Foundation/Platform/IO.h"
15#include "gli/convert.hpp"
26 const std::string dds_zstd_suffix =
".dds.zst";
28 const size_t dds_zstd_suffix_len = dds_zstd_suffix.length();
30 bool decodeFromMemory(
Context* context,
const TextureLoadInfo& loadInfo,
const void* dataPtr,
const size_t dataSize)
32 if (dataPtr ==
nullptr || dataSize == 0) {
37 const void* data_ptr =
nullptr;
41 if ((dds_zstd_suffix_len <= N) && (loadInfo.
resourcePath.substr(N - dds_zstd_suffix_len) == dds_zstd_suffix)) {
42 ZSTD_DCtx* zstd_dctx = ZSTD_createDCtx();
45 auto size = ZSTD_getFrameContentSize(dataPtr, dataSize);
46 if (size == ZSTD_CONTENTSIZE_UNKNOWN) {
47 LOG_ERROR(logger,
"ZSTD_CONTENTSIZE_UNKNOWN");
50 else if (size == ZSTD_CONTENTSIZE_ERROR) {
51 LOG_ERROR(logger,
"ZSTD_CONTENTSIZE_ERROR");
54 else if (std::numeric_limits<size_t>::max() < size) {
55 LOG_ERROR(logger,
"File too large: %ull", size);
58 data_siz =
static_cast<size_t>(size);
60 decompressed.resize(data_siz,
false);
61 auto result = ZSTD_decompressDCtx(zstd_dctx, decompressed.data(), decompressed.size(), dataPtr, dataSize);
62 if (ZSTD_isError(result)) {
63 LOG_ERROR(logger,
"ZSTD decompression failed: %s", ZSTD_getErrorName(result));
66 LOG_DEBUG(logger,
"ZSTD decompressed dds image %s", loadInfo.
resourcePath.c_str());
67 data_ptr = decompressed.data();
69 ZSTD_freeDCtx(zstd_dctx);
76 gli::texture textureData = gli::load(
reinterpret_cast<const char*
>(data_ptr), data_siz);
78 if (textureData.empty()) {
83 auto target = Cogs::ResourceDimensions::Unknown;
84 switch (textureData.target()) {
86 target = Cogs::ResourceDimensions::Texture1D;
88 case gli::TARGET_1D_ARRAY:
89 target = Cogs::ResourceDimensions::Texture1DArray;
92 target = Cogs::ResourceDimensions::Texture2D;
94 case gli::TARGET_2D_ARRAY:
95 target = Cogs::ResourceDimensions::Texture2DArray;
98 target = Cogs::ResourceDimensions::Texture3D;
100 case gli::TARGET_RECT:
101 target = Cogs::ResourceDimensions::Texture2D;
103 case gli::TARGET_RECT_ARRAY:
104 target = Cogs::ResourceDimensions::Texture2DArray;
106 case gli::TARGET_CUBE:
107 target = Cogs::ResourceDimensions::TextureCube;
109 case gli::TARGET_CUBE_ARRAY:
110 target = Cogs::ResourceDimensions::TextureCubeArray;
113 assert(
false &&
"Unhandled gli texture target");
117 Cogs::TextureFormat format = Cogs::formatMap[textureData.format()];
118 if (format == Cogs::TextureFormat::Unknown) {
119 LOG_ERROR(logger,
"Unsupported texture format %d in %s.", format, loadInfo.
resourcePath.c_str());
124 textureData = gli::flip(textureData);
127 auto texture = context->textureManager->lock(loadInfo.
handle);
128 texture->description.target = target;
130 bool generateMipMaps = (textureData.levels() <= 1) && (
TextureLoadFlags(loadInfo.
loadFlags) & TextureLoadFlags::NoMipMaps) != TextureLoadFlags::NoMipMaps;
131 texture->setData(target,
134 textureData.extent(0).s,
135 textureData.extent(0).t,
136 textureData.extent(0).p,
137 static_cast<uint32_t
>(textureData.layers()),
138 static_cast<uint32_t
>(textureData.faces()),
139 static_cast<uint32_t
>(textureData.levels()),
151 if ((dds_zstd_suffix_len <= N) && (loadInfo.
resourcePath.substr(N - dds_zstd_suffix_len) == dds_zstd_suffix)) {
155 auto extension = Cogs::IO::extension(loadInfo.
resourcePath);
156 for (
auto& c : extension) {
157 c =
static_cast<decltype(extension)::value_type
>(std::tolower(c));
159 return extension ==
".dds" || extension ==
".ktx";
168 return decodeFromMemory(context, loadInfo, data.data(), data.size());
171bool Cogs::Core::GliTextureLoader::load(
Context* context,
const TextureLoadInfo& loadInfo,
const void* dataPtr,
size_t dataSize)
173 return decodeFromMemory(context, loadInfo, dataPtr, dataSize);
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< class ResourceStore > resourceStore
ResourceStore service instance.
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
TextureLoadFlags
Texture loading flags. May be combined with resource load flags.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
std::string resourcePath
Resource path. Used to locate resource.
ResourceHandleBase handle
Handle to resource structure for holding actual resource data.
ResourceLoadFlags loadFlags
Desired loading flags. Used to specify how the resource will be loaded.