light/modules/asset_baker/public/bakers.hpp
light7734 cd886aa8c9
Some checks reported errors
continuous-integration/drone/push Build was killed
refactor: flatten directory structure
2025-07-20 04:46:15 +03:30

184 lines
4 KiB
C++

#pragma once
#include <asset_parser/assets/text.hpp>
#include <asset_parser/assets/texture.hpp>
#include <filesystem>
#include <logger/logger.hpp>
#include <string_view>
#include <unordered_set>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
namespace lt {
class Loader
{
public:
[[nodiscard]] virtual auto get_name() const -> std::string_view = 0;
Loader() = default;
Loader(Loader &&) = default;
Loader(const Loader &) = delete;
auto operator=(Loader &&) -> Loader & = default;
auto operator=(const Loader &) -> Loader & = delete;
virtual ~Loader() = default;
private:
};
class TextureLoader: public Loader
{
public:
TextureLoader() = default;
[[nodiscard]] virtual auto load(std::filesystem::path file_path) const
-> Assets::TextureAsset::PackageData
= 0;
};
class StbLoader: public TextureLoader
{
public:
StbLoader() = default;
void load(std::filesystem::path path);
[[nodiscard]] static auto get_supported_extensions() -> std::unordered_set<std::string_view>
{
return { ".png" };
}
[[nodiscard]] auto get_name() const -> std::string_view override
{
return "StbLoader";
}
[[nodiscard]] auto load(std::filesystem::path file_path) const
-> Assets::TextureAsset::PackageData override
{
auto width = int {};
auto height = int {};
auto channels = int {};
auto *pixels = stbi_load(file_path.string().c_str(), &width, &height, &channels, 4);
if (!pixels)
{
throw std::runtime_error {
std::format("Failed to load image file at: {} using stbi_load", file_path.string()),
};
}
const auto metadata = Assets::Asset::Metadata {
.type = Assets::Asset::Type::Texture,
};
const auto texture_metadata = Assets::TextureAsset::Metadata {
.format = Assets::TextureAsset::Format::RGBA8,
.num_components = static_cast<uint32_t>(channels),
.pixel_size = {
static_cast<uint32_t>(width),
static_cast<uint32_t>(height),
{},
},
};
auto pixels_blob = Assets::Blob {};
pixels_blob.resize(static_cast<size_t>(width) * height * channels);
// TODO(Light): figure out if it's possible to directly populate a blob with stbi functions
memcpy(pixels_blob.data(), pixels, pixels_blob.size());
stbi_image_free(pixels);
return Assets::TextureAsset::PackageData {
.metadata = metadata,
.texture_metadata = texture_metadata,
.pixels = std::move(pixels_blob),
};
}
};
class TextureLoaderFactory
{
public:
static auto create(std::string_view file_extension) -> std::unique_ptr<TextureLoader>
{
if (StbLoader::get_supported_extensions().contains(file_extension))
{
return std::make_unique<StbLoader>();
}
return {};
}
};
class TextLoader: Loader
{
public:
[[nodiscard]] static auto get_supported_extensions() -> std::unordered_set<std::string_view>
{
return { ".glsl", ".txt", ".hlsl" };
}
[[nodiscard]] auto get_name() const -> std::string_view override
{
return "TextLoader";
}
[[nodiscard]] auto load(const std::filesystem::path &file_path) const
-> Assets::TextAsset::PackageData
{
auto stream = std::ifstream { file_path, std::ios::binary };
if (!stream.good())
{
throw std::runtime_error {
std::format(
"Failed to open ifstream for text loading of file: {}",
file_path.string()
),
};
}
auto file_size = std::filesystem::file_size(file_path);
auto text_blob = Assets::Blob(file_size);
stream.read((char *)(text_blob.data()), static_cast<long>(file_size)); // NOLINT
const auto metadata = Assets::Asset::Metadata {
.type = Assets::Asset::Type::Text,
};
const auto text_metadata = Assets::TextAsset::Metadata {
.lines = {},
};
return Assets::TextAsset::PackageData {
.metadata = metadata,
.text_metadata = {},
.text_blob = std::move(text_blob),
};
}
};
class TextLoaderFactory
{
public:
static auto create(std::string_view file_extension) -> std::unique_ptr<TextLoader>
{
if (TextLoader::get_supported_extensions().contains(file_extension))
{
return std::make_unique<TextLoader>();
}
return {};
}
};
} // namespace lt