From a2f0f7c7a45ba8b30984fb135b8b54f11fb119f8 Mon Sep 17 00:00:00 2001 From: skal Date: Sun, 8 Mar 2026 09:33:17 +0100 Subject: feat: Implement dual-mode asset loading and update documentation This commit introduces a dual-mode asset loading system to enhance developer workflow and optimize release builds. Key changes include: - **Dual-Mode Asset Loading:** Assets are now loaded from disk during development (when is OFF) for faster iteration, particularly for heavy assets like and files. For release builds ( ON), all assets are embedded directly into the binary, ensuring a single, self-contained executable. - **Explicit Asset Typing:** Replaced generic asset type with specific types (, , , , ) in and the enum in for clearer categorization and more robust processing. - **Build System Integration:** Modified to pass a flag to in development builds. - **Asset Packer Updates:** now generates file paths for disk-loaded assets and embeds data for others based on the build mode. - **Asset Manager Enhancements:** includes new logic in for loading and caching disk-based assets and updates to for proper memory deallocation. - **Documentation:** Updated to reflect the new asset nomenclature and dual-mode loading strategy. - **Project Rules:** Added a concise rule to mandating top-level documentation updates for medium/large sub-system changes. handoff(Gemini): Implemented dual-mode asset loading and updated documentation. --- tools/asset_packer.cc | 106 ++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 50 deletions(-) (limited to 'tools') diff --git a/tools/asset_packer.cc b/tools/asset_packer.cc index c982a39..e28d71f 100644 --- a/tools/asset_packer.cc +++ b/tools/asset_packer.cc @@ -37,17 +37,6 @@ static const std::map kAssetPackerProcGenFuncMap = { #endif }; -static bool HasImageExtension(const std::string& filename) { - std::string ext = filename.substr(filename.find_last_of(".") + 1); - return ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "tga" || - ext == "bmp"; -} - -static bool HasMeshExtension(const std::string& filename) { - std::string ext = filename.substr(filename.find_last_of(".") + 1); - return ext == "obj"; -} - // Forward declaration struct AssetBuildInfo; @@ -348,14 +337,20 @@ static bool ProcessImageFile(const std::string& full_path, } int main(int argc, char* argv[]) { - if (argc != 4) { + if (argc < 4) { fprintf(stderr, "Usage: %s " - "\n", + " [--disk_load]\n", argv[0]); return 1; } + bool disk_load_mode = false; + if (argc > 4 && std::strcmp(argv[4], "--disk_load") == 0) { + disk_load_mode = true; + printf("Asset packer running in disk-load mode.\n"); + } + std::string assets_txt_path = argv[1]; std::string output_assets_h_path = argv[2]; std::string output_assets_data_cc_path = argv[3]; @@ -438,7 +433,7 @@ int main(int argc, char* argv[]) { info.data_array_name = "ASSET_DATA_" + info.name; info.params_array_name = "ASSET_PROC_PARAMS_" + info.name; info.func_name_str_name = "ASSET_PROC_FUNC_STR_" + info.name; - info.asset_type = "STATIC"; + info.asset_type = compression_type_str; if (compression_type_str.rfind("PROC_GPU(", 0) == 0) { info.asset_type = "PROC_GPU"; @@ -452,7 +447,11 @@ int main(int argc, char* argv[]) { } } else if (compression_type_str == "MP3") { info.asset_type = "MP3"; - } else if (compression_type_str != "NONE") { + } else if (compression_type_str != "WGSL" && + compression_type_str != "SPEC" && + compression_type_str != "TEXTURE" && + compression_type_str != "MESH" && + compression_type_str != "BINARY") { fprintf(stderr, "Warning: Unknown compression type '%s' for asset: %s\n", compression_type_str.c_str(), info.name.c_str()); @@ -488,44 +487,50 @@ int main(int argc, char* argv[]) { std::filesystem::path combined_path = base_path / info.filename; std::string full_path = combined_path.lexically_normal().string(); - std::vector buffer; - bool is_image = HasImageExtension(info.filename); - bool is_mesh = HasMeshExtension(info.filename); - - if (is_image) { - if (!ProcessImageFile(full_path, &buffer, info.name)) { - return 1; - } - } else if (is_mesh) { - if (!ProcessMeshFile(full_path, &buffer, info.name)) { - return 1; - } + if (disk_load_mode && + (info.asset_type == "SPEC" || info.asset_type == "MP3")) { + fprintf(assets_data_cc_file, + "alignas(16) static const char %s[] = \"%s\";\n", + info.data_array_name.c_str(), full_path.c_str()); + fprintf(assets_data_cc_file, "const size_t ASSET_SIZE_%s = %zu;\n", + info.name.c_str(), full_path.length() + 1); } else { - std::ifstream asset_file(full_path, std::ios::binary); - if (!asset_file.is_open()) { - fprintf(stderr, "Error: Could not open asset file: %s\n", - full_path.c_str()); - return 1; + std::vector buffer; + if (info.asset_type == "TEXTURE") { + if (!ProcessImageFile(full_path, &buffer, info.name)) { + return 1; + } + } else if (info.asset_type == "MESH") { + if (!ProcessMeshFile(full_path, &buffer, info.name)) { + return 1; + } + } else { + std::ifstream asset_file(full_path, std::ios::binary); + if (!asset_file.is_open()) { + fprintf(stderr, "Error: Could not open asset file: %s\n", + full_path.c_str()); + return 1; + } + buffer.assign((std::istreambuf_iterator(asset_file)), + std::istreambuf_iterator()); } - buffer.assign((std::istreambuf_iterator(asset_file)), - std::istreambuf_iterator()); - } - - size_t original_size = buffer.size(); - buffer.push_back(0); // Null terminator for safety - fprintf(assets_data_cc_file, "const size_t ASSET_SIZE_%s = %zu;\n", - info.name.c_str(), original_size); - fprintf(assets_data_cc_file, - "alignas(16) static const uint8_t %s[] = {\n ", - info.data_array_name.c_str()); - for (size_t i = 0; i < buffer.size(); ++i) { - if (i > 0 && i % 12 == 0) - fprintf(assets_data_cc_file, "\n "); - fprintf(assets_data_cc_file, "0x%02x%s", buffer[i], - (i == buffer.size() - 1 ? "" : ", ")); + size_t original_size = buffer.size(); + buffer.push_back(0); // Null terminator for safety + + fprintf(assets_data_cc_file, "const size_t ASSET_SIZE_%s = %zu;\n", + info.name.c_str(), original_size); + fprintf(assets_data_cc_file, + "alignas(16) static const uint8_t %s[] = {\n ", + info.data_array_name.c_str()); + for (size_t i = 0; i < buffer.size(); ++i) { + if (i > 0 && i % 12 == 0) + fprintf(assets_data_cc_file, "\n "); + fprintf(assets_data_cc_file, "0x%02x%s", buffer[i], + (i == buffer.size() - 1 ? "" : ", ")); + } + fprintf(assets_data_cc_file, "\n};\n"); } - fprintf(assets_data_cc_file, "\n};\n"); } else { fprintf(assets_data_cc_file, "static const float %s[] = {", info.params_array_name.c_str()); @@ -550,7 +555,8 @@ int main(int argc, char* argv[]) { info.params_array_name.c_str(), info.proc_params.size()); } else { fprintf(assets_data_cc_file, - "%s, ASSET_SIZE_%s, AssetType::%s, nullptr, nullptr, 0", + "(const uint8_t*)%s, ASSET_SIZE_%s, AssetType::%s, nullptr, " + "nullptr, 0", info.data_array_name.c_str(), info.name.c_str(), info.asset_type.c_str()); } -- cgit v1.2.3