123 lines
2.8 KiB
C++
123 lines
2.8 KiB
C++
#include "assets/dynamic_data_loaders/dynamic_texture_loader.hpp"
|
|
|
|
#if defined(__GNUC__) || defined(__GNUG__)
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC system_header
|
|
#elif defined(_MSC_VER)
|
|
#pragma warning(push, 0)
|
|
#endif
|
|
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#define STB_IMAGE_STATIC
|
|
#include "stb_image.h"
|
|
|
|
#if defined(__GNUC__) || defined(__GNUG__)
|
|
#pragma GCC diagnostic pop
|
|
#elif defined(_MSC_VER)
|
|
#pragma warning(pop)
|
|
#endif
|
|
|
|
#include "util/logger.hpp"
|
|
|
|
dynamic_texture_loader::dynamic_texture_loader(components::texture::flags enabled_components) :
|
|
m_enabled_components{ enabled_components },
|
|
m_loader_id_lookup{
|
|
{ "jpg", loader_id_type{ 0 } },
|
|
{ "png", loader_id_type{ 1 } },
|
|
{ "tga", loader_id_type{ 2 } },
|
|
{ "bmp", loader_id_type{ 3 } },
|
|
{ "psd", loader_id_type{ 4 } },
|
|
{ "gif", loader_id_type{ 5 } },
|
|
{ "hdr", loader_id_type{ 6 } },
|
|
{ "pic", loader_id_type{ 7 } }
|
|
} {}
|
|
|
|
std::optional<dynamic_texture_loader::loader_id_type> dynamic_texture_loader::find_loader(const std::string_view& name)
|
|
{
|
|
const auto it = m_loader_id_lookup.find(name);
|
|
|
|
if (it != m_loader_id_lookup.end())
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::error_code dynamic_texture_loader::prefetch(
|
|
const loader_id_type loader_id,
|
|
const ztu::string_list& directories,
|
|
prefetch_queue& queue
|
|
) {
|
|
// Nothing to prefetch...
|
|
return {};
|
|
}
|
|
|
|
std::error_code dynamic_texture_loader::load(
|
|
const loader_id_type loader_id,
|
|
const ztu::string_list& directories,
|
|
dynamic_texture_store& store,
|
|
texture_prefetch_lookup& id_lookup,
|
|
const bool pedantic
|
|
) {
|
|
stbi_set_flip_vertically_on_load(true);
|
|
|
|
int width, height, channels;
|
|
|
|
for (const auto filename : directories)
|
|
{
|
|
const auto id_it = id_lookup.find(filename);
|
|
|
|
if (id_it != id_lookup.end()) [[unlikely]]
|
|
{
|
|
continue;
|
|
}
|
|
|
|
auto ptr = reinterpret_cast<std::uint8_t*>(stbi_load(
|
|
filename.data(), // Null terminated by string_list
|
|
&width,
|
|
&height,
|
|
&channels,
|
|
0
|
|
));
|
|
|
|
if (ptr == nullptr) {
|
|
return std::make_error_code(std::errc::no_such_file_or_directory);
|
|
}
|
|
|
|
auto data = std::unique_ptr<std::uint8_t[]>(ptr);
|
|
|
|
using flags = components::texture::flags;
|
|
|
|
auto components = flags{};
|
|
switch (channels)
|
|
{
|
|
case 1:
|
|
components = flags::luminance;
|
|
break;
|
|
case 2:
|
|
components = flags::luminance | flags::alpha;
|
|
break;
|
|
case 3:
|
|
components = flags::red | flags::green | flags::blue;
|
|
break;
|
|
case 4:
|
|
components = flags::red | flags::green | flags::blue | flags::alpha;
|
|
break;
|
|
default: [[unlikely]]
|
|
ztu::logger::error("Unsupported pixel component composition %", static_cast<int>(components));
|
|
continue;
|
|
}
|
|
|
|
const auto id = store.add(dynamic_texture_buffer(
|
|
std::move(data),
|
|
width,
|
|
height,
|
|
components
|
|
));
|
|
id_lookup.emplace_hint(id_it, filename, id);
|
|
}
|
|
|
|
return {};
|
|
}
|