feat: text asset
fix: miscalculated offset for asset blobs refactor: remove file manager completely
This commit is contained in:
		
							parent
							
								
									40e92bb1da
								
							
						
					
					
						commit
						fc2fe26160
					
				
					 34 changed files with 635 additions and 485 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								data/assets/fonts/open_sans/LICENSE.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/fonts/open_sans/LICENSE.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/assets/shaders/quads/ps.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/shaders/quads/ps.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/assets/shaders/quads/vs.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/shaders/quads/vs.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/assets/shaders/texture/ps.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/shaders/texture/ps.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/assets/shaders/texture/vs.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/shaders/texture/vs.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/assets/shaders/tinted_texture/ps.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/shaders/tinted_texture/ps.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/assets/shaders/tinted_texture/vs.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/shaders/tinted_texture/vs.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -19,4 +19,3 @@ void main() | |||
| 	vso_Tint = a_Tint; | ||||
| 	vso_TexCoord = a_TexCoord; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -1,5 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <asset_parser/assets/text.hpp> | ||||
| #include <asset_parser/assets/texture.hpp> | ||||
| #include <filesystem> | ||||
| #include <logger/logger.hpp> | ||||
|  | @ -117,4 +118,66 @@ public: | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| 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(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
 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include <asset_baker/bakers.hpp> | ||||
| #include <asset_parser/assets/text.hpp> | ||||
| #include <asset_parser/assets/texture.hpp> | ||||
| #include <asset_parser/parser.hpp> | ||||
| #include <filesystem> | ||||
|  | @ -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; | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| add_library_module(asset_parser  | ||||
|     parser.cpp | ||||
|     assets/texture.cpp | ||||
|     assets/text.cpp | ||||
| ) | ||||
| 
 | ||||
| target_link_libraries( | ||||
|  |  | |||
							
								
								
									
										54
									
								
								modules/asset_parser/include/asset_parser/assets/text.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								modules/asset_parser/include/asset_parser/assets/text.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <asset_parser/parser.hpp> | ||||
| #include <compressors/compressors.hpp> | ||||
| #include <cstdint> | ||||
| #include <filesystem> | ||||
| #include <fstream> | ||||
| #include <logger/logger.hpp> | ||||
| 
 | ||||
| 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
 | ||||
|  | @ -0,0 +1,64 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <asset_parser/parser.hpp> | ||||
| #include <compressors/compressors.hpp> | ||||
| #include <cstdint> | ||||
| #include <filesystem> | ||||
| #include <fstream> | ||||
| #include <logger/logger.hpp> | ||||
| 
 | ||||
| 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<uint32_t, 3> 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
 | ||||
|  | @ -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<uint32_t, 3> 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<long>(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<long>(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<size_t>(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<long>(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
 | ||||
|  |  | |||
							
								
								
									
										156
									
								
								modules/asset_parser/src/assets/text.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								modules/asset_parser/src/assets/text.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,156 @@ | |||
| #include <asset_parser/assets/text.hpp> | ||||
| #include <lz4.h> | ||||
| #include <nlohmann/json.hpp> | ||||
| 
 | ||||
| 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<size_t>(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<long>(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<long>(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<long>(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
 | ||||
|  | @ -2,11 +2,157 @@ | |||
| #include <lz4.h> | ||||
| #include <nlohmann/json.hpp> | ||||
| 
 | ||||
| // [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<size_t>(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<long>(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<long>(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<long>(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
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <asset_parser/assets/text.hpp> | ||||
| #include <engine/base/base.hpp> | ||||
| #include <engine/utils/file_manager.hpp> | ||||
| #include <glm/glm.hpp> | ||||
| 
 | ||||
| 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>& sharedContext | ||||
| 	    Assets::Blob vertex_blob, | ||||
| 	    Assets::Blob pixel_blob, | ||||
| 	    const Ref<SharedContext> &shared_context | ||||
| 	) -> Ref<Shader>; | ||||
| 
 | ||||
| 	virtual ~Shader() = default; | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ | |||
| #include <d3d11.h> | ||||
| #include <engine/base/base.hpp> | ||||
| #include <engine/graphics/shader.hpp> | ||||
| #include <engine/utils/file_manager.hpp> | ||||
| #include <wrl.h> | ||||
| 
 | ||||
| namespace Light { | ||||
|  |  | |||
|  | @ -2,14 +2,13 @@ | |||
| 
 | ||||
| #include <engine/base/base.hpp> | ||||
| #include <engine/graphics/shader.hpp> | ||||
| #include <engine/utils/file_manager.hpp> | ||||
| 
 | ||||
| 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
 | ||||
|  |  | |||
|  | @ -1,80 +0,0 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <engine/base/base.hpp> | ||||
| 
 | ||||
| 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
 | ||||
|  | @ -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<Shader> | ||||
| 	{ | ||||
| 		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<std::string, Ref<Shader>> m_shaders; | ||||
| 
 | ||||
| 	std::unordered_map<std::string, Ref<Texture>> m_textures; | ||||
|  |  | |||
|  | @ -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"); | ||||
|  |  | |||
|  | @ -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"); | ||||
|  |  | |||
|  | @ -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"); | ||||
|  |  | |||
|  | @ -11,15 +11,18 @@ | |||
| namespace Light { | ||||
| 
 | ||||
| auto Shader::create( | ||||
|     const BasicFileHandle& vertexFile, | ||||
|     const BasicFileHandle& pixelFile, | ||||
|     const Ref<SharedContext>&  /*sharedContext*/ | ||||
|     Assets::Blob vertex_blob, | ||||
|     Assets::Blob pixel_blob, | ||||
|     const Ref<SharedContext> &shared_context | ||||
| ) -> Ref<Shader> | ||||
| { | ||||
| 	std::ignore = shared_context; | ||||
| 
 | ||||
| 	// load shader source
 | ||||
| 	switch (GraphicsContext::get_graphics_api()) | ||||
| 	{ | ||||
| 	case GraphicsAPI::OpenGL: return create_ref<glShader>(vertexFile, pixelFile); | ||||
| 	case GraphicsAPI::OpenGL: | ||||
| 		return create_ref<glShader>(std::move(vertex_blob), std::move(pixel_blob)); | ||||
| 
 | ||||
| 	case GraphicsAPI::DirectX: | ||||
| 		lt_win(return create_ref<dxShader>( | ||||
|  |  | |||
|  | @ -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<const
 | ||||
| // char*>(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 | ||||
| 		); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,63 +0,0 @@ | |||
| #include <engine/utils/file_manager.hpp> | ||||
| #include <utility> | ||||
| 
 | ||||
| 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<char *>(data), size); | ||||
| 
 | ||||
| 	file.close(); | ||||
| 	return { data, static_cast<unsigned int>(size), path, name, extension }; | ||||
| } | ||||
| 
 | ||||
| } // namespace Light
 | ||||
|  | @ -1,68 +1,85 @@ | |||
| #include <asset_parser/assets/text.hpp> | ||||
| #include <asset_parser/assets/texture.hpp> | ||||
| #include <asset_parser/parser.hpp> | ||||
| #include <engine/graphics/graphics_context.hpp> | ||||
| #include <engine/graphics/shader.hpp> | ||||
| #include <engine/graphics/texture.hpp> | ||||
| #include <engine/utils/file_manager.hpp> | ||||
| #include <engine/utils/resource_manager.hpp> | ||||
| #include <logger/logger.hpp> | ||||
| 
 | ||||
| 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>( | ||||
| 	    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>(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<std::byte>(blob_metadata.uncompressed_size); | ||||
| 	asset.unpack_blob(blob_metadata.tag, blob.data(), blob.size()); | ||||
| 
 | ||||
| 	m_textures[name] = Ref<Texture>(Texture::create( | ||||
| 	    metadata.pixel_size[0], | ||||
| 	    metadata.pixel_size[1], | ||||
| 	    metadata.num_components, | ||||
| 	    std::bit_cast<unsigned char *>(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<std::byte>(blob_metadata.uncompressed_size); | ||||
| 		asset.unpack_blob(blob_metadata.tag, blob.data(), blob.size()); | ||||
| 
 | ||||
| 		m_textures[name] = Ref<Texture>(Texture::create( | ||||
| 		    metadata.pixel_size[0], | ||||
| 		    metadata.pixel_size[1], | ||||
| 		    metadata.num_components, | ||||
| 		    std::bit_cast<unsigned char *>(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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue