feat: asset baking
Only supported .png textures at the moment
This commit is contained in:
		
							parent
							
								
									71d08cbe9f
								
							
						
					
					
						commit
						38997b3908
					
				
					 23 changed files with 594 additions and 393 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								data/assets/textures/awesomeface.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/assets/textures/awesomeface.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/engine/icons/asset/dir.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/engine/icons/asset/dir.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/engine/icons/asset/img.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/engine/icons/asset/img.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/engine/icons/asset/scene.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/engine/icons/asset/scene.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								data/engine/icons/asset/txt.asset
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/engine/icons/asset/txt.asset
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -5,6 +5,7 @@ Layout | |||
| {version}              | 4 bytes, ie. uint32_t | ||||
| {general metadata}     | sizeof(AssetMetadata) | ||||
| {specialized metadata} | sizeof(XXXAssetMetadata), eg. TextureAssetMetadata | ||||
| {n}                    | 4 bytes, ie. uint32_t | ||||
| {blob_0...n metadata}  | n * sizeof(BlobMetadata) | ||||
| {blob_0...n data}      | variable size based on actual data | ||||
| {end marker}           | 8 byte, ie size_t for marking the END | ||||
|  | @ -13,7 +14,8 @@ Sections | |||
| --------------------------------------------------------------------------------------------------- | ||||
| version              -> The version of the asset for forward compatibility | ||||
| general metadata     -> Common asset metadata such as file-path, asset-type, creator, etc. | ||||
| specialized metadata -> Metadata specific to the asset, eg. texture dimensions for Textures | ||||
| specialized metadata -> Metadata specific to the asset, eg. texture dimensions for Textures. | ||||
| n                    -> The number of blobs. | ||||
| blob_0...n metadata  -> Metadata specifying how the actual data is packed, required for unpacking. | ||||
| blob_0...n data      -> The actual data, packed and compressed to be reacdy for direct engine consumption. | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										4
									
								
								docs/architecture/resource.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								docs/architecture/resource.rst
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| Resource Management | ||||
| 
 | ||||
| =================================================================================================== | ||||
| 
 | ||||
|  | @ -6,4 +6,5 @@ target_link_libraries( | |||
|     asset_baker | ||||
|     PRIVATE asset_parser | ||||
|     PRIVATE stb::stb | ||||
|     PRIVATE logger | ||||
| ) | ||||
|  |  | |||
							
								
								
									
										120
									
								
								modules/asset_baker/include/asset_baker/bakers.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								modules/asset_baker/include/asset_baker/bakers.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,120 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <asset_parser/assets/texture.hpp> | ||||
| #include <filesystem> | ||||
| #include <logger/logger.hpp> | ||||
| #include <string_view> | ||||
| #include <unordered_set> | ||||
| 
 | ||||
| #define STB_IMAGE_IMPLEMENTATION | ||||
| #include <stb_image.h> | ||||
| 
 | ||||
| namespace lt { | ||||
| 
 | ||||
| class Loader | ||||
| { | ||||
| public: | ||||
| 	[[nodiscard]] virtual auto get_name() const -> std::string_view = 0; | ||||
| 
 | ||||
| 	Loader() = default; | ||||
| 
 | ||||
| 	Loader(Loader &&) = default; | ||||
| 
 | ||||
| 	Loader(const Loader &) = delete; | ||||
| 
 | ||||
| 	auto operator=(Loader &&) -> Loader & = default; | ||||
| 
 | ||||
| 	auto operator=(const Loader &) -> Loader & = delete; | ||||
| 
 | ||||
| 	virtual ~Loader() = default; | ||||
| 
 | ||||
| private: | ||||
| }; | ||||
| 
 | ||||
| class TextureLoader: public Loader | ||||
| { | ||||
| public: | ||||
| 	TextureLoader() = default; | ||||
| 
 | ||||
| 	[[nodiscard]] virtual auto load(std::filesystem::path file_path) const | ||||
| 	    -> Assets::TextureAsset::PackageData | ||||
| 	    = 0; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| class StbLoader: public TextureLoader | ||||
| { | ||||
| public: | ||||
| 	StbLoader() = default; | ||||
| 
 | ||||
| 	void load(std::filesystem::path path); | ||||
| 
 | ||||
| 	[[nodiscard]] static auto get_supported_extensions() -> std::unordered_set<std::string_view> | ||||
| 	{ | ||||
| 		return { ".png" }; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_name() const -> std::string_view override | ||||
| 	{ | ||||
| 		return "StbLoader"; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto load(std::filesystem::path file_path) const | ||||
| 	    -> Assets::TextureAsset::PackageData override | ||||
| 	{ | ||||
| 		auto width = int {}; | ||||
| 		auto height = int {}; | ||||
| 		auto channels = int {}; | ||||
| 
 | ||||
| 		auto *pixels = stbi_load(file_path.string().c_str(), &width, &height, &channels, 4); | ||||
| 		if (!pixels) | ||||
| 		{ | ||||
| 			throw std::runtime_error { | ||||
| 				std::format("Failed to load image file at: {} using stbi_load", file_path.string()), | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		const auto metadata = Assets::Asset::Metadata { | ||||
| 			.type = Assets::Asset::Type::Texture, | ||||
| 		}; | ||||
| 
 | ||||
| 		const auto texture_metadata = Assets::TextureAsset::Metadata { | ||||
|             .format = Assets::TextureAsset::Format::RGBA8, | ||||
|             .num_components = static_cast<uint32_t>(channels), | ||||
|             .pixel_size = { | ||||
|                 static_cast<uint32_t>(width), | ||||
|                 static_cast<uint32_t>(height), | ||||
|                 {}, | ||||
|             }, | ||||
|         }; | ||||
| 
 | ||||
| 		auto pixels_blob = Assets::Blob {}; | ||||
| 		pixels_blob.resize(static_cast<size_t>(width) * height * channels); | ||||
| 
 | ||||
| 		// TODO(Light): figure out if it's possible to directly populate a blob with stbi functions
 | ||||
| 		memcpy(pixels_blob.data(), pixels, pixels_blob.size()); | ||||
| 		stbi_image_free(pixels); | ||||
| 
 | ||||
| 		return Assets::TextureAsset::PackageData { | ||||
| 			.metadata = metadata, | ||||
| 			.texture_metadata = texture_metadata, | ||||
| 			.pixels = std::move(pixels_blob), | ||||
| 		}; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| class TextureLoaderFactory | ||||
| { | ||||
| public: | ||||
| 	static auto create(std::string_view file_extension) -> std::unique_ptr<TextureLoader> | ||||
| 	{ | ||||
| 		if (StbLoader::get_supported_extensions().contains(file_extension)) | ||||
| 		{ | ||||
| 			return std::make_unique<StbLoader>(); | ||||
| 		} | ||||
| 
 | ||||
| 		return {}; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| } // namespace lt
 | ||||
|  | @ -1,85 +1,70 @@ | |||
| #include <asset_baker/bakers.hpp> | ||||
| #include <asset_parser/assets/texture.hpp> | ||||
| #include <asset_parser/parser.hpp> | ||||
| #include <filesystem> | ||||
| #include <iostream> | ||||
| #include <logger/logger.hpp> | ||||
| 
 | ||||
| #define STB_IMAGE_IMPLEMENTATION | ||||
| #include <stb_image.h> | ||||
| 
 | ||||
| #define ASSERT(x, ...)    \ | ||||
| 	if (!(x))             \ | ||||
| 	{                     \ | ||||
| 		log(__VA_ARGS__); \ | ||||
| 		return -1;        \ | ||||
| void try_packing_texture( | ||||
|     const std::filesystem::path &in_path, | ||||
|     const std::filesystem::path &out_path | ||||
| ) | ||||
| { | ||||
| 	auto texture_loader = lt::TextureLoaderFactory::create(in_path.extension().string()); | ||||
| 	if (!texture_loader) | ||||
| 	{ | ||||
| 		// Don't log anything; this is expected.
 | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	try | ||||
| 	{ | ||||
| 		Assets::TextureAsset::pack(texture_loader->load(in_path), out_path); | ||||
| 
 | ||||
| template<typename... Args> | ||||
| void log(Args &&...args) | ||||
| { | ||||
| 	(std::cout << ... << args); | ||||
| 	std::cout << '\n'; | ||||
| 		log_inf("Packed a texture:"); | ||||
| 		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("\tloader  : {}", texture_loader->get_name()); | ||||
| 		log_err("\tin path : {}", in_path.string()); | ||||
| 		log_err("\tout path: {}", out_path.string()); | ||||
| 		log_err("\texp.what: {}", exp.what()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| auto convert_image(const std::filesystem::path &input, const std::filesystem::path &output) -> bool | ||||
| auto main(int argc, char *argv[]) -> int32_t | ||||
| try | ||||
| { | ||||
| 	auto width = int {}; | ||||
| 	auto height = int {}; | ||||
| 	auto channels = int {}; | ||||
| 	if (argc != 2) | ||||
| 	{ | ||||
| 		throw std::logic_error("Argc should be 2 -- exe dir (implicit) and target dir"); | ||||
| 	} | ||||
| 
 | ||||
| 	auto *pixels = stbi_load(input.string().c_str(), &width, &height, &channels, 4); | ||||
| 	for (const auto &directory_iterator : | ||||
| 	     std::filesystem::recursive_directory_iterator(argv[1])) // NOLINT
 | ||||
| 	{ | ||||
| 		if (directory_iterator.is_directory()) | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 	if (!pixels) | ||||
| 		return false; | ||||
| 		const auto &in_path = directory_iterator.path(); | ||||
| 
 | ||||
| 	auto texture_info = Assets::TextureInfo { | ||||
| 		.size       = static_cast<size_t>(width * height * 4), | ||||
| 		.format     = Assets::TextureFormat::RGBA8, | ||||
| 		.pixel_size = { | ||||
| 		    static_cast<uint32_t>(width), | ||||
| 		    static_cast<uint32_t>(height), | ||||
| 		    0ul, | ||||
| 		}, | ||||
| 		.original_file = input.string(), | ||||
| 	}; | ||||
| 		auto out_path = in_path; | ||||
| 		out_path.replace_extension(".asset"); | ||||
| 
 | ||||
| 	auto file = Assets::pack_texture(&texture_info, pixels); | ||||
| 		try_packing_texture(in_path, out_path); | ||||
| 	} | ||||
| 
 | ||||
| 	stbi_image_free(pixels); | ||||
| 
 | ||||
| 	Assets::save_binary_file(output.string().c_str(), file); | ||||
| 
 | ||||
| 	return true; | ||||
| 	return EXIT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| catch (const std::exception &exp) | ||||
| { | ||||
| 	std::ios_base::sync_with_stdio(false); | ||||
| 	log_crt("Terminating due to uncaught exception:"); | ||||
| 	log_crt("\texception.what: {}:", exp.what()); | ||||
| 
 | ||||
| 	ASSERT( | ||||
| 	    argc == 3, | ||||
| 	    "Argc MUST be 3, 1: execution-path(implicit), 2: input-directory, 3: output-directory" | ||||
| 	); | ||||
| 
 | ||||
| 	for (const auto &p : std::filesystem::directory_iterator(argv[1])) | ||||
| 	{ | ||||
| 		if (p.path().extension() == ".png") | ||||
| 		{ | ||||
| 			log("Found a texture: ", p); | ||||
| 
 | ||||
| 			auto newp = p.path(); | ||||
| 			newp.replace_extension(".asset_texture"); | ||||
| 			convert_image(p.path(), newp); | ||||
| 		} | ||||
| 		else if (p.path().extension() == ".obj") | ||||
| 		{ | ||||
| 			log("Found a mesh -> ", p, " (unsupported)"); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			log("Unknown -> ", p); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return EXIT_FAILURE; | ||||
| } | ||||
|  |  | |||
|  | @ -7,4 +7,5 @@ target_link_libraries( | |||
|     asset_parser | ||||
|     PRIVATE LZ4::lz4_static  | ||||
|     PRIVATE nlohmann_json::nlohmann_json  | ||||
|     PRIVATE logger | ||||
| ) | ||||
|  |  | |||
|  | @ -1,34 +0,0 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| #include <asset_parser/parser.hpp> | ||||
| 
 | ||||
| namespace Assets { | ||||
| 
 | ||||
| enum class TextureFormat : uint8_t | ||||
| { | ||||
| 	None = 0, | ||||
| 	RGBA8, | ||||
| }; | ||||
| 
 | ||||
| struct TextureInfo | ||||
| { | ||||
| 	size_t size; | ||||
| 	CompressionMode compression_mode; | ||||
| 	TextureFormat format; | ||||
| 	std::array<uint32_t, 3> pixel_size; | ||||
| 	std::string original_file; | ||||
| }; | ||||
| 
 | ||||
| auto read_texture_info(AssetFile *file) -> TextureInfo; | ||||
| 
 | ||||
| void unpack_texture( | ||||
|     TextureInfo *info, | ||||
|     const void *source_buffer, | ||||
|     size_t source_size, | ||||
|     void *destination | ||||
| ); | ||||
| 
 | ||||
| auto pack_texture(TextureInfo *info, void *pixel_data) -> AssetFile; | ||||
| 
 | ||||
| } // namespace Assets
 | ||||
|  | @ -1,34 +1,276 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <compressors/compressors.hpp> | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
| #include <filesystem> | ||||
| #include <fstream> | ||||
| #include <logger/logger.hpp> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace Assets { | ||||
| 
 | ||||
| struct AssetFile | ||||
| { | ||||
| 	uint32_t version; | ||||
| constexpr auto current_version = uint32_t { 1 }; | ||||
| 
 | ||||
| struct BlobMetadata | ||||
| { | ||||
| 	enum class Tag : uint8_t | ||||
| 	{ | ||||
| 		color, | ||||
| 		depth, | ||||
| 		vertices, | ||||
| 		indices, | ||||
| 	}; | ||||
| 
 | ||||
| 	Tag tag; | ||||
| 
 | ||||
| 	size_t offset; | ||||
| 
 | ||||
| 	CompressionType compression_type; | ||||
| 
 | ||||
| 	size_t compressed_size; | ||||
| 
 | ||||
| 	size_t uncompressed_size; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| using Blob = std::vector<std::byte>; | ||||
| 
 | ||||
| class Asset | ||||
| { | ||||
| public: | ||||
| 	enum class Type : uint32_t // NOLINT(performance-enum-size)
 | ||||
| 	{ | ||||
| 		Texture, | ||||
| 		Mesh, | ||||
| 		Material, | ||||
| 	} type; | ||||
| 	}; | ||||
| 
 | ||||
| 	std::string json; | ||||
| 	std::vector<uint8_t> blob; | ||||
| 	struct Metadata | ||||
| 	{ | ||||
| 		Type type; | ||||
| 	}; | ||||
| 
 | ||||
| 	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; | ||||
| }; | ||||
| 
 | ||||
| enum class CompressionMode : uint32_t // NOLINT(performance-enum-size)
 | ||||
| class TextureAsset: public Asset | ||||
| { | ||||
| 	None, | ||||
| 	LZ4, | ||||
| 	LZ4HC, | ||||
| }; | ||||
| public: | ||||
| 	enum class Format : uint32_t // NOLINT(performance-enum-size)
 | ||||
| 	{ | ||||
| 		None = 0, | ||||
| 		RGBA8, | ||||
| 	}; | ||||
| 
 | ||||
| auto save_binary_file(const char *path, const AssetFile &in_file) -> bool; | ||||
| auto load_binary_file(const char *path, AssetFile &out_file) -> bool; | ||||
| 	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
 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								modules/asset_parser/include/compressors/compressors.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								modules/asset_parser/include/compressors/compressors.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <cstdint> | ||||
| 
 | ||||
| namespace Assets { | ||||
| 
 | ||||
| enum class CompressionType : uint32_t // NOLINT(performance-enum-size)
 | ||||
| { | ||||
| 	None, | ||||
| 	LZ4, | ||||
| 	LZ4HC, | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  | @ -2,79 +2,11 @@ | |||
| #include <lz4.h> | ||||
| #include <nlohmann/json.hpp> | ||||
| 
 | ||||
| // [version], [type] --
 | ||||
| // [asset_metadata], [blob_metadata] --
 | ||||
| // [blob] --
 | ||||
| 
 | ||||
| namespace Assets { | ||||
| 
 | ||||
| using namespace nlohmann; | ||||
| 
 | ||||
| auto read_texture_info(AssetFile *file) -> TextureInfo | ||||
| { | ||||
| 	json texture_meta_data = json::parse(file->json); | ||||
| 
 | ||||
| 	return TextureInfo { | ||||
| 		.size            = texture_meta_data["bufferSize"], | ||||
| 		.compression_mode = texture_meta_data["compression"], | ||||
| 		.format          = texture_meta_data["format"], | ||||
| 		.pixel_size      = { | ||||
| 		         texture_meta_data["width"], | ||||
| 		         texture_meta_data["height"], | ||||
| 		         0, | ||||
|         }, | ||||
| 		.original_file = texture_meta_data["originalFile"], | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| void unpack_texture( | ||||
|     TextureInfo *info, | ||||
|     const void *source_buffer, | ||||
|     size_t source_size, | ||||
|     void *destination | ||||
| ) | ||||
| { | ||||
| 	if (info->compression_mode == CompressionMode::LZ4) | ||||
| 	{ | ||||
| 		LZ4_decompress_safe( | ||||
| 		    (const char *)source_buffer, | ||||
| 		    (char *)destination, | ||||
| 		    source_size, | ||||
| 		    info->size | ||||
| 		); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		memcpy(destination, source_buffer, source_size); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| auto pack_texture(TextureInfo *info, void *pixel_data) -> AssetFile | ||||
| { | ||||
| 	json metadata; | ||||
| 	metadata["format"] = info->format; | ||||
| 	metadata["width"] = info->pixel_size[0]; | ||||
| 	metadata["height"] = info->pixel_size[1]; | ||||
| 	metadata["bufferSize"] = info->size; | ||||
| 	metadata["originalFile"] = info->original_file; | ||||
| 	metadata["compression"] = CompressionMode::LZ4; | ||||
| 
 | ||||
| 	AssetFile file; | ||||
| 	file.type = AssetFile::Type::Texture; | ||||
| 	file.version = 1u; | ||||
| 
 | ||||
| 	const int compress_staging = LZ4_compressBound(info->size); | ||||
| 	file.blob.resize(compress_staging); | ||||
| 	const int compression_size = LZ4_compress_default( | ||||
| 	    (const char *)pixel_data, | ||||
| 	    (char *)file.blob.data(), | ||||
| 	    info->size, | ||||
| 	    compress_staging | ||||
| 	); | ||||
| 	file.blob.resize(compression_size); | ||||
| 
 | ||||
| 
 | ||||
| 	metadata["compression"] = CompressionMode::LZ4; | ||||
| 
 | ||||
| 	file.json = metadata.dump(); | ||||
| 
 | ||||
| 	return file; | ||||
| } | ||||
| 
 | ||||
| } // namespace Assets
 | ||||
|  |  | |||
|  | @ -1,56 +1,62 @@ | |||
| #include <asset_parser/parser.hpp> | ||||
| #include <format> | ||||
| #include <fstream> | ||||
| #include <istream> | ||||
| #include <ostream> | ||||
| #include <utility> | ||||
| 
 | ||||
| namespace Assets { | ||||
| 
 | ||||
| auto save_binary_file(const char *path, const AssetFile &file) -> bool | ||||
| { | ||||
| 	std::ofstream outstream(path, std::ios::binary | std::ios::out); | ||||
| 
 | ||||
| 	outstream.write((const char *)&file.version, sizeof(uint32_t)); | ||||
| 	outstream.write((const char *)&file.type, sizeof(AssetFile::Type)); | ||||
| 
 | ||||
| 	uint32_t json_size = file.json.size(); | ||||
| 	uint32_t blob_size = file.blob.size(); | ||||
| 	outstream.write((const char *)&json_size, sizeof(uint32_t)); | ||||
| 	outstream.write((const char *)&blob_size, sizeof(uint32_t)); | ||||
| 
 | ||||
| 	outstream.write(file.json.c_str(), json_size); | ||||
| 	outstream.write((const char *)file.blob.data(), blob_size); | ||||
| 
 | ||||
| 	outstream.close(); | ||||
| 
 | ||||
| 	outstream.close(); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| auto load_binary_file(const char *path, AssetFile &out_file) -> bool | ||||
| { | ||||
| 	std::ifstream instream(path, std::ios::binary); | ||||
| 	instream.seekg(0ull); | ||||
| 
 | ||||
| 	if (!instream.is_open()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	instream.read((char *)&out_file.version, sizeof(uint32_t)); | ||||
| 	instream.read((char *)&out_file.type, sizeof(AssetFile::Type)); | ||||
| 
 | ||||
| 	uint32_t json_size; | ||||
| 	uint32_t blob_size; | ||||
| 	instream.read((char *)&json_size, sizeof(uint32_t)); | ||||
| 	instream.read((char *)&blob_size, sizeof(uint32_t)); | ||||
| 
 | ||||
| 	out_file.json.resize(json_size); | ||||
| 	out_file.blob.resize(blob_size); | ||||
| 	instream.read((char *)out_file.json.data(), json_size); | ||||
| 	instream.read((char *)out_file.blob.data(), blob_size); | ||||
| 
 | ||||
| 	instream.close(); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| // void Asset::unpack(std::byte *destination)
 | ||||
| // {
 | ||||
| // 	if (!m_stream.is_open())
 | ||||
| // 	{
 | ||||
| // 		throw std::logic_error {
 | ||||
| // 			"Failed to unpack asset: "
 | ||||
| // 			"ifstream is closed",
 | ||||
| // 		};
 | ||||
| // 	}
 | ||||
| //
 | ||||
| // 	switch (m_metadata.blob_compression_type)
 | ||||
| // 	{
 | ||||
| // 	case CompressionType::None:
 | ||||
| // 		if (m_metadata.packed_size != m_metadata.unpacked_size)
 | ||||
| // 		{
 | ||||
| // 			throw std::logic_error {
 | ||||
| // 				"Failed to unpack asset: "
 | ||||
| // 				"compression type set to none but packed/unpacked sizes differ",
 | ||||
| // 			};
 | ||||
| // 		}
 | ||||
| //
 | ||||
| // 		m_stream.read(
 | ||||
| // 		    std::bit_cast<char *>(destination),
 | ||||
| // 		    static_cast<long>(m_metadata.packed_size)
 | ||||
| // 		);
 | ||||
| // 		m_stream.close();
 | ||||
| //
 | ||||
| // 	case CompressionType::LZ4:
 | ||||
| // 		m_stream.close();
 | ||||
| // 		throw std::logic_error {
 | ||||
| // 			"Failed to unpack asset: "
 | ||||
| // 			"LZ4 compression is not implemented yet",
 | ||||
| // 		};
 | ||||
| //
 | ||||
| //
 | ||||
| // 	case CompressionType::LZ4HC:
 | ||||
| // 		m_stream.close();
 | ||||
| // 		throw std::logic_error {
 | ||||
| // 			"Failed to unpack asset: "
 | ||||
| // 			"LZ4HC compression is not implemented yet",
 | ||||
| // 		};
 | ||||
| //
 | ||||
| // 	default:
 | ||||
| // 		m_stream.close();
 | ||||
| // 		throw std::logic_error {
 | ||||
| // 			std::format(
 | ||||
| // 			    "Failed to unpack asset: "
 | ||||
| // 			    "Compression type was not recognized: {}",
 | ||||
| // 			    std::to_underlying(m_metadata.blob_compression_type)
 | ||||
| // 			),
 | ||||
| // 		};
 | ||||
| // 	}
 | ||||
| // }
 | ||||
| 
 | ||||
| } // namespace Assets
 | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ target_link_libraries( | |||
|   PUBLIC opengl::opengl | ||||
|   PUBLIC glfw | ||||
|   PUBLIC imgui | ||||
|   PUBLIC stb::stb | ||||
|   PUBLIC asset_parser | ||||
|   PUBLIC yaml-cpp::yaml-cpp | ||||
|   PUBLIC EnTT::EnTT | ||||
| ) | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ namespace Light { | |||
| class BasicFileHandle | ||||
| { | ||||
| public: | ||||
| virtual ~BasicFileHandle() = default; | ||||
| 	virtual ~BasicFileHandle() = default; | ||||
| 	BasicFileHandle( | ||||
| 	    uint8_t *data = nullptr, | ||||
| 	    uint32_t size = 0ull, | ||||
|  | @ -58,13 +58,12 @@ virtual ~BasicFileHandle() = default; | |||
| 		return is_valid(); | ||||
| 	} | ||||
| 
 | ||||
| protected: | ||||
| private: | ||||
| 	// made protected for custom free():
 | ||||
| 	uint8_t *m_data; | ||||
| 
 | ||||
| 	uint32_t m_size; | ||||
| 
 | ||||
| private: | ||||
| 	const std::string m_path; | ||||
| 
 | ||||
| 	const std::string m_name; | ||||
|  | @ -72,68 +71,10 @@ private: | |||
| 	const std::string m_extension; | ||||
| }; | ||||
| 
 | ||||
| class ImageFileHandle: public BasicFileHandle | ||||
| { | ||||
| public: | ||||
| virtual ~ImageFileHandle() = default; | ||||
| 	ImageFileHandle( | ||||
| 	    uint8_t *data, | ||||
| 	    uint32_t size, | ||||
| 	    const std::string &path, | ||||
| 	    const std::string &name, | ||||
| 	    const std::string &extension, | ||||
| 	    uint32_t width, | ||||
| 	    uint32_t height, | ||||
| 	    uint32_t components, | ||||
| 	    uint32_t desiredComponents | ||||
| 	) | ||||
| 	    : BasicFileHandle(data, size, path, name, extension) | ||||
| 	    , m_width(width) | ||||
| 	    , m_height(height) | ||||
| 	    , m_components(components) | ||||
| 	    , m_desired_components(desiredComponents) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	void release() override; | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_width() const -> uint32_t | ||||
| 	{ | ||||
| 		return m_width; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_height() const -> uint32_t | ||||
| 	{ | ||||
| 		return m_height; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_components() const -> uint32_t | ||||
| 	{ | ||||
| 		return m_components; | ||||
| 	} | ||||
| 
 | ||||
| 	[[nodiscard]] auto get_desired_components() const -> uint32_t | ||||
| 	{ | ||||
| 		return m_desired_components; | ||||
| 	} | ||||
| 
 | ||||
| private: | ||||
| 	uint32_t m_width; | ||||
| 
 | ||||
| 	uint32_t m_height; | ||||
| 
 | ||||
| 	uint32_t m_components; | ||||
| 
 | ||||
| 	uint32_t m_desired_components; | ||||
| }; | ||||
| 
 | ||||
| class FileManager | ||||
| { | ||||
| public: | ||||
| 	static auto read_text_file(const std::string &path) -> BasicFileHandle; | ||||
| 
 | ||||
| 	static auto read_image_file(const std::string &path, int32_t desiredComponents) | ||||
| 	    -> ImageFileHandle; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Light
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <engine/base/base.hpp> | ||||
| #include <filesystem> | ||||
| 
 | ||||
| namespace Light { | ||||
| 
 | ||||
|  | @ -26,13 +27,9 @@ public: | |||
| 		instance().load_shader_impl(name, vertexPath, pixelPath); | ||||
| 	} | ||||
| 
 | ||||
| 	static void load_texture( | ||||
| 	    const std::string &name, | ||||
| 	    const std::string &path, | ||||
| 	    unsigned int desiredComponents = 4u | ||||
| 	) | ||||
| 	static void load_texture(const std::string &name, const std::string &path) | ||||
| 	{ | ||||
| 		instance().load_texture_impl(name, path, desiredComponents); | ||||
| 		instance().load_texture_impl(name, path); | ||||
| 	} | ||||
| 
 | ||||
| 	static void release_texture(const std::string &name) | ||||
|  | @ -59,11 +56,7 @@ private: | |||
| 	    const std::string &pixelPath | ||||
| 	); | ||||
| 
 | ||||
| 	void load_texture_impl( | ||||
| 	    const std::string &name, | ||||
| 	    const std::string &path, | ||||
| 	    unsigned int desiredComponents = 4u | ||||
| 	); | ||||
| 	void load_texture_impl(const std::string &name, const std::filesystem::path &path); | ||||
| 
 | ||||
| 	void release_texture_impl(const std::string &name); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,5 @@ | |||
| #define STB_IMAGE_IMPLEMENTATION | ||||
| #include <engine/utils/file_manager.hpp> | ||||
| #include <utility> | ||||
| #include <stb_image.h> | ||||
| 
 | ||||
| namespace Light { | ||||
| 
 | ||||
|  | @ -27,7 +25,6 @@ void BasicFileHandle::release() | |||
| 	m_size = 0ull; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| auto FileManager::read_text_file(const std::string &path) -> BasicFileHandle | ||||
| { | ||||
| 	// parse path info
 | ||||
|  | @ -63,52 +60,52 @@ auto FileManager::read_text_file(const std::string &path) -> BasicFileHandle | |||
| 	return { data, static_cast<unsigned int>(size), path, name, extension }; | ||||
| } | ||||
| 
 | ||||
| auto FileManager::read_image_file(const std::string &path, int32_t desiredComponents) | ||||
|     -> ImageFileHandle | ||||
| { | ||||
| 	// parse path info
 | ||||
| 	auto name = path.substr(0, path.find('.') + -1); | ||||
| 	auto extension = path.substr(path.find('.') + 1); | ||||
| // auto FileManager::read_image_file(const std::string &path, int32_t desiredComponents)
 | ||||
| //     -> ImageFileHandle
 | ||||
| // {
 | ||||
| // 	// parse path info
 | ||||
| // 	auto name = path.substr(0, path.find('.') + -1);
 | ||||
| // 	auto extension = path.substr(path.find('.') + 1);
 | ||||
| //
 | ||||
| // 	// load image
 | ||||
| // 	auto width = 0;
 | ||||
| // 	auto height = 0;
 | ||||
| // 	auto fetchedComponents = 0;
 | ||||
| // 	auto *pixels = stbi_load(path.c_str(), &width, &height, &fetchedComponents, desiredComponents);
 | ||||
| //
 | ||||
| // 	// check
 | ||||
| // 	if (!pixels)
 | ||||
| // 	{
 | ||||
| // 		log_wrn("Failed to load image file: <{}>", path);
 | ||||
| // 	}
 | ||||
| // 	else if (fetchedComponents != desiredComponents)
 | ||||
| // 	{
 | ||||
| // 		log_wrn(
 | ||||
| // 		    "Mismatch of fetched/desired components: <{}> ({}/{})",
 | ||||
| // 		    name + '.' + extension,
 | ||||
| // 		    fetchedComponents,
 | ||||
| // 		    desiredComponents
 | ||||
| // 		);
 | ||||
| // 	}
 | ||||
| //
 | ||||
| // 	return ImageFileHandle(
 | ||||
| // 	    pixels,
 | ||||
| // 	    width * height,
 | ||||
| // 	    path,
 | ||||
| // 	    name,
 | ||||
| // 	    extension,
 | ||||
| // 	    width,
 | ||||
| // 	    height,
 | ||||
| // 	    fetchedComponents,
 | ||||
| // 	    desiredComponents
 | ||||
| // 	);
 | ||||
| // }
 | ||||
| 
 | ||||
| 	// load image
 | ||||
| 	auto width = 0; | ||||
| 	auto height = 0; | ||||
| 	auto fetchedComponents = 0; | ||||
| 	auto *pixels = stbi_load(path.c_str(), &width, &height, &fetchedComponents, desiredComponents); | ||||
| 
 | ||||
| 	// check
 | ||||
| 	if (!pixels) | ||||
| 	{ | ||||
| 		log_wrn("Failed to load image file: <{}>", path); | ||||
| 	} | ||||
| 	else if (fetchedComponents != desiredComponents) | ||||
| 	{ | ||||
| 		log_wrn( | ||||
| 		    "Mismatch of fetched/desired components: <{}> ({}/{})", | ||||
| 		    name + '.' + extension, | ||||
| 		    fetchedComponents, | ||||
| 		    desiredComponents | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	return ImageFileHandle( | ||||
| 	    pixels, | ||||
| 	    width * height, | ||||
| 	    path, | ||||
| 	    name, | ||||
| 	    extension, | ||||
| 	    width, | ||||
| 	    height, | ||||
| 	    fetchedComponents, | ||||
| 	    desiredComponents | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| void ImageFileHandle::release() | ||||
| { | ||||
| 	stbi_image_free(reinterpret_cast<void *>(m_data)); | ||||
| 	m_data = nullptr; | ||||
| 	m_size = 0ull; | ||||
| } | ||||
| // void ImageFileHandle::release()
 | ||||
| // {
 | ||||
| // 	stbi_image_free(reinterpret_cast<void *>(m_data));
 | ||||
| // 	m_data = nullptr;
 | ||||
| // 	m_size = 0ull;
 | ||||
| // }
 | ||||
| 
 | ||||
| } // namespace Light
 | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| #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> | ||||
|  | @ -12,49 +14,44 @@ void ResourceManager::load_shader_impl( | |||
|     const std::string &pixelPath | ||||
| ) | ||||
| { | ||||
| 	// check
 | ||||
| 	lt_assert(!vertexPath.empty(), "Empty 'vertexPath'"); | ||||
| 	lt_assert(!pixelPath.empty(), "Empty 'pixelPath'"); | ||||
| 
 | ||||
| 	// load files
 | ||||
| 	auto vertexFile = FileManager::read_text_file(vertexPath); | ||||
| 	auto pixelFile = FileManager::read_text_file(pixelPath); | ||||
| 
 | ||||
| 	// check
 | ||||
| 	lt_assert(vertexFile.is_valid(), "Failed to read vertex file: {}", vertexPath); | ||||
| 	lt_assert(pixelFile.is_valid(), "Failed to read vertex file: {}", pixelPath); | ||||
| 
 | ||||
| 	// create shader
 | ||||
| 	m_shaders[name] = Ref<Shader>( | ||||
| 	    Shader::create(vertexFile, pixelFile, GraphicsContext::get_shared_context()) | ||||
| 	); | ||||
| 
 | ||||
| 	// free file
 | ||||
| 	vertexFile.release(); | ||||
| 	pixelFile.release(); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::load_texture_impl( | ||||
|     const std::string &name, | ||||
|     const std::string &path, | ||||
|     unsigned int desiredComponents /* = 4u */ | ||||
| ) | ||||
| void ResourceManager::load_texture_impl(const std::string &name, const std::filesystem::path &path) | ||||
| { | ||||
| 	// load file
 | ||||
| 	auto imgFile = FileManager::read_image_file(path, desiredComponents); | ||||
| 	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()); | ||||
| 
 | ||||
| 	// create texture
 | ||||
| 	m_textures[name] = Ref<Texture>(Texture::create( | ||||
| 	    imgFile.get_width(), | ||||
| 	    imgFile.get_height(), | ||||
| 	    imgFile.get_components(), | ||||
| 	    imgFile.get_data(), | ||||
| 	    metadata.pixel_size[0], | ||||
| 	    metadata.pixel_size[1], | ||||
| 	    metadata.num_components, | ||||
| 	    std::bit_cast<unsigned char *>(blob.data()), | ||||
| 	    GraphicsContext::get_shared_context(), | ||||
| 	    path | ||||
| 	)); | ||||
| 
 | ||||
| 	// free file
 | ||||
| 	imgFile.release(); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::release_texture_impl(const std::string &name) | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ EditorLayer::EditorLayer(const std::string &name) | |||
| 		m_camera_entity = m_scene->create_entity("Camera"); | ||||
| 		m_camera_entity.add_component<CameraComponent>(SceneCamera(), true); | ||||
| 
 | ||||
| 		ResourceManager::load_texture("Awesomeface", "data/assets/textures/awesomeface.png"); | ||||
| 		ResourceManager::load_texture("Awesomeface", "data/assets/textures/awesomeface.asset"); | ||||
| 
 | ||||
| 		auto entity = Entity { m_scene->create_entity("Awesomeface", {}) }; | ||||
| 		entity.add_component<SpriteRendererComponent>( | ||||
|  |  | |||
|  | @ -10,10 +10,10 @@ AssetBrowserPanel::AssetBrowserPanel(Ref<Scene> active_scene) | |||
|     , m_assets_path("./data/assets") | ||||
|     , m_active_scene(std::move(active_scene)) | ||||
| { | ||||
| 	ResourceManager::load_texture("_Assets_Directory", "data/engine/icons/asset/dir.png"); | ||||
| 	ResourceManager::load_texture("_Assets_Scene", "data/engine/icons/asset/scene.png"); | ||||
| 	ResourceManager::load_texture("_Assets_Image", "data/engine/icons/asset/img.png"); | ||||
| 	ResourceManager::load_texture("_Assets_Text", "data/engine/icons/asset/txt.png"); | ||||
| 	ResourceManager::load_texture("_Assets_Directory", "data/engine/icons/asset/dir.asset"); | ||||
| 	ResourceManager::load_texture("_Assets_Scene", "data/engine/icons/asset/scene.asset"); | ||||
| 	ResourceManager::load_texture("_Assets_Image", "data/engine/icons/asset/img.asset"); | ||||
| 	ResourceManager::load_texture("_Assets_Text", "data/engine/icons/asset/txt.asset"); | ||||
| 
 | ||||
| 	m_directory_texture = ResourceManager::get_texture("_Assets_Directory"); | ||||
| 	m_scene_texture = ResourceManager::get_texture("_Assets_Scene"); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue