From fc2fe2616056a3f0f4716e896b20e47e15ab8efa Mon Sep 17 00:00:00 2001 From: light7734 Date: Wed, 9 Jul 2025 21:30:17 +0330 Subject: [PATCH] feat: text asset fix: miscalculated offset for asset blobs refactor: remove file manager completely --- data/assets/fonts/open_sans/LICENSE.asset | Bin 0 -> 11414 bytes data/assets/shaders/quads/ps.asset | Bin 0 -> 188 bytes data/assets/shaders/quads/vs.asset | Bin 0 -> 377 bytes data/assets/shaders/texture/ps.asset | Bin 0 -> 228 bytes data/assets/shaders/texture/vs.asset | Bin 0 -> 379 bytes data/assets/shaders/tinted_texture/ps.asset | Bin 0 -> 258 bytes data/assets/shaders/tinted_texture/vs.asset | Bin 0 -> 434 bytes data/assets/shaders/tinted_texture/vs.glsl | 1 - data/assets/textures/awesomeface.asset | Bin 4194376 -> 4194376 bytes data/engine/icons/asset/dir.asset | Bin 1048648 -> 1048648 bytes data/engine/icons/asset/img.asset | Bin 262216 -> 262216 bytes data/engine/icons/asset/scene.asset | Bin 1048648 -> 1048648 bytes data/engine/icons/asset/txt.asset | Bin 262216 -> 262216 bytes .../include/asset_baker/bakers.hpp | 63 ++++++ modules/asset_baker/src/baker.cpp | 34 ++- modules/asset_parser/CMakeLists.txt | 1 + .../include/asset_parser/assets/text.hpp | 54 +++++ .../include/asset_parser/assets/texture.hpp | 64 ++++++ .../include/asset_parser/parser.hpp | 214 +----------------- modules/asset_parser/src/assets/text.cpp | 156 +++++++++++++ modules/asset_parser/src/assets/texture.cpp | 154 ++++++++++++- modules/engine/CMakeLists.txt | 2 - .../engine/include/engine/graphics/shader.hpp | 17 +- .../platform/graphics/directx/shader.hpp | 1 - .../platform/graphics/opengl/shader.hpp | 7 +- .../include/engine/utils/file_manager.hpp | 80 ------- .../include/engine/utils/resource_manager.hpp | 19 +- .../src/graphics/renderer_programs/quad.cpp | 4 +- .../graphics/renderer_programs/texture.cpp | 4 +- .../renderer_programs/tinted_texture.cpp | 4 +- modules/engine/src/graphics/shader.cpp | 11 +- .../src/platform/graphics/opengl/shader.cpp | 64 ++---- modules/engine/src/utils/file_manager.cpp | 63 ------ modules/engine/src/utils/resource_manager.cpp | 103 +++++---- 34 files changed, 635 insertions(+), 485 deletions(-) create mode 100644 data/assets/fonts/open_sans/LICENSE.asset create mode 100644 data/assets/shaders/quads/ps.asset create mode 100644 data/assets/shaders/quads/vs.asset create mode 100644 data/assets/shaders/texture/ps.asset create mode 100644 data/assets/shaders/texture/vs.asset create mode 100644 data/assets/shaders/tinted_texture/ps.asset create mode 100644 data/assets/shaders/tinted_texture/vs.asset create mode 100644 modules/asset_parser/include/asset_parser/assets/text.hpp create mode 100644 modules/asset_parser/src/assets/text.cpp delete mode 100644 modules/engine/include/engine/utils/file_manager.hpp delete mode 100644 modules/engine/src/utils/file_manager.cpp diff --git a/data/assets/fonts/open_sans/LICENSE.asset b/data/assets/fonts/open_sans/LICENSE.asset new file mode 100644 index 0000000000000000000000000000000000000000..b6240b4e36d98b82b9298ed4062015713292933d GIT binary patch literal 11414 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 D;uZ0$ literal 0 HcmV?d00001 diff --git a/data/assets/shaders/quads/ps.asset b/data/assets/shaders/quads/ps.asset new file mode 100644 index 0000000000000000000000000000000000000000..2fb6df5f9670e4d1d950f618768a50d7439ac761 GIT binary patch literal 188 zcmZQ%U|?VZVh~^i5e~K$f9e?+EI@210P$O(Y#6OvmReMtnV+X%Vq&0>oL`j6#g&<- zP?nl(qEJ?xAMaL_n4X)OSK^$XlV4=b#g$)L0+CF^B3YK7nWB)Jn3<=c$yLq8iJ?Tn J7Mq#1TmaFxGEe{j literal 0 HcmV?d00001 diff --git a/data/assets/shaders/quads/vs.asset b/data/assets/shaders/quads/vs.asset new file mode 100644 index 0000000000000000000000000000000000000000..ece5ee0b7a4bbbfbd1463fc3768a762ef70acd6f GIT binary patch literal 377 zcmZvXJqyAx5Qd|h`4tB)tvFQ3AQV9noIAOe*v4|w<{(X@BH|x+u<^U-L2{S-c=BG4 zG1hO7x1PV|v%~em*wn{Q^Y6vI`0+!hOpT;LhzK$=it|z)sj)#xnY6w#gD3>l;8Z3+ zrU}*P^YNd?$#>(DN;2`ASKE9dqA_ex=ctPZw$ZpHQ$e#y*QoZ1p`FS+ouBxil2(B0 zq+@>m5W5On%@2vLrgUXwQ7LU-8XRE`l|&tco?MjgHCi3rFJRPJa`1y|CuI5rpZN_Z CMR7_1 literal 0 HcmV?d00001 diff --git a/data/assets/shaders/texture/ps.asset b/data/assets/shaders/texture/ps.asset new file mode 100644 index 0000000000000000000000000000000000000000..77519b3fe9a3b56c4536faee9c5fe85689d9781a GIT binary patch literal 228 zcmZQ%U|?VZVh~^i5e~K$f9e?+EI@210P)vA*)UqUEVZaOGe1wk#MD3`Ilm~Ciz_ov zp)57oNTIAaKRzV2!Z|;`D8-tKt28e&Ex#yNp*S(OASboR$VH(PBwbQklnRv1FD(J- zGEqna>T)YeOwUctD{;=x$u9y*mgQ%rDC8z)=4ohhRdaD-C{eIgD1n%y0XI_z#ePj| Hu39bt6S+XT literal 0 HcmV?d00001 diff --git a/data/assets/shaders/texture/vs.asset b/data/assets/shaders/texture/vs.asset new file mode 100644 index 0000000000000000000000000000000000000000..ff2c5a6129b61b08644c65d2b31be0fe912bad4c GIT binary patch literal 379 zcmZvX%L>9U5JgjW<|_u=sJN(7K`4UY4|E}JCALvU+6<%*D^mP%7iN4`aUhu__i}Q_ z6GC*{;_`S~%ZH{ChnEDWt)l#PFL}k%WDOLq5bMOa%1}Yr~ zpf(ZZ$nW7F%m7EOX?{~(tJcVsgtx0^NUV`S-|WBx#% zWj9kr0OgMm%I3rTj_HDP&IwdGwF6Xy31kXQf56y%`X0lD_~pa!YfRZ~!<@f8S|jBR D{=snr literal 0 HcmV?d00001 diff --git a/data/assets/shaders/tinted_texture/ps.asset b/data/assets/shaders/tinted_texture/ps.asset new file mode 100644 index 0000000000000000000000000000000000000000..17d2d2ed12631e1bfda83631028b0b760ddc1800 GIT binary patch literal 258 zcmZWj!3x4K4DGzxuLyYA#Dk0p!Wak>zhL(@r zV2mw%j0nbb$cE>gvHi$rjQwNg@49lRdqE14-4<%n$hlD9uuj1BR2D*+be_c11c#hR zH!0^m&x8(8c4srRHxFc=vk&=m&IJKQRZkbJ$U42_yEz|fJ_oOS*hhX1ndSlaI zw=Z5vedLDURq0c}C(IjZQ|xXU8C;yE8zkiJTP{MN5lV1?CVK?vnJR1~=|$vK5A}6a dm*G|(pZ@rm!68BlJ$^pJF2~Z4rku#BoJmXCaxNFrk*-`yPx^8t*K#AbawqrlAdfPTC&?Z@ T%Zt3qP~Ie#MBe3N%4hTk*@u~RvzN13e7QEU z@TaH~(TrjB0 SAaC+6LmA13e9CyiB>xKqLq5>} diff --git a/data/engine/icons/asset/dir.asset b/data/engine/icons/asset/dir.asset index b8989ffeaa783461f24c532d3233b31bcc7ecd07..eb3c62f77609819f3e881cd0843fc4ea2c436890 100644 GIT binary patch delta 112 zcmXwuxe0(!6a=65ePA&YDg4k1ti?iCh$-6qTq&BU;g&^uq&}<`ZuK delta 112 zcmXwu$q9f!00VcuZ$&J?uMN!GChWzZ`bY_4OI9V`17Q-f&;364So3n*yQ}l%(({d7 kb4JZBfdPhDfNVGi#JXr0zfnihzVjq1;JE>rpUi~1_lL?9286sZ8U2&V{A2JYBgh?YQ`c2 E09VHe{Qv*} diff --git a/data/engine/icons/asset/scene.asset b/data/engine/icons/asset/scene.asset index 5d10a62ecec6dbe041f6a0491543c55d2b8dbec1..d1f871b1d39428fc077ff4e3d8ad9a5e9531535a 100644 GIT binary patch delta 112 zcmXwuxe0(!6a=65ePA&YDg4k1ti?iCh$-6qTq&BU;g&^uq&}<`ZuK delta 112 zcmXwu$q9f!00VcuZ$&J?uMN!GChWzZ`bY_4OI9V`17Q-f&;364So3n*yQ}l%(({d7 kb4JZBfdPhDfNVGi#JXr0zfnihzVjq1;JE>rpUi~1_lL?9286sZ8U2&V{A2JYBgh?YQ`c2 E09VHe{Qv*} diff --git a/modules/asset_baker/include/asset_baker/bakers.hpp b/modules/asset_baker/include/asset_baker/bakers.hpp index 6a32262..3d56d1d 100644 --- a/modules/asset_baker/include/asset_baker/bakers.hpp +++ b/modules/asset_baker/include/asset_baker/bakers.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -117,4 +118,66 @@ public: } }; +class TextLoader: Loader +{ +public: + [[nodiscard]] static auto get_supported_extensions() -> std::unordered_set + { + return { ".glsl", ".txt", ".hlsl" }; + } + + [[nodiscard]] auto get_name() const -> std::string_view override + { + return "TextLoader"; + } + + [[nodiscard]] auto load(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(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 + { + if (TextLoader::get_supported_extensions().contains(file_extension)) + { + return std::make_unique(); + } + + return {}; + } +}; + } // namespace lt diff --git a/modules/asset_baker/src/baker.cpp b/modules/asset_baker/src/baker.cpp index 2d3333c..418feec 100644 --- a/modules/asset_baker/src/baker.cpp +++ b/modules/asset_baker/src/baker.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -20,14 +21,14 @@ void try_packing_texture( { Assets::TextureAsset::pack(texture_loader->load(in_path), out_path); - log_inf("Packed a texture:"); + log_inf("Packed a texture asset:"); log_inf("\tloader : {}", texture_loader->get_name()); log_inf("\tin path: {}", in_path.string()); log_inf("\tout path: {}", out_path.string()); } catch (const std::exception &exp) { - log_err("Failed to pack texture:"); + log_err("Failed to pack texture asset:"); log_err("\tloader : {}", texture_loader->get_name()); log_err("\tin path : {}", in_path.string()); log_err("\tout path: {}", out_path.string()); @@ -35,6 +36,34 @@ void try_packing_texture( } } +void try_packing_text(const std::filesystem::path &in_path, const std::filesystem::path &out_path) +{ + auto text_loader = lt::TextLoaderFactory::create(in_path.extension().string()); + if (!text_loader) + { + // Don't log anything; this is expected. + return; + } + + try + { + Assets::TextAsset::pack(text_loader->load(in_path), out_path); + + log_inf("Packed a text asset:"); + log_inf("\tloader : {}", text_loader->get_name()); + log_inf("\tin path: {}", in_path.string()); + log_inf("\tout path: {}", out_path.string()); + } + catch (const std::exception &exp) + { + log_err("Failed to pack a text asset:"); + log_err("\tloader : {}", text_loader->get_name()); + log_err("\tin path : {}", in_path.string()); + log_err("\tout path: {}", out_path.string()); + log_err("\texp.what: {}", exp.what()); + } +} + auto main(int argc, char *argv[]) -> int32_t try { @@ -57,6 +86,7 @@ try out_path.replace_extension(".asset"); try_packing_texture(in_path, out_path); + try_packing_text(in_path, out_path); } return EXIT_SUCCESS; diff --git a/modules/asset_parser/CMakeLists.txt b/modules/asset_parser/CMakeLists.txt index 6c892c0..d64bc24 100644 --- a/modules/asset_parser/CMakeLists.txt +++ b/modules/asset_parser/CMakeLists.txt @@ -1,6 +1,7 @@ add_library_module(asset_parser parser.cpp assets/texture.cpp + assets/text.cpp ) target_link_libraries( diff --git a/modules/asset_parser/include/asset_parser/assets/text.hpp b/modules/asset_parser/include/asset_parser/assets/text.hpp new file mode 100644 index 0000000..5bb240d --- /dev/null +++ b/modules/asset_parser/include/asset_parser/assets/text.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Assets { + +class TextAsset: public Asset +{ +public: + struct Metadata + { + uint32_t lines {}; + }; + + /** Data required to pack a text asset */ + struct PackageData + { + Asset::Metadata metadata; + + Metadata text_metadata; + + Blob text_blob; + }; + + static void pack(const PackageData &data, const std::filesystem::path &out_path); + + TextAsset(const std::filesystem::path &path); + + void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity); + + [[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata &; + + [[nodiscard]] auto get_metadata() const -> const Metadata &; + + [[nodiscard]] auto get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &; + +private: + uint32_t version {}; + + Asset::Metadata m_asset_metadata {}; + + Metadata m_metadata {}; + + BlobMetadata m_text_blob_metadata {}; + + std::ifstream m_stream; +}; + +} // namespace Assets diff --git a/modules/asset_parser/include/asset_parser/assets/texture.hpp b/modules/asset_parser/include/asset_parser/assets/texture.hpp index e69de29..04bd18c 100644 --- a/modules/asset_parser/include/asset_parser/assets/texture.hpp +++ b/modules/asset_parser/include/asset_parser/assets/texture.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Assets { + +class TextureAsset: public Asset +{ +public: + enum class Format : uint32_t // NOLINT(performance-enum-size) + { + None = 0, + RGBA8, + }; + + struct Metadata + { + Format format; + + uint32_t num_components; + + std::array pixel_size; + }; + + /** Data required to pack a texture asset */ + struct PackageData + { + Asset::Metadata metadata; + + Metadata texture_metadata; + + Blob pixels; + }; + + static void pack(const PackageData &data, const std::filesystem::path &out_path); + + TextureAsset(const std::filesystem::path &path); + + void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity); + + [[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata &; + + [[nodiscard]] auto get_metadata() const -> const Metadata &; + + [[nodiscard]] auto get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &; + +private: + uint32_t version {}; + + Asset::Metadata m_asset_metadata {}; + + Metadata m_metadata {}; + + BlobMetadata m_pixel_blob_metadata {}; + + std::ifstream m_stream; +}; + +} // namespace Assets diff --git a/modules/asset_parser/include/asset_parser/parser.hpp b/modules/asset_parser/include/asset_parser/parser.hpp index 49e7ee0..1dfc1e8 100644 --- a/modules/asset_parser/include/asset_parser/parser.hpp +++ b/modules/asset_parser/include/asset_parser/parser.hpp @@ -16,6 +16,7 @@ struct BlobMetadata { enum class Tag : uint8_t { + text, color, depth, vertices, @@ -41,7 +42,9 @@ class Asset public: enum class Type : uint32_t // NOLINT(performance-enum-size) { + None, Texture, + Text, Mesh, Material, }; @@ -53,224 +56,13 @@ public: Asset() = default; - Asset(Metadata metadata, std::filesystem::path path, std::ifstream stream) - : m_metadata(metadata) - , m_file_path(std::move(path)) - , m_stream(std::move(stream)) - { - } - /** Directly unpacks from disk to the destination. * * @note The destination MUST have at least blob_metadata.unpacked_size bytes available for * writing, otherwise segfault could occur! */ void unpack_blob(BlobMetadata::Tag blob_tag, std::byte *destination); - - [[nodiscard]] auto get_metadata() const -> const Metadata & - { - return m_metadata; - } - - [[nodiscard]] auto get_file_path() const -> std::filesystem::path - { - return m_file_path; - } - -private: - Metadata m_metadata; - - std::filesystem::path m_file_path; - - std::ifstream m_stream; }; -class TextureAsset: public Asset -{ -public: - enum class Format : uint32_t // NOLINT(performance-enum-size) - { - None = 0, - RGBA8, - }; - - struct Metadata - { - Format format; - - uint32_t num_components; - - std::array pixel_size; - }; - - /** Data required to pack a texture */ - struct PackageData - { - Asset::Metadata metadata; - - Metadata texture_metadata; - - Blob pixels; - }; - - TextureAsset(const std::filesystem::path &path) - { - m_stream = std::ifstream { path, std::ios::binary }; - if (!m_stream.is_open()) - { - throw std::runtime_error { std::format( - "Failed to open ifm_stream for loading texture asset at: {}", - path.string() - ) }; - } - - // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) - m_stream.read((char *)&version, sizeof(version)); - m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata)); - m_stream.read((char *)&m_metadata, sizeof(m_metadata)); - - auto num_blobs = uint32_t {}; - m_stream.read((char *)&num_blobs, sizeof(num_blobs)); - if (num_blobs != 1) - { - throw std::runtime_error { - std::format("Failed to load texture asset: invalid number of blobs: {}", num_blobs) - }; - } - - m_stream.read((char *)&m_pixel_blob_metadata, sizeof(m_pixel_blob_metadata)); - if (m_pixel_blob_metadata.tag != BlobMetadata::Tag::color) - { - throw std::runtime_error { - std::format( - "Failed to load texture asset: invalid blob tag, expected {}, got {}", - std::to_underlying(BlobMetadata::Tag::color), - std::to_underlying(m_pixel_blob_metadata.tag) - ), - }; - } - // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) - } - - void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity) - { - if (tag != BlobMetadata::Tag::color) - { - throw std::runtime_error { std::format( - "Invalid tag for unpack_blob of TextureAsset: {}", - std::to_underlying(tag) - ) }; - } - - m_stream.seekg(static_cast(m_pixel_blob_metadata.offset)); - switch (m_pixel_blob_metadata.compression_type) - { - case Assets::CompressionType::None: - if (m_pixel_blob_metadata.uncompressed_size != m_pixel_blob_metadata.compressed_size) - { - throw std::runtime_error("Failed to unpack blob from TextureAsset: " - "compressed/uncompressed size mismatch for no compression " - "type"); - } - - if (m_pixel_blob_metadata.uncompressed_size > destination_capacity) - { - throw std::runtime_error("Failed to unpack blob from TextureAsset: " - "uncompressed_size > destination_capacity, unpacking " - "would result in segfault"); - } - - if (!m_stream.is_open()) - { - throw std::runtime_error("Failed to unpack blob from TextureAsset: ifstream is " - "closed"); - } - - m_stream.read( - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - (char *)destination, - static_cast(m_pixel_blob_metadata.uncompressed_size) - ); - - return; - - default: - throw std::runtime_error(std::format( - "Failed to unpack blob from TextureAsset: unsupported " - "compression type: {}", - std::to_underlying(m_pixel_blob_metadata.compression_type) - )); - } - } - - static void pack(const PackageData &data, const std::filesystem::path &out_path) - { - const auto &[metadata, texture_metadata, pixels] = data; - - auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc }; - if (!stream.is_open()) - { - throw std::runtime_error { - std::format("Failed to open ofstream for packing texture at: {}", out_path.string()) - }; - } - stream.seekp(0); - - // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) - stream.write((char *)¤t_version, sizeof(current_version)); - - stream.write((char *)&metadata, sizeof(metadata)); - stream.write((char *)&texture_metadata, sizeof(texture_metadata)); - - constexpr auto number_of_blobs = uint32_t { 1 }; - stream.write((char *)&number_of_blobs, sizeof(number_of_blobs)); - - auto pixels_metadata = BlobMetadata { - .tag = BlobMetadata::Tag::color, - .offset = static_cast(stream.tellp()), - .compression_type = CompressionType::None, - .compressed_size = pixels.size(), - .uncompressed_size = pixels.size(), - }; - - stream.write((char *)&pixels_metadata, sizeof(pixels_metadata)); - stream.write((char *)&pixels[0], static_cast(pixels.size())); - // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) - } - - [[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata & - { - return m_asset_metadata; - } - - [[nodiscard]] auto get_metadata() const -> const Metadata & - { - return m_metadata; - } - - [[nodiscard]] auto get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata & - { - if (tag != BlobMetadata::Tag::color) - { - throw std::runtime_error { std::format( - "Invalid tag for get_blob_metadata of TextureAsset: {}", - std::to_underlying(tag) - ) }; - } - - return m_pixel_blob_metadata; - } - -private: - Asset::Metadata m_asset_metadata {}; - - Metadata m_metadata {}; - - BlobMetadata m_pixel_blob_metadata {}; - - uint32_t version {}; - - std::ifstream m_stream; -}; } // namespace Assets diff --git a/modules/asset_parser/src/assets/text.cpp b/modules/asset_parser/src/assets/text.cpp new file mode 100644 index 0000000..5bae4e9 --- /dev/null +++ b/modules/asset_parser/src/assets/text.cpp @@ -0,0 +1,156 @@ +#include +#include +#include + +namespace Assets { + +/* static */ void TextAsset::pack(const PackageData &data, const std::filesystem::path &out_path) +{ + const auto &[metadata, text_metadata, text] = data; + + auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc }; + if (!stream.is_open()) + { + throw std::runtime_error { + std::format("Failed to open ofstream for packing Text at: {}", out_path.string()) + }; + } + stream.seekp(0); + + // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) + stream.write((char *)¤t_version, sizeof(current_version)); + stream.write((char *)&metadata, sizeof(metadata)); + stream.write((char *)&text_metadata, sizeof(text_metadata)); + + constexpr auto number_of_blobs = uint32_t { 1 }; + stream.write((char *)&number_of_blobs, sizeof(number_of_blobs)); + + auto textblob_metadata = BlobMetadata { + .tag = BlobMetadata::Tag::text, + .offset = static_cast(stream.tellp()) + sizeof(BlobMetadata), + .compression_type = CompressionType::None, + .compressed_size = text.size(), + .uncompressed_size = text.size(), + }; + + stream.write((char *)&textblob_metadata, sizeof(textblob_metadata)); + stream.write((char *)text.data(), static_cast(text.size())); + // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) +} + +TextAsset::TextAsset(const std::filesystem::path &path) +{ + m_stream = std::ifstream { path, std::ios::binary }; + if (!m_stream.is_open()) + { + throw std::runtime_error { + std::format("Failed to open ifstream for loading Text asset at: {}", path.string()) + }; + } + + // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) + m_stream.read((char *)&version, sizeof(version)); + m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata)); + m_stream.read((char *)&m_metadata, sizeof(m_metadata)); + + auto num_blobs = uint32_t {}; + m_stream.read((char *)&num_blobs, sizeof(num_blobs)); + if (num_blobs != 1) + { + throw std::runtime_error { + std::format("Failed to load Text asset: invalid number of blobs: {}", num_blobs) + }; + } + + m_stream.read((char *)&m_text_blob_metadata, sizeof(m_text_blob_metadata)); + if (m_text_blob_metadata.tag != BlobMetadata::Tag::text) + { + throw std::runtime_error { + std::format( + "Failed to load Text asset: invalid blob tag, expected {}, got {}", + std::to_underlying(BlobMetadata::Tag::text), + std::to_underlying(m_text_blob_metadata.tag) + ), + }; + } + // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) +} + +void TextAsset::unpack_blob( + BlobMetadata::Tag tag, + std::byte *destination, + size_t destination_capacity +) +{ + if (tag != BlobMetadata::Tag::text) + { + throw std::runtime_error { + std::format("Invalid tag for unpack_blob of TextAsset: {}", std::to_underlying(tag)) + }; + } + + m_stream.seekg(static_cast(m_text_blob_metadata.offset)); + switch (m_text_blob_metadata.compression_type) + { + case Assets::CompressionType::None: + if (m_text_blob_metadata.uncompressed_size != m_text_blob_metadata.compressed_size) + { + throw std::runtime_error("Failed to unpack blob from TextAsset: " + "compressed/uncompressed size mismatch for no compression " + "type"); + } + + if (m_text_blob_metadata.uncompressed_size > destination_capacity) + { + throw std::runtime_error("Failed to unpack blob from TextAsset: " + "uncompressed_size > destination_capacity, unpacking " + "would result in segfault"); + } + + if (!m_stream.is_open()) + { + throw std::runtime_error("Failed to unpack blob from TextAsset: ifstream is " + "closed"); + } + + m_stream.read( + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) + (char *)destination, + static_cast(m_text_blob_metadata.uncompressed_size) + ); + + return; + + default: + throw std::runtime_error(std::format( + "Failed to unpack blob from TextAsset: unsupported " + "compression type: {}", + std::to_underlying(m_text_blob_metadata.compression_type) + )); + } +} + +[[nodiscard]] auto TextAsset::get_asset_metadata() const -> const Asset::Metadata & +{ + return m_asset_metadata; +} + +[[nodiscard]] auto TextAsset::get_metadata() const -> const Metadata & +{ + return m_metadata; +} + +[[nodiscard]] auto TextAsset::get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata & +{ + if (tag != BlobMetadata::Tag::text) + { + throw std::runtime_error { std::format( + "Invalid tag for get_blob_metadata of TextAsset: {}", + std::to_underlying(tag) + ) }; + } + + return m_text_blob_metadata; +} + +} // namespace Assets diff --git a/modules/asset_parser/src/assets/texture.cpp b/modules/asset_parser/src/assets/texture.cpp index 3e1b00b..d52a873 100644 --- a/modules/asset_parser/src/assets/texture.cpp +++ b/modules/asset_parser/src/assets/texture.cpp @@ -2,11 +2,157 @@ #include #include -// [version], [type] -- -// [asset_metadata], [blob_metadata] -- -// [blob] -- - namespace Assets { +/* static */ void TextureAsset::pack(const PackageData &data, const std::filesystem::path &out_path) +{ + const auto &[metadata, texture_metadata, pixels] = data; + + auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc }; + if (!stream.is_open()) + { + throw std::runtime_error { + std::format("Failed to open ofstream for packing texture at: {}", out_path.string()) + }; + } + stream.seekp(0); + + // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) + stream.write((char *)¤t_version, sizeof(current_version)); + + stream.write((char *)&metadata, sizeof(metadata)); + stream.write((char *)&texture_metadata, sizeof(texture_metadata)); + + constexpr auto number_of_blobs = uint32_t { 1 }; + stream.write((char *)&number_of_blobs, sizeof(number_of_blobs)); + + auto pixels_metadata = BlobMetadata { + .tag = BlobMetadata::Tag::color, + .offset = static_cast(stream.tellp()) + sizeof(BlobMetadata), + .compression_type = CompressionType::None, + .compressed_size = pixels.size(), + .uncompressed_size = pixels.size(), + }; + + stream.write((char *)&pixels_metadata, sizeof(pixels_metadata)); + stream.write((char *)&pixels[0], static_cast(pixels.size())); + // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) +} + +TextureAsset::TextureAsset(const std::filesystem::path &path) +{ + m_stream = std::ifstream { path, std::ios::binary }; + if (!m_stream.is_open()) + { + throw std::runtime_error { + std::format("Failed to open ifstream for loading texture asset at: {}", path.string()) + }; + } + + // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) + m_stream.read((char *)&version, sizeof(version)); + m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata)); + m_stream.read((char *)&m_metadata, sizeof(m_metadata)); + + auto num_blobs = uint32_t {}; + m_stream.read((char *)&num_blobs, sizeof(num_blobs)); + if (num_blobs != 1) + { + throw std::runtime_error { + std::format("Failed to load texture asset: invalid number of blobs: {}", num_blobs) + }; + } + + m_stream.read((char *)&m_pixel_blob_metadata, sizeof(m_pixel_blob_metadata)); + if (m_pixel_blob_metadata.tag != BlobMetadata::Tag::color) + { + throw std::runtime_error { + std::format( + "Failed to load texture asset: invalid blob tag, expected {}, got {}", + std::to_underlying(BlobMetadata::Tag::color), + std::to_underlying(m_pixel_blob_metadata.tag) + ), + }; + } + // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) +} + +void TextureAsset::unpack_blob( + BlobMetadata::Tag tag, + std::byte *destination, + size_t destination_capacity +) +{ + if (tag != BlobMetadata::Tag::color) + { + throw std::runtime_error { + std::format("Invalid tag for unpack_blob of TextureAsset: {}", std::to_underlying(tag)) + }; + } + + m_stream.seekg(static_cast(m_pixel_blob_metadata.offset)); + switch (m_pixel_blob_metadata.compression_type) + { + case Assets::CompressionType::None: + if (m_pixel_blob_metadata.uncompressed_size != m_pixel_blob_metadata.compressed_size) + { + throw std::runtime_error("Failed to unpack blob from TextureAsset: " + "compressed/uncompressed size mismatch for no compression " + "type"); + } + + if (m_pixel_blob_metadata.uncompressed_size > destination_capacity) + { + throw std::runtime_error("Failed to unpack blob from TextureAsset: " + "uncompressed_size > destination_capacity, unpacking " + "would result in segfault"); + } + + if (!m_stream.is_open()) + { + throw std::runtime_error("Failed to unpack blob from TextureAsset: ifstream is " + "closed"); + } + + m_stream.read( + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) + (char *)destination, + static_cast(m_pixel_blob_metadata.uncompressed_size) + ); + + return; + + default: + throw std::runtime_error(std::format( + "Failed to unpack blob from TextureAsset: unsupported " + "compression type: {}", + std::to_underlying(m_pixel_blob_metadata.compression_type) + )); + } +} + +[[nodiscard]] auto TextureAsset::get_asset_metadata() const -> const Asset::Metadata & +{ + return m_asset_metadata; +} + +[[nodiscard]] auto TextureAsset::get_metadata() const -> const Metadata & +{ + return m_metadata; +} + +[[nodiscard]] auto TextureAsset::get_blob_metadata(BlobMetadata::Tag tag) const + -> const BlobMetadata & +{ + if (tag != BlobMetadata::Tag::color) + { + throw std::runtime_error { std::format( + "Invalid tag for get_blob_metadata of TextureAsset: {}", + std::to_underlying(tag) + ) }; + } + + return m_pixel_blob_metadata; +} } // namespace Assets diff --git a/modules/engine/CMakeLists.txt b/modules/engine/CMakeLists.txt index becfdec..777850e 100644 --- a/modules/engine/CMakeLists.txt +++ b/modules/engine/CMakeLists.txt @@ -38,7 +38,6 @@ if(NOT WIN32) scene/scene.cpp time/timer.cpp user_interface/user_interface.cpp - utils/file_manager.cpp utils/resource_manager.cpp utils/serializer.cpp utils/stringifier.cpp @@ -90,7 +89,6 @@ else() scene/scene.cpp time/timer.cpp user_interface/user_interface.cpp - utils/file_manager.cpp utils/resource_manager.cpp utils/serializer.cpp utils/stringifier.cpp diff --git a/modules/engine/include/engine/graphics/shader.hpp b/modules/engine/include/engine/graphics/shader.hpp index 0982cab..00194d3 100644 --- a/modules/engine/include/engine/graphics/shader.hpp +++ b/modules/engine/include/engine/graphics/shader.hpp @@ -1,7 +1,7 @@ #pragma once +#include #include -#include #include namespace Light { @@ -13,16 +13,17 @@ class Shader public: enum Stage { - NONE = 0, - VERTEX = 1, - PIXEL = 2, - GEOMETRY = 3 + none = 0, + + vertex, + pixel, + geometry, }; static auto create( - const BasicFileHandle& vertexFile, - const BasicFileHandle& pixelFile, - const Ref& sharedContext + Assets::Blob vertex_blob, + Assets::Blob pixel_blob, + const Ref &shared_context ) -> Ref; virtual ~Shader() = default; diff --git a/modules/engine/include/engine/platform/graphics/directx/shader.hpp b/modules/engine/include/engine/platform/graphics/directx/shader.hpp index f56637f..8b236a1 100644 --- a/modules/engine/include/engine/platform/graphics/directx/shader.hpp +++ b/modules/engine/include/engine/platform/graphics/directx/shader.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include namespace Light { diff --git a/modules/engine/include/engine/platform/graphics/opengl/shader.hpp b/modules/engine/include/engine/platform/graphics/opengl/shader.hpp index 59f69dc..a214306 100644 --- a/modules/engine/include/engine/platform/graphics/opengl/shader.hpp +++ b/modules/engine/include/engine/platform/graphics/opengl/shader.hpp @@ -2,14 +2,13 @@ #include #include -#include namespace Light { class glShader: public Shader { public: - glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile); + glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob); ~glShader() override; @@ -18,9 +17,9 @@ public: void un_bind() override; private: - unsigned int compile_shader(const std::string& source, Shader::Stage stage); + unsigned int compile_shader(const std::string &source, Shader::Stage stage); - unsigned int m_shader_id{0u}; + unsigned int m_shader_id { 0u }; }; } // namespace Light diff --git a/modules/engine/include/engine/utils/file_manager.hpp b/modules/engine/include/engine/utils/file_manager.hpp deleted file mode 100644 index dea824f..0000000 --- a/modules/engine/include/engine/utils/file_manager.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -namespace Light { - -class BasicFileHandle -{ -public: - virtual ~BasicFileHandle() = default; - BasicFileHandle( - uint8_t *data = nullptr, - uint32_t size = 0ull, - std::string path = "", - std::string name = "", - std::string extension = "" - ); - - virtual void release(); - - auto get_data() -> uint8_t * - { - return m_data; - } - - auto get_size() const -> uint32_t - { - return m_size; - } - - auto get_path() -> const std::string & - { - return m_path; - } - - auto get_name() -> const std::string & - { - return m_name; - } - - auto get_extension() -> const std::string & - { - return m_extension; - } - - auto get_name_with_extention() -> const std::string & - { - return m_name + '.' + m_extension; - } - - [[nodiscard]] auto is_valid() const -> bool - { - return !!m_data; - } - - operator bool() const - { - return is_valid(); - } - -private: - // made protected for custom free(): - uint8_t *m_data; - - uint32_t m_size; - - const std::string m_path; - - const std::string m_name; - - const std::string m_extension; -}; - -class FileManager -{ -public: - static auto read_text_file(const std::string &path) -> BasicFileHandle; -}; - -} // namespace Light diff --git a/modules/engine/include/engine/utils/resource_manager.hpp b/modules/engine/include/engine/utils/resource_manager.hpp index b4f5ea7..dc042ba 100644 --- a/modules/engine/include/engine/utils/resource_manager.hpp +++ b/modules/engine/include/engine/utils/resource_manager.hpp @@ -20,23 +20,18 @@ public: static void load_shader( const std::string &name, - const std::string &vertexPath, - const std::string &pixelPath + const std::filesystem::path &vertex_path, + const std::filesystem::path &pixel_path ) { - instance().load_shader_impl(name, vertexPath, pixelPath); + instance().load_shader_impl(name, vertex_path, pixel_path); } - static void load_texture(const std::string &name, const std::string &path) + static void load_texture(const std::string &name, const std::filesystem::path &path) { instance().load_texture_impl(name, path); } - static void release_texture(const std::string &name) - { - instance().release_texture_impl(name); - } - static auto get_shader(const std::string &name) -> Ref { return instance().m_shaders[name]; @@ -52,14 +47,12 @@ private: void load_shader_impl( const std::string &name, - const std::string &vertexPath, - const std::string &pixelPath + const std::filesystem::path &vertex_path, + const std::filesystem::path &pixel_path ); void load_texture_impl(const std::string &name, const std::filesystem::path &path); - void release_texture_impl(const std::string &name); - std::unordered_map> m_shaders; std::unordered_map> m_textures; diff --git a/modules/engine/src/graphics/renderer_programs/quad.cpp b/modules/engine/src/graphics/renderer_programs/quad.cpp index bbd8245..ee36e88 100644 --- a/modules/engine/src/graphics/renderer_programs/quad.cpp +++ b/modules/engine/src/graphics/renderer_programs/quad.cpp @@ -19,8 +19,8 @@ QuadRendererProgram::QuadRendererProgram( // #todo: don't use relative path ResourceManager::load_shader( "LT_ENGINE_RESOURCES_QUAD_SHADER", - "data/assets/shaders/quads/vs.glsl", - "data/assets/shaders/quads/ps.glsl" + "data/assets/shaders/quads/vs.asset", + "data/assets/shaders/quads/ps.asset" ); m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER"); diff --git a/modules/engine/src/graphics/renderer_programs/texture.cpp b/modules/engine/src/graphics/renderer_programs/texture.cpp index 0fbae15..ea8c0e4 100644 --- a/modules/engine/src/graphics/renderer_programs/texture.cpp +++ b/modules/engine/src/graphics/renderer_programs/texture.cpp @@ -19,8 +19,8 @@ TextureRendererProgram::TextureRendererProgram( // #todo: don't use relative path ResourceManager::load_shader( "LT_ENGINE_RESOURCES_TEXTURE_SHADER", - "data/assets/shaders/texture/vs.glsl", - "data/assets/shaders/texture/ps.glsl" + "data/assets/shaders/texture/vs.asset", + "data/assets/shaders/texture/ps.asset" ); m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_TEXTURE_SHADER"); diff --git a/modules/engine/src/graphics/renderer_programs/tinted_texture.cpp b/modules/engine/src/graphics/renderer_programs/tinted_texture.cpp index a461ccc..36fac1d 100644 --- a/modules/engine/src/graphics/renderer_programs/tinted_texture.cpp +++ b/modules/engine/src/graphics/renderer_programs/tinted_texture.cpp @@ -19,8 +19,8 @@ TintedTextureRendererProgram::TintedTextureRendererProgram( // #todo: don't use relative path ResourceManager::load_shader( "LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER", - "data/assets/shaders/tinted_texture/vs.glsl", - "data/assets/shaders/tinted_texture/ps.glsl" + "data/assets/shaders/tinted_texture/vs.asset", + "data/assets/shaders/tinted_texture/ps.asset" ); m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER"); diff --git a/modules/engine/src/graphics/shader.cpp b/modules/engine/src/graphics/shader.cpp index d140d0b..408ec10 100644 --- a/modules/engine/src/graphics/shader.cpp +++ b/modules/engine/src/graphics/shader.cpp @@ -11,15 +11,18 @@ namespace Light { auto Shader::create( - const BasicFileHandle& vertexFile, - const BasicFileHandle& pixelFile, - const Ref& /*sharedContext*/ + Assets::Blob vertex_blob, + Assets::Blob pixel_blob, + const Ref &shared_context ) -> Ref { + std::ignore = shared_context; + // load shader source switch (GraphicsContext::get_graphics_api()) { - case GraphicsAPI::OpenGL: return create_ref(vertexFile, pixelFile); + case GraphicsAPI::OpenGL: + return create_ref(std::move(vertex_blob), std::move(pixel_blob)); case GraphicsAPI::DirectX: lt_win(return create_ref( diff --git a/modules/engine/src/platform/graphics/opengl/shader.cpp b/modules/engine/src/platform/graphics/opengl/shader.cpp index e4a1fd7..9fe299e 100644 --- a/modules/engine/src/platform/graphics/opengl/shader.cpp +++ b/modules/engine/src/platform/graphics/opengl/shader.cpp @@ -6,27 +6,29 @@ namespace Light { -glShader::glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile) +glShader::glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob) + : m_shader_id(glCreateProgram()) { - // create - m_shader_id = glCreateProgram(); + auto vertex_source = std::string { + vertex_blob.data(), + vertex_blob.data() + vertex_blob.size(), // NOLINT + }; - std::string const vertexSource(vertexFile.get_data(), vertexFile.get_data() + vertexFile.get_size()); - std::string const pixelSource(pixelFile.get_data(), pixelFile.get_data() + pixelFile.get_size()); + auto pixel_source = std::string { + pixel_blob.data(), + pixel_blob.data() + pixel_blob.size(), // NOLINT + }; - unsigned int const vertexShader = compile_shader(vertexSource, Shader::Stage::VERTEX); - unsigned int const pixelShader = compile_shader(pixelSource, Shader::Stage::PIXEL); + const auto vertex_shader = compile_shader(vertex_source, Shader::Stage::vertex); + const auto pixel_shader = compile_shader(pixel_source, Shader::Stage::pixel); - // attach shaders - glAttachShader(m_shader_id, vertexShader); - glAttachShader(m_shader_id, pixelShader); + glAttachShader(m_shader_id, vertex_shader); + glAttachShader(m_shader_id, pixel_shader); - // link shader program glLinkProgram(m_shader_id); - // delete shaders (free memory) - glDeleteShader(vertexShader); - glDeleteShader(pixelShader); + glDeleteShader(vertex_shader); + glDeleteShader(pixel_shader); } glShader::~glShader() @@ -44,38 +46,14 @@ void glShader::un_bind() glUseProgram(NULL); } -// shaderc::SpvCompilationResult glShader::compile_glsl(basic_file_handle file, Shader::Stage stage) -// { -// // compile options -// shaderc::CompileOptions options; -// options.SetTargetEnvironment(shaderc_target_env_opengl, shaderc_env_version_opengl_4_5); -// options.SetOptimizationLevel(shaderc_optimization_level_performance); -// -// // compile -// shaderc::Compiler compiler; -// shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(reinterpret_cast(file.GetData()), stage == Shader::Stage::VERTEX ? -// shaderc_shader_kind::shaderc_vertex_shader : shaderc_shader_kind::shaderc_fragment_shader, -// file.GetName().c_str(), options); -// -// // log error -// if (result.GetCompilationStatus() != shaderc_compilation_status_success) -// { -// log_err("Failed to compile {} shader at {}...", stage == Shader::Stage::VERTEX ? -// "vertex" : "pixel", file.GetPath()); log_err(" {}", result.GetErrorMessage()); -// } -// -// return result; -// } - -auto glShader::compile_shader(const std::string& source, Shader::Stage stage) -> unsigned int +auto glShader::compile_shader(const std::string &source, Shader::Stage stage) -> unsigned int { // &(address of) needs an lvalue const auto *lvalue_source = source.c_str(); auto shader = glCreateShader( - stage == Shader::Stage::VERTEX ? GL_VERTEX_SHADER : - stage == Shader::Stage::PIXEL ? GL_FRAGMENT_SHADER : - stage == Shader::Stage::GEOMETRY ? GL_GEOMETRY_SHADER : + stage == Shader::Stage::vertex ? GL_VERTEX_SHADER : + stage == Shader::Stage::pixel ? GL_FRAGMENT_SHADER : + stage == Shader::Stage::geometry ? GL_GEOMETRY_SHADER : NULL ); @@ -96,7 +74,7 @@ auto glShader::compile_shader(const std::string& source, Shader::Stage stage) -> log_err( "glShader::glShader: failed to compile {} shader:\n {}", - stage == Shader::Stage::VERTEX ? "Vertex" : "Pixel", + stage == Shader::Stage::vertex ? "Vertex" : "Pixel", errorLog ); diff --git a/modules/engine/src/utils/file_manager.cpp b/modules/engine/src/utils/file_manager.cpp deleted file mode 100644 index f42d54f..0000000 --- a/modules/engine/src/utils/file_manager.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include - -namespace Light { - -BasicFileHandle::BasicFileHandle( - uint8_t *data, - uint32_t size, - std::string path, - std::string name, - std::string extension -) - : m_data(data) - , m_size(size) - , m_path(std::move(path)) - , m_name(std::move(name)) - , m_extension(std::move(extension)) -{ -} - -void BasicFileHandle::release() -{ - delete m_data; - m_data = nullptr; - m_size = 0ull; -} - -auto FileManager::read_text_file(const std::string &path) -> BasicFileHandle -{ - // parse path info - auto name = path.substr(0, path.find('.') + -1); - auto extension = path.substr(path.find('.') + 1); - - // open file - auto file = std::ifstream { path.c_str(), std::ios_base::in | std::ios_base::binary }; - - // check - if (!file) - { - log_wrn("Failed to load text file: {}", path); - file.close(); - return nullptr; - } - - // fetch file size - file.seekg(0, std::ios::end); - auto size = file.tellg(); - file.seekg(0, std::ios::beg); - - if (!size) - { - log_wrn("Empty text file: {}", path); - } - - // read file - auto *data = new uint8_t[size]; - file.read(reinterpret_cast(data), size); - - file.close(); - return { data, static_cast(size), path, name, extension }; -} - -} // namespace Light diff --git a/modules/engine/src/utils/resource_manager.cpp b/modules/engine/src/utils/resource_manager.cpp index e698f02..9ee7683 100644 --- a/modules/engine/src/utils/resource_manager.cpp +++ b/modules/engine/src/utils/resource_manager.cpp @@ -1,68 +1,85 @@ +#include #include -#include #include #include #include -#include #include +#include namespace Light { void ResourceManager::load_shader_impl( const std::string &name, - const std::string &vertexPath, - const std::string &pixelPath + const std::filesystem::path &vertex_path, + const std::filesystem::path &pixel_path ) { - lt_assert(!vertexPath.empty(), "Empty 'vertexPath'"); - lt_assert(!pixelPath.empty(), "Empty 'pixelPath'"); + try + { + log_trc("Loading shader:"); + log_trc("\tname : {}", name); + log_trc("\tvertex path: {}", vertex_path.string()); + log_trc("\tpixel path : {}", pixel_path.string()); - auto vertexFile = FileManager::read_text_file(vertexPath); - auto pixelFile = FileManager::read_text_file(pixelPath); + auto vertex_asset = Assets::TextAsset { vertex_path }; + auto pixel_asset = Assets::TextAsset { pixel_path }; - lt_assert(vertexFile.is_valid(), "Failed to read vertex file: {}", vertexPath); - lt_assert(pixelFile.is_valid(), "Failed to read vertex file: {}", pixelPath); + auto vertex_blob_metadata = vertex_asset.get_blob_metadata(Assets::BlobMetadata::Tag::text); + auto pixel_blob_metadata = pixel_asset.get_blob_metadata(Assets::BlobMetadata::Tag::text); - m_shaders[name] = Ref( - Shader::create(vertexFile, pixelFile, GraphicsContext::get_shared_context()) - ); + auto vertex_blob = Assets::Blob(vertex_blob_metadata.uncompressed_size); + auto pixel_blob = Assets::Blob(pixel_blob_metadata.uncompressed_size); - vertexFile.release(); - pixelFile.release(); + vertex_asset.unpack_blob(vertex_blob_metadata.tag, vertex_blob.data(), vertex_blob.size()); + pixel_asset.unpack_blob(pixel_blob_metadata.tag, pixel_blob.data(), pixel_blob.size()); + + m_shaders[name] = Ref(Shader::create( + std::move(vertex_blob), + std::move(pixel_blob), + GraphicsContext::get_shared_context() + )); + } + catch (const std::exception &exp) + { + log_err("Failed to load shader:"); + log_err("\tname : {}", name); + log_err("\tvertex path: {}", vertex_path.string()); + log_err("\tpixel path : {}", pixel_path.string()); + log_err("\texception : {}", exp.what()); + } } void ResourceManager::load_texture_impl(const std::string &name, const std::filesystem::path &path) { - log_trc("Loading texture:"); - log_trc("\tname: {}", name); - log_trc("\tpath: {}", path.string()); - - auto asset = Assets::TextureAsset { path }; - const auto metadata = asset.get_metadata(); - const auto blob_metadata = asset.get_blob_metadata(Assets::BlobMetadata::Tag::color); - - auto blob = std::vector(blob_metadata.uncompressed_size); - asset.unpack_blob(blob_metadata.tag, blob.data(), blob.size()); - - m_textures[name] = Ref(Texture::create( - metadata.pixel_size[0], - metadata.pixel_size[1], - metadata.num_components, - std::bit_cast(blob.data()), - GraphicsContext::get_shared_context(), - path - )); -} - -void ResourceManager::release_texture_impl(const std::string &name) -{ - if (!m_textures[name]) + try { - log_wrn("Failed to find texture named: {}", name); - return; - } + log_trc("Loading texture:"); + log_trc("\tname: {}", name); + log_trc("\tpath: {}", path.string()); - m_textures[name] = nullptr; + auto asset = Assets::TextureAsset { path }; + const auto metadata = asset.get_metadata(); + const auto blob_metadata = asset.get_blob_metadata(Assets::BlobMetadata::Tag::color); + + auto blob = std::vector(blob_metadata.uncompressed_size); + asset.unpack_blob(blob_metadata.tag, blob.data(), blob.size()); + + m_textures[name] = Ref(Texture::create( + metadata.pixel_size[0], + metadata.pixel_size[1], + metadata.num_components, + std::bit_cast(blob.data()), + GraphicsContext::get_shared_context(), + path + )); + } + catch (const std::exception &exp) + { + log_err("Failed to load texture:"); + log_err("\tname : {}", name); + log_err("\tpath : {}", path.string()); + log_err("\texception: {}", exp.what()); + } } } // namespace Light