From 30e691fea5097c2d50d05ab3a4e68757553569c4 Mon Sep 17 00:00:00 2001 From: Vlad-Stefan Harbuz Date: Sun, 30 May 2021 23:03:14 +0200 Subject: [PATCH] Make PeonyFile stuff much simpler and easier to understand --- CMakeLists.txt | 9 + data/scenes/animtest.peony_scene | 2 +- data/scenes/coast.peony_scene | 4 +- data/scenes/terraintest.peony_scene | 2 +- renderdoc_settings.cap | 2 +- src/_unity.cpp | 2 + src/constants.hpp | 3 +- src/engine.cpp | 148 ++++---- src/internals.cpp | 72 ++-- src/materials.cpp | 6 +- src/materials.hpp | 2 +- src/models.cpp | 143 ++++---- src/models.hpp | 40 +-- src/peony.cpp | 2 + src/peony_parser.cpp | 520 ++++------------------------ src/peony_parser.hpp | 110 ++---- src/peony_parser_utils.cpp | 291 ++++++++++++++++ src/peony_parser_utils.hpp | 42 +++ src/shaders.cpp | 21 +- src/state.hpp | 2 +- 20 files changed, 646 insertions(+), 777 deletions(-) create mode 100644 src/peony_parser_utils.cpp create mode 100644 src/peony_parser_utils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c79fc17..261ec05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") set(UNITY true) +# Treat all .c files as .cpp files +file(GLOB_RECURSE CFILES "${CMAKE_SOURCE_DIR}/src_external/*.c") +set_source_files_properties(${CFILES} PROPERTIES LANGUAGE CXX) + if (UNITY) add_executable( peony @@ -16,6 +20,7 @@ else() peony # WIN32 src_external/glad.cpp + src_external/pstr.c src/logs.cpp src/util.cpp src/debug.cpp @@ -38,6 +43,7 @@ else() src/physics.cpp src/models.cpp src/peony_parser.cpp + src/peony_parser_utils.cpp src/cameras.cpp src/state.cpp src/debug_ui.cpp @@ -57,6 +63,9 @@ target_link_libraries(peony PRIVATE glfw freetype assimp glm) target_precompile_headers(peony PRIVATE src/flags.hpp) if (MSVC) + set_property( + TARGET peony PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + ) add_compile_options( -FC -GS -MTd -MP18 -W4 -WL -WX -Z7 -Zo -diagnostics:column -fp:fast -nologo -sdl -guard:cf -permissive- -std:c++latest -wd4100 -wd4127 -wd4201 -O2 -GL -Oi diff --git a/data/scenes/animtest.peony_scene b/data/scenes/animtest.peony_scene index 021a71d..e6c1383 100644 --- a/data/scenes/animtest.peony_scene +++ b/data/scenes/animtest.peony_scene @@ -654,7 +654,7 @@ spatial_component.rotation = vec4(-90.0, 0.0, 1.0, 0.0) spatial_component.scale = vec3(1.0, 1.0, 1.0) > ocean -builtin_model_name = ocean +model_path = builtin:ocean materials = [ocean] render_passes = [forward_depth] spatial_component.position = vec3(0.0, 0.0, 0.0) diff --git a/data/scenes/coast.peony_scene b/data/scenes/coast.peony_scene index efb3df2..3eddcd3 100644 --- a/data/scenes/coast.peony_scene +++ b/data/scenes/coast.peony_scene @@ -63,7 +63,7 @@ spatial_component.scale = vec3(1.0, 1.0, 1.0) ; light_component.attenuation = vec4(2.0, 0.18, 0.064, 0.0) ; > axes -; builtin_model_name = axes +; model_path = builtin:axes ; materials = [axes] ; render_passes = [forward_nodepth] ; spatial_component.position = vec3(0.0, 0.1, 0.0) @@ -71,7 +71,7 @@ spatial_component.scale = vec3(1.0, 1.0, 1.0) ; spatial_component.scale = vec3(1.0, 1.0, 1.0) > ocean -builtin_model_name = ocean +model_path = builtin:ocean materials = [ocean] render_passes = [forward_depth] spatial_component.position = vec3(0.0, 0.0, 0.0) diff --git a/data/scenes/terraintest.peony_scene b/data/scenes/terraintest.peony_scene index 39a0dc4..7649bc0 100644 --- a/data/scenes/terraintest.peony_scene +++ b/data/scenes/terraintest.peony_scene @@ -45,7 +45,7 @@ behavior_component.behavior = test ; spatial_component.scale = vec3(1.0, 1.0, 1.0) > ocean -builtin_model_name = ocean +model_path = builtin:ocean materials = [ocean] render_passes = [forward_depth] spatial_component.position = vec3(0.0, 0.0, 0.0) diff --git a/renderdoc_settings.cap b/renderdoc_settings.cap index d8a02c3..cc8e232 100644 --- a/renderdoc_settings.cap +++ b/renderdoc_settings.cap @@ -5,7 +5,7 @@ "commandLine": "", "environment": [ ], - "executable": "D:\\proj-versioned\\peony\\build\\peony.exe", + "executable": "D:\\proj-versioned\\peony\\bin\\Debug\\peony.exe", "inject": false, "numQueuedFrames": 0, "options": { diff --git a/src/_unity.cpp b/src/_unity.cpp index 6f70bf3..bbfb511 100644 --- a/src/_unity.cpp +++ b/src/_unity.cpp @@ -1,4 +1,5 @@ #include "../src_external/glad.cpp" +#include "../src_external/pstr.c" #include "logs.cpp" #include "util.cpp" #include "debug.cpp" @@ -21,6 +22,7 @@ #include "physics.cpp" #include "models.cpp" #include "peony_parser.cpp" +#include "peony_parser_utils.cpp" #include "cameras.cpp" #include "state.cpp" #include "debug_ui.cpp" diff --git a/src/constants.hpp b/src/constants.hpp index 3d2d7ee..e9a1216 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -54,11 +54,10 @@ constexpr uint32 MAX_N_TEXTURES_PER_MATERIAL = 16; constexpr uint8 MAX_N_UNIFORMS = 64; constexpr uint8 MAX_UNIFORM_NAME_LENGTH = 64; constexpr uint8 MAX_N_TEXTURE_UNITS = 80; -constexpr uint32 MAX_TOKEN_LENGTH = 128; +constexpr uint32 MAX_COMMON_NAME_LENGTH = 128; constexpr uint32 MAX_N_BONES = 128; constexpr uint32 MAX_N_BONES_PER_VERTEX = 4; constexpr uint32 MAX_NODE_NAME_LENGTH = 32; constexpr uint32 MAX_N_ANIMATIONS = 2; constexpr uint32 MAX_N_ANIM_KEYS = 256; -constexpr uint32 MAX_N_PEONY_ARRAY_VALUES = 16; constexpr uint16 MAX_N_LIGHTS = 8; diff --git a/src/engine.cpp b/src/engine.cpp index e2d9685..ce65ccb 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,11 +1,12 @@ #include namespace chrono = std::chrono; +#include "../src_external/pstr.h" #include "util.hpp" #include "engine.hpp" #include "logs.hpp" -#include "str.hpp" #include "debug.hpp" #include "peony_parser.hpp" +#include "peony_parser_utils.hpp" #include "models.hpp" #include "internals.hpp" #include "renderer.hpp" @@ -98,109 +99,94 @@ namespace engine { return false; } - char scene_path[MAX_PATH] = {0}; - strcpy(scene_path, SCENE_DIR); - strcat(scene_path, scene_name); - strcat(scene_path, SCENE_EXTENSION); - strcat(scene_path, "\0"); - - gui::log("Loading scene: %s", scene_path); - // Get some memory for everything we need MemoryPool temp_memory_pool = {}; + defer { memory::destroy_memory_pool(&temp_memory_pool); }; - // Get EntityTemplates - StackArray entity_templates; - uint32 n_entities = 0; - bool32 could_load_file = peony_parser::parse_scene_file( - scene_path, &entity_templates, &n_entities - ); + // Load scene file + char scene_path[MAX_PATH] = {}; + pstr_vcat(scene_path, MAX_PATH, SCENE_DIR, scene_name, SCENE_EXTENSION, nullptr); + gui::log("Loading scene: %s", scene_path); - if (!could_load_file) { + PeonyFile *scene_file = MEMORY_PUSH(&temp_memory_pool, PeonyFile, "scene_file"); + if (!peony_parser::parse_file(scene_file, scene_path)) { gui::log("Could not load scene: %s", scene_path); return false; } - // Destroy everything after we've confirmed we could load the scene. + // Destroy our current scene after we've confirmed we could load the new scene. destroy_scene(state); - - strcpy(state->current_scene_name, scene_name); + pstr_copy(state->current_scene_name, MAX_COMMON_NAME_LENGTH, scene_name); // Get only the unique used materials - StackArray used_materials; - each (entity_template, entity_templates) { - each (material_name, entity_template->material_names) { - bool32 does_material_already_exist = false; - each (used_material, used_materials) { - if (str::eq(*material_name, *used_material)) { - does_material_already_exist = true; - break; - } - } - if (!does_material_already_exist) { - strcpy(*(used_materials.push()), *material_name); - } - } - } + Array used_materials( + &temp_memory_pool, MAX_N_MATERIALS, "used_materials" + ); + peony_parser_utils::get_unique_string_values_for_prop_name( + scene_file, &used_materials, "materials" + ); - // Create materials - MaterialTemplate material_template; + // Create Materials + PeonyFile *material_file = MEMORY_PUSH(&temp_memory_pool, PeonyFile, "material_file"); each (used_material, used_materials) { - material_template = {}; - char path[MAX_PATH]; - peony_parser::get_material_path(path, *used_material); - peony_parser::parse_material_file(path, &material_template); - peony_parser::create_material_from_template( + memset(material_file, 0, sizeof(PeonyFile)); + char material_file_path[MAX_PATH] = {}; + pstr_vcat( + material_file_path, MAX_PATH, + MATERIAL_FILE_DIRECTORY, *used_material, MATERIAL_FILE_EXTENSION, nullptr + ); + if (!peony_parser::parse_file(material_file, material_file_path)) { + gui::log("Could not load material: %s", material_file_path); + break; + } + assert(material_file->n_entries > 0); + peony_parser_utils::create_material_from_peony_file_entry( state->materials.push(), - &material_template, + &material_file->entries[0], &state->builtin_textures, &temp_memory_pool ); } - // Create entity, ModelLoader, EntityLoader - range (0, n_entities) { - EntityTemplate *entity_template = entity_templates[idx]; - Entity *entity = entities::add_entity_to_set( - &state->entity_set, entity_template->entity_debug_name - ); + range (0, scene_file->n_entries) { + PeonyFileEntry *entry = &scene_file->entries[idx]; + + // Create Entity + Entity *entity = entities::add_entity_to_set(&state->entity_set, entry->name); - // NOTE: We only want to make a ModelLoader from this EntityTemplate - // if we haven't already encountered this model is a previous - // EntityTemplate. If two entities have the same - // `model_path_or_builtin_model_name`, we just make one model and use it - // in both. + // Create ModelLoader + char const *model_path = peony_parser_utils::get_string( + peony_parser_utils::find_prop(entry, "model_path") + ); + // NOTE: We only want to make a ModelLoader from this PeonyFileEntry if we haven't + // already encountered this model in a previous entry. If two entities + // have the same `model_path`, we just make one model and use it in both. ModelLoader *found_model_loader = state->model_loaders.find( - [entity_template](ModelLoader *candidate_model_loader) -> bool32 { - return str::eq( - entity_template->model_path_or_builtin_model_name, - candidate_model_loader->model_path_or_builtin_model_name + [model_path](ModelLoader *candidate_model_loader) -> bool32 { + return pstr_eq( + model_path, + candidate_model_loader->model_path ); } ); if (found_model_loader) { - logs::info( - "Skipping already-loaded model %s", - entity_template->model_path_or_builtin_model_name - ); - } - if (!found_model_loader) { - peony_parser::create_model_loader_from_entity_template( - entity_template, + logs::info("Skipping already-loaded model %s", model_path); + } else { + peony_parser_utils::create_model_loader_from_peony_file_entry( + entry, entity->handle, - &state->model_loaders + state->model_loaders.push() ); } - peony_parser::create_entity_loader_from_entity_template( - entity_template, + + // Create EntityLoader + peony_parser_utils::create_entity_loader_from_peony_file_entry( + entry, entity->handle, - &state->entity_loader_set + state->entity_loader_set.loaders[entity->handle] ); } - // Clean up - memory::destroy_memory_pool(&temp_memory_pool); - return true; } @@ -211,14 +197,14 @@ namespace engine { char command[input::MAX_TEXT_INPUT_COMMAND_LENGTH] = {0}; char arguments[input::MAX_TEXT_INPUT_ARGUMENTS_LENGTH] = {0}; - str::split_on_first_occurrence( + pstr_split_on_first_occurrence( state->input_state.text_input, command, input::MAX_TEXT_INPUT_COMMAND_LENGTH, arguments, input::MAX_TEXT_INPUT_ARGUMENTS_LENGTH, ' ' ); - if (str::eq(command, "help")) { + if (pstr_eq(command, "help")) { gui::log( "Some useful commands\n" "--------------------\n" @@ -227,9 +213,9 @@ namespace engine { "Use texture \"none\" to disable.\n" "help: show help" ); - } else if (str::eq(command, "loadscene")) { + } else if (pstr_eq(command, "loadscene")) { load_scene(arguments, state); - } else if (str::eq(command, "renderdebug")) { + } else if (pstr_eq(command, "renderdebug")) { state->renderdebug_displayed_texture_type = materials::texture_type_from_string( arguments ); @@ -237,7 +223,7 @@ namespace engine { gui::log("Unknown command: %s", command); } - str::clear(state->input_state.text_input); + pstr_clear(state->input_state.text_input); } @@ -398,15 +384,13 @@ namespace engine { ModelLoader *model_loader = state->model_loaders.find( [entity_loader](ModelLoader *candidate_model_loader) -> bool32 { - return str::eq( - entity_loader->model_path_or_builtin_model_name, - candidate_model_loader->model_path_or_builtin_model_name - ); + return pstr_eq(entity_loader->model_path, candidate_model_loader->model_path); } ); if (!model_loader) { logs::fatal( - "Encountered an EntityLoader for which we cannot find the ModelLoader." + "Encountered an EntityLoader %d for which we cannot find the ModelLoader.", + entity_loader->entity_handle ); } diff --git a/src/internals.cpp b/src/internals.cpp index f3e3991..49451d9 100644 --- a/src/internals.cpp +++ b/src/internals.cpp @@ -188,7 +188,6 @@ void internals::create_internal_materials(State *state) { ); } - // We've created all internal materials, so we will mark the next position // in the array of materials, so we know where non-internal materials start. state->first_non_internal_material_idx = state->materials.length; @@ -215,19 +214,15 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader, - ModelSource::data, - "screenquad_lighting" - ); + models::init_model_loader(model_loader, "builtin:screenquad_lighting"); models::init_entity_loader( entity_loader, "screenquad_lighting", - "screenquad_lighting", + "builtin:screenquad_lighting", RenderPass::lighting, entity->handle ); - strcpy(*(model_loader->material_names.push()), "lighting"); + models::add_material_to_model_loader(model_loader, "lighting"); } #if USE_BLOOM @@ -238,20 +233,15 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader - entity_loader, - ModelSource::data, - "screenquad_preblur" - ); + models::init_model_loader(model_loader "builtin:screenquad_preblur"); models::init_entity_loader( entity_loader, "screenquad_preblur", - "screenquad_preblur", + "builtin:screenquad_preblur", RenderPass::preblur, entity->handle ); - strcpy(*(model_loader->material_names.push()), "preblur"); + models::add_material_to_model_loader(model_loader, "preblur"); } // Blur 1 screenquad @@ -261,19 +251,15 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader, - ModelSource::data, - "screenquad_blur1" - ); + models::init_model_loader(model_loader, "builtin:screenquad_blur1"); models::init_entity_loader( entity_loader, "screenquad_blur1", - "screenquad_blur1", + "builtin:screenquad_blur1", RenderPass::blur1, entity->handle ); - strcpy(*(model_loader->material_names.push()), "blur1"); + models::add_material_to_model_loader(model_loader, "blur1"); } // Blur 2 screenquad @@ -283,19 +269,15 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader, - ModelSource::data, - "screenquad_blur2", - ); + models::init_model_loader(model_loader, "builtin:screenquad_blur2"); models::init_entity_loader( entity_loader, "screenquad_blur2", - "screenquad_blur2", + "builtin:screenquad_blur2", RenderPass::blur2, entity->handle ); - strcpy(*(model_loader->material_names.push()), "blur2"); + models::add_material_to_model_loader(model_loader, "blur2"); } #endif @@ -306,19 +288,15 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader, - ModelSource::data, - "screenquad_postprocessing" - ); + models::init_model_loader(model_loader, "builtin:screenquad_postprocessing"); models::init_entity_loader( entity_loader, "screenquad_postprocessing", - "screenquad_postprocessing", + "builtin:screenquad_postprocessing", RenderPass::postprocessing, entity->handle ); - strcpy(*(model_loader->material_names.push()), "postprocessing"); + models::add_material_to_model_loader(model_loader, "postprocessing"); } // Debug screenquad @@ -328,19 +306,15 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader, - ModelSource::data, - "screenquad_renderdebug" - ); + models::init_model_loader(model_loader, "builtin:screenquad_renderdebug"); models::init_entity_loader( entity_loader, "screenquad_renderdebug", - "screenquad_renderdebug", + "builtin:screenquad_renderdebug", RenderPass::renderdebug, entity->handle ); - strcpy(*(model_loader->material_names.push()), "renderdebug"); + models::add_material_to_model_loader(model_loader, "renderdebug"); } // Skysphere @@ -351,15 +325,11 @@ void internals::create_internal_entities(State *state) { ); ModelLoader *model_loader = state->model_loaders.push(); EntityLoader *entity_loader = state->entity_loader_set.loaders[entity->handle]; - models::init_model_loader( - model_loader, - ModelSource::data, - "skysphere" - ); + models::init_model_loader(model_loader, "builtin:skysphere"); models::init_entity_loader( entity_loader, "skysphere", - "skysphere", + "builtin:skysphere", RenderPass::forward_skybox, entity->handle ); @@ -369,7 +339,7 @@ void internals::create_internal_entities(State *state) { .rotation = glm::angleAxis(radians(0.0f), v3(1.0f, 0.0f, 0.0f)), .scale = v3(75.0f), }; - strcpy(*(model_loader->material_names.push()), "skysphere"); + models::add_material_to_model_loader(model_loader, "skysphere"); #endif } diff --git a/src/materials.cpp b/src/materials.cpp index 934b621..8951b76 100644 --- a/src/materials.cpp +++ b/src/materials.cpp @@ -1,3 +1,4 @@ +#include "../src_external/pstr.h" #include "shaders.hpp" #include "array.hpp" #include "util.hpp" @@ -423,7 +424,7 @@ Material* materials::init_material( Material *material, const char *name ) { - strcpy(material->name, name); + pstr_copy(material->name, MAX_COMMON_NAME_LENGTH, name); material->state = MaterialState::initialized; return material; }; @@ -470,8 +471,9 @@ void materials::add_texture_to_material( material->is_screensize_dependent = true; } material->textures[material->n_textures++] = texture; - strcpy( + pstr_copy( material->texture_uniform_names[material->idx_texture_uniform_names++], + MAX_COMMON_NAME_LENGTH, uniform_name ); } diff --git a/src/materials.hpp b/src/materials.hpp index 7de96a2..96509eb 100644 --- a/src/materials.hpp +++ b/src/materials.hpp @@ -118,7 +118,7 @@ namespace materials { }; struct Material { - char name[MAX_TOKEN_LENGTH]; + char name[MAX_COMMON_NAME_LENGTH]; MaterialState state; bool32 have_textures_been_generated = false; bool32 is_screensize_dependent = false; diff --git a/src/models.cpp b/src/models.cpp index 88f7770..3eac23a 100644 --- a/src/models.cpp +++ b/src/models.cpp @@ -1,7 +1,7 @@ #include "../src_external/glad/glad.h" +#include "../src_external/pstr.h" #include #include -#include "str.hpp" #include "pack.hpp" #include "logs.hpp" #include "models.hpp" @@ -231,7 +231,11 @@ namespace models { .idx_parent = idx_parent, // NOTE: offset is added later, since we don't have the aiBone at this stage. }; - strcpy(animation_component->bones[idx_new_bone].name, node->mName.C_Str()); + pstr_copy( + animation_component->bones[idx_new_bone].name, + MAX_NODE_NAME_LENGTH, + node->mName.C_Str() + ); animation_component->n_bones++; range (0, node->mNumChildren) { @@ -280,7 +284,11 @@ namespace models { .duration = ai_animation->mDuration * ai_animation->mTicksPerSecond, .idx_bone_matrix_set = anim::push_to_bone_matrix_pool(bone_matrix_pool), }; - strcpy(animation->name, ai_animation->mName.C_Str()); + pstr_copy( + animation->name, + MAX_NODE_NAME_LENGTH, + ai_animation->mName.C_Str() + ); // Calculate bone matrices. // NOTE: We do not finalise the bone matrices at this stage! @@ -293,7 +301,7 @@ namespace models { range_named (idx_channel, 0, ai_animation->mNumChannels) { aiNodeAnim *ai_channel = ai_animation->mChannels[idx_channel]; - if (str::eq(ai_channel->mNodeName.C_Str(), bone->name)) { + if (pstr_eq(ai_channel->mNodeName.C_Str(), bone->name)) { found_channel_idx = idx_channel; did_find_channel = true; break; @@ -432,7 +440,7 @@ namespace models { bool32 did_find_bone = false; range_named (idx_animcomp_bone, 0, animation_component->n_bones) { - if (str::eq( + if (pstr_eq( animation_component->bones[idx_animcomp_bone].name, ai_bone->mName.C_Str() )) { did_find_bone = true; @@ -515,9 +523,8 @@ namespace models { ) { // NOTE: This function stores its vertex data in the MemoryPool for each // mesh, and so is intended to be called from a separate thread. - char full_path[MAX_PATH]; - strcpy(full_path, MODEL_DIR); - strcat(full_path, model_loader->model_path_or_builtin_model_name); + char full_path[MAX_PATH] = {}; + pstr_vcat(full_path, MAX_PATH, MODEL_DIR, model_loader->model_path, nullptr); START_TIMER(assimp_import); const aiScene *scene = aiImportFile( @@ -541,19 +548,9 @@ namespace models { } AnimationComponent *animation_component = &model_loader->animation_component; - - load_bones( - animation_component, scene - ); - - load_node( - model_loader, scene->mRootNode, scene, m4(1.0f), 0ULL - ); - - load_animations( - animation_component, scene, bone_matrix_pool - ); - + load_bones(animation_component, scene); + load_node(model_loader, scene->mRootNode, scene, m4(1.0f), 0ULL); + load_animations(animation_component, scene, bone_matrix_pool); aiReleaseImport(scene); model_loader->state = ModelLoaderState::mesh_data_loaded; @@ -573,13 +570,13 @@ namespace models { uint32 n_indices = 0; GLenum mode = 0; - if (str::eq(model_loader->model_path_or_builtin_model_name, "axes")) { + if (pstr_eq(model_loader->model_path, "builtin:axes")) { vertex_data = (Vertex*)AXES_VERTICES; n_vertices = 6; index_data = nullptr; n_indices = 0; mode = GL_LINES; - } else if (str::eq(model_loader->model_path_or_builtin_model_name, "ocean")) { + } else if (pstr_eq(model_loader->model_path, "builtin:ocean")) { make_plane( &temp_memory_pool, 200, 200, @@ -588,7 +585,7 @@ namespace models { &vertex_data, &index_data ); mode = GL_TRIANGLES; - } else if (str::eq(model_loader->model_path_or_builtin_model_name, "skysphere")) { + } else if (pstr_eq(model_loader->model_path, "builtin:skysphere")) { make_sphere( &temp_memory_pool, 64, 64, @@ -597,7 +594,7 @@ namespace models { ); mode = GL_TRIANGLE_STRIP; } else if ( - str::starts_with(model_loader->model_path_or_builtin_model_name, "screenquad") + pstr_starts_with(model_loader->model_path, "builtin:screenquad") ) { vertex_data = (Vertex*)SCREENQUAD_VERTICES; n_vertices = 6; @@ -605,10 +602,7 @@ namespace models { n_indices = 0; mode = GL_TRIANGLES; } else { - logs::fatal( - "Could not find builtin model: %s", - model_loader->model_path_or_builtin_model_name - ); + logs::fatal("Could not find builtin model: %s", model_loader->model_path); } Mesh *mesh = &model_loader->meshes[model_loader->n_meshes++]; @@ -665,29 +659,29 @@ const char* models::render_pass_to_string(RenderPass render_pass) { RenderPass models::render_pass_from_string(const char* str) { - if (str::eq(str, "none")) { + if (pstr_eq(str, "none")) { return RenderPass::none; - } else if (str::eq(str, "shadowcaster")) { + } else if (pstr_eq(str, "shadowcaster")) { return RenderPass::shadowcaster; - } else if (str::eq(str, "deferred")) { + } else if (pstr_eq(str, "deferred")) { return RenderPass::deferred; - } else if (str::eq(str, "forward_depth")) { + } else if (pstr_eq(str, "forward_depth")) { return RenderPass::forward_depth; - } else if (str::eq(str, "forward_nodepth")) { + } else if (pstr_eq(str, "forward_nodepth")) { return RenderPass::forward_nodepth; - } else if (str::eq(str, "forward_skybox")) { + } else if (pstr_eq(str, "forward_skybox")) { return RenderPass::forward_skybox; - } else if (str::eq(str, "lighting")) { + } else if (pstr_eq(str, "lighting")) { return RenderPass::lighting; - } else if (str::eq(str, "postprocessing")) { + } else if (pstr_eq(str, "postprocessing")) { return RenderPass::postprocessing; - } else if (str::eq(str, "preblur")) { + } else if (pstr_eq(str, "preblur")) { return RenderPass::preblur; - } else if (str::eq(str, "blur1")) { + } else if (pstr_eq(str, "blur1")) { return RenderPass::blur1; - } else if (str::eq(str, "blur2")) { + } else if (pstr_eq(str, "blur2")) { return RenderPass::blur2; - } else if (str::eq(str, "renderdebug")) { + } else if (pstr_eq(str, "renderdebug")) { return RenderPass::renderdebug; } else { logs::fatal("Could not parse RenderPass: %s", str); @@ -704,9 +698,9 @@ bool32 models::prepare_model_loader_and_check_if_done( BoneMatrixPool *bone_matrix_pool ) { if (model_loader->state == ModelLoaderState::initialized) { - if (model_loader->model_source != ModelSource::file) { + if (pstr_starts_with(model_loader->model_path, "builtin:")) { logs::error( - "Found model with model_source=file for which no vertex data was loaded." + "Found model with builtin model_path for which no vertex data was loaded." ); return false; } @@ -723,24 +717,21 @@ bool32 models::prepare_model_loader_and_check_if_done( } if (model_loader->state == ModelLoaderState::mesh_data_loaded) { - // Setup vertex buffers - if (model_loader->model_source == ModelSource::file) { - for (uint32 idx = 0; idx < model_loader->n_meshes; idx++) { - Mesh *mesh = &model_loader->meshes[idx]; - setup_mesh_vertex_buffers( - mesh, - mesh->vertices, mesh->n_vertices, - mesh->indices, mesh->n_indices - ); - memory::destroy_memory_pool(&mesh->temp_memory_pool); - } + for (uint32 idx = 0; idx < model_loader->n_meshes; idx++) { + Mesh *mesh = &model_loader->meshes[idx]; + setup_mesh_vertex_buffers( + mesh, + mesh->vertices, mesh->n_vertices, + mesh->indices, mesh->n_indices + ); + memory::destroy_memory_pool(&mesh->temp_memory_pool); } model_loader->state = ModelLoaderState::vertex_buffers_set_up; } if (model_loader->state == ModelLoaderState::vertex_buffers_set_up) { // Set material names for each mesh - range_named (idx_material, 0, model_loader->material_names.length) { + range_named (idx_material, 0, model_loader->n_material_names) { range_named (idx_mesh, 0, model_loader->n_meshes) { Mesh *mesh = &model_loader->meshes[idx_mesh]; uint8 mesh_number = pack::get(&mesh->indices_pack, 0); @@ -751,9 +742,13 @@ bool32 models::prepare_model_loader_and_check_if_done( // meshes all get material number 0. if ( mesh_number == idx_material || - (mesh_number >= model_loader->material_names.length && idx_material == 0) + (mesh_number >= model_loader->n_material_names && idx_material == 0) ) { - strcpy(mesh->material_name, *(model_loader->material_names[idx_material])); + pstr_copy( + mesh->material_name, + MAX_COMMON_NAME_LENGTH, + model_loader->material_names[idx_material] + ); } } } @@ -876,21 +871,28 @@ bool32 models::is_entity_loader_valid(EntityLoader *entity_loader) { } +void models::add_material_to_model_loader( + ModelLoader *model_loader, + char const *material_name +) { + pstr_copy( + model_loader->material_names[model_loader->n_material_names++], + MAX_COMMON_NAME_LENGTH, + material_name + ); +} + + ModelLoader* models::init_model_loader( ModelLoader *model_loader, - ModelSource model_source, - const char *model_path_or_builtin_model_name + const char *model_path ) { assert(model_loader); - model_loader->model_source = model_source; - strcpy( - model_loader->model_path_or_builtin_model_name, - model_path_or_builtin_model_name - ); + pstr_copy(model_loader->model_path, MAX_PATH, model_path); model_loader->state = ModelLoaderState::initialized; - if (model_source == ModelSource::data) { + if (pstr_starts_with(model_path, "builtin:")) { load_model_from_data(model_loader); } @@ -901,18 +903,17 @@ ModelLoader* models::init_model_loader( EntityLoader* models::init_entity_loader( EntityLoader *entity_loader, const char *name, - const char *model_path_or_builtin_model_name, + const char *model_path, RenderPass render_pass, EntityHandle entity_handle ) { assert(entity_loader); - strcpy(entity_loader->name, name); - strcpy( - entity_loader->model_path_or_builtin_model_name, - model_path_or_builtin_model_name - ); + pstr_copy(entity_loader->name, MAX_COMMON_NAME_LENGTH, name); + pstr_copy(entity_loader->model_path, MAX_PATH, model_path); entity_loader->render_pass = render_pass; entity_loader->entity_handle = entity_handle; + // TODO: Can we move this to constructor? + // If so, can we do so for other init_*() methods? entity_loader->state = EntityLoaderState::initialized; return entity_loader; } diff --git a/src/models.hpp b/src/models.hpp index fbf1fb0..a351800 100644 --- a/src/models.hpp +++ b/src/models.hpp @@ -14,6 +14,9 @@ #include "lights.hpp" namespace models { + // NOTE: Should be at least peony_parser::MAX_N_ARRAY_VALUES + constexpr uint32 const MAX_N_COMMON_ARRAY_VALUES = 8; + enum class RenderMode {regular, depth}; enum class RenderPass : uint32 { @@ -31,15 +34,6 @@ namespace models { renderdebug = (1 << 10), }; - enum class ModelSource { - // Invalid. - none, - // Loaded on initialisation, from given vertex data. - file, - // Loaded on demand, from file. - data - }; - struct Vertex { v3 position; v3 normal; @@ -51,7 +45,7 @@ namespace models { struct Mesh { MemoryPool temp_memory_pool; m4 transform; - char material_name[MAX_TOKEN_LENGTH]; + char material_name[MAX_COMMON_NAME_LENGTH]; Pack indices_pack; uint32 vao; uint32 vbo; @@ -73,12 +67,15 @@ namespace models { }; struct ModelLoader { - ModelSource model_source; - char model_path_or_builtin_model_name[MAX_PATH]; + // These from from the file + char model_path[MAX_PATH]; + char material_names[MAX_COMMON_NAME_LENGTH][MAX_N_COMMON_ARRAY_VALUES]; + uint32 n_material_names; + + // These are created later Mesh meshes[MAX_N_MESHES]; uint32 n_meshes; AnimationComponent animation_component; - StackArray material_names; ModelLoaderState state; }; @@ -90,14 +87,14 @@ namespace models { struct EntityLoader { char name[MAX_DEBUG_NAME_LENGTH]; - char model_path_or_builtin_model_name[MAX_PATH]; + char model_path[MAX_PATH]; EntityHandle entity_handle; + RenderPass render_pass; + EntityLoaderState state; SpatialComponent spatial_component; LightComponent light_component; BehaviorComponent behavior_component; PhysicsComponent physics_component; - RenderPass render_pass; - EntityLoaderState state; }; struct EntityLoaderSet { @@ -139,15 +136,18 @@ namespace models { ); bool32 is_model_loader_valid(ModelLoader *model_loader); bool32 is_entity_loader_valid(EntityLoader *entity_loader); + void add_material_to_model_loader( + ModelLoader *model_loader, + char const *material_name + ); ModelLoader* init_model_loader( ModelLoader *model_loader, - ModelSource model_source, - const char *model_path_or_builtin_model_name + const char *model_path ); EntityLoader* init_entity_loader( EntityLoader *entity_loader, const char *name, - const char *model_path_or_builtin_model_name, + const char *model_path, RenderPass render_pass, EntityHandle entity_handle ); @@ -155,7 +155,7 @@ namespace models { void destroy_drawable_component(DrawableComponent *drawable_component); } -using models::ModelSource, models::Vertex, models::Mesh, models::ModelLoaderState, +using models::Vertex, models::Mesh, models::ModelLoaderState, models::ModelLoader, models::EntityLoaderState, models::EntityLoader, models::EntityLoaderSet, models::DrawableComponent, models::DrawableComponentSet, diff --git a/src/peony.cpp b/src/peony.cpp index 9ae5b35..176d6d6 100644 --- a/src/peony.cpp +++ b/src/peony.cpp @@ -1,10 +1,12 @@ #include +#include "../src_external/pstr.h" #include "types.hpp" #include "logs.hpp" #include "util.hpp" #include "renderer.hpp" #include "engine.hpp" #include "state.hpp" +#include "peony_parser.hpp" #include "intrinsics.hpp" diff --git a/src/peony_parser.cpp b/src/peony_parser.cpp index b65467b..e60f631 100644 --- a/src/peony_parser.cpp +++ b/src/peony_parser.cpp @@ -1,3 +1,4 @@ +#include "../src_external/pstr.h" #include "peony_parser.hpp" #include "logs.hpp" #include "str.hpp" @@ -5,21 +6,21 @@ namespace peony_parser { - pny_internal void print_value(PropValue value, PropValueType type) { - if (type == PropValueType::unknown) { + pny_internal void print_value(PeonyFilePropValue *value) { + if (value->type == PeonyFilePropValueType::unknown) { logs::info(""); - } else if (type == PropValueType::string) { - logs::info("%s", value.string_value); - } else if (type == PropValueType::boolean) { - logs::info("%d", value.boolean_value); - } else if (type == PropValueType::number) { - logs::info("%f", value.number_value); - } else if (type == PropValueType::vec2) { - logs::print_v2(&value.vec2_value); - } else if (type == PropValueType::vec3) { - logs::print_v3(&value.vec3_value); - } else if (type == PropValueType::vec4) { - logs::print_v4(&value.vec4_value); + } else if (value->type == PeonyFilePropValueType::string) { + logs::info("%s", value->string_value); + } else if (value->type == PeonyFilePropValueType::boolean) { + logs::info("%d", value->boolean_value); + } else if (value->type == PeonyFilePropValueType::number) { + logs::info("%f", value->number_value); + } else if (value->type == PeonyFilePropValueType::vec2) { + logs::print_v2(&value->vec2_value); + } else if (value->type == PeonyFilePropValueType::vec3) { + logs::print_v3(&value->vec3_value); + } else if (value->type == PeonyFilePropValueType::vec4) { + logs::print_v4(&value->vec4_value); } else { logs::info(""); } @@ -43,12 +44,13 @@ namespace peony_parser { target == '_' || target == '-' || target == '/' || + target == ':' || target == '.'; } pny_internal bool32 is_token_name(const char *token) { - range (0, strlen(token)) { + range (0, pstr_len(token)) { if (!is_char_allowed_in_name(token[idx])) { return false; } @@ -167,35 +169,32 @@ namespace peony_parser { pny_internal void get_value_from_token( - char *token, - FILE *f, - PropValueType *prop_value_type, - PropValue *prop_value + char *token, FILE *f, PeonyFilePropValue *prop_value ) { // NOTE: Type names the can start a value: vec2, vec3, vec4 - if (str::eq(token, "vec2")) { - *prop_value_type = PropValueType::vec2; + if (pstr_eq(token, "vec2")) { + prop_value->type = PeonyFilePropValueType::vec2; parse_vec2(token, f, &prop_value->vec2_value); - } else if (str::eq(token, "vec3")) { - *prop_value_type = PropValueType::vec3; + } else if (pstr_eq(token, "vec3")) { + prop_value->type = PeonyFilePropValueType::vec3; parse_vec3(token, f, &prop_value->vec3_value); - } else if (str::eq(token, "vec4")) { - *prop_value_type = PropValueType::vec4; + } else if (pstr_eq(token, "vec4")) { + prop_value->type = PeonyFilePropValueType::vec4; parse_vec4(token, f, &prop_value->vec4_value); - } else if (str::eq(token, "true")) { - *prop_value_type = PropValueType::boolean; + } else if (pstr_eq(token, "true")) { + prop_value->type = PeonyFilePropValueType::boolean; prop_value->boolean_value = true; - } else if (str::eq(token, "false")) { - *prop_value_type = PropValueType::boolean; + } else if (pstr_eq(token, "false")) { + prop_value->type = PeonyFilePropValueType::boolean; prop_value->boolean_value = false; - } else if (str::eq(token, "0.0") || strtod(token, nullptr) != 0.0f) { + } else if (pstr_eq(token, "0.0") || strtod(token, nullptr) != 0.0f) { // NOTE: `strtod()` returns 0.0 if parsing fails, so we need to check // if our value actually was 0.0; - *prop_value_type = PropValueType::number; + prop_value->type = PeonyFilePropValueType::number; prop_value->number_value = (real32)strtod(token, nullptr); } else { - *prop_value_type = PropValueType::string; - strcpy(prop_value->string_value, token); + prop_value->type = PeonyFilePropValueType::string; + pstr_copy(prop_value->string_value, MAX_TOKEN_LENGTH, token); } } @@ -206,15 +205,12 @@ namespace peony_parser { } - pny_internal uint32 parse_property( + pny_internal void parse_property( + PeonyFileProp *prop, char *token, - FILE *f, - char prop_name[MAX_TOKEN_LENGTH], - PropValueType prop_value_types[MAX_N_PEONY_ARRAY_VALUES], - PropValue prop_values[MAX_N_PEONY_ARRAY_VALUES] + FILE *f ) { - uint32 n_values = 0; - strcpy(prop_name, token); + pstr_copy(prop->name, MAX_TOKEN_LENGTH, token); get_non_trivial_token(token, f); assert(token[0] == TOKEN_EQUALS); get_non_trivial_token(token, f); @@ -224,459 +220,61 @@ namespace peony_parser { ); if (is_token_name(token)) { - get_value_from_token( - token, - f, - &prop_value_types[n_values], - &prop_values[n_values] - ); - n_values++; + get_value_from_token(token, f, &prop->values[prop->n_values]); + prop->n_values++; + if (prop->n_values > MAX_N_ARRAY_VALUES) { + logs::fatal("Too many array values in peony file"); + assert(false); + } } else if (token[0] == TOKEN_ARRAY_START) { while (true) { get_non_trivial_token(token, f); if (token[0] == TOKEN_ARRAY_END) { break; } - get_value_from_token( - token, - f, - &prop_value_types[n_values], - &prop_values[n_values] - ); - n_values++; - } - } - - return n_values; - } -} - - -void peony_parser::get_material_path(char *path, const char *name) { - strcpy(path, MATERIAL_FILE_DIRECTORY); - strcat(path, name); - strcat(path, MATERIAL_FILE_EXTENSION); -} - -void peony_parser::print_material_template(MaterialTemplate *material_template) { - logs::info("MaterialTemplate"); - logs::info(" name: %s", material_template->name); - logs::info(" shader_asset_vert_path: %s", material_template->shader_asset_vert_path); - logs::info(" shader_asset_frag_path: %s", material_template->shader_asset_frag_path); - logs::info(" shader_asset_geom_path: %s", material_template->shader_asset_geom_path); - logs::info( - " depth_shader_asset_vert_path: %s", - material_template->depth_shader_asset_vert_path - ); - logs::info( - " depth_shader_asset_frag_path: %s", - material_template->depth_shader_asset_frag_path - ); - logs::info( - " depth_shader_asset_geom_path: %s", - material_template->depth_shader_asset_geom_path - ); - logs::info(" albedo_static:"); - logs::print_v4(&material_template->albedo_static); - logs::info(" metallic_static: %f", material_template->metallic_static); - logs::info(" roughness_static: %f", material_template->roughness_static); - logs::info(" ao_static: %f", material_template->ao_static); - logs::info(" n_textures: %d", material_template->n_textures); - for ( - uint32 idx_texture = 0; - idx_texture < material_template->n_textures; - idx_texture++ - ) { - logs::info( - " texture %s (%s, %s)", - material_template->texture_uniform_names[idx_texture], - materials::texture_type_to_string( - material_template->texture_types[idx_texture] - ), - material_template->texture_paths[idx_texture] - ); - } - logs::info(" n_builtin_textures: %d", material_template->n_builtin_textures); - for ( - uint32 idx_texture = 0; - idx_texture < material_template->n_builtin_textures; - idx_texture++ - ) { - logs::info( - " built-in texture %s", - material_template->builtin_texture_names[idx_texture] - ); - } -} - - -void peony_parser::print_entity_template(EntityTemplate *entity_template) { - logs::info("EntityTemplate"); - logs::info(" name: %s", entity_template->entity_debug_name); - logs::info( - " model_path_or_builtin_model_name: %s", - entity_template->model_path_or_builtin_model_name - ); - logs::info(" model_source: %d", entity_template->model_source); - logs::info(" material_names.length: %d", entity_template->material_names.length); - logs::info(" material_names:"); - each (material_name, entity_template->material_names) { - logs::info(*material_name); - } - logs::info(" render_pass: %d", entity_template->render_pass); - spatial::print_spatial_component(&entity_template->spatial_component); -} - - -void peony_parser::parse_material_file( - const char *path, MaterialTemplate *material_template -) { - FILE *f = fopen(path, "r"); - - if (!f) { - logs::fatal("Could not open file %s.", path); - return; - } - - char token[MAX_TOKEN_LENGTH]; - uint32 n_values; - char prop_name[MAX_TOKEN_LENGTH]; - PropValueType prop_value_types[MAX_N_PEONY_ARRAY_VALUES]; - PropValue prop_values[MAX_N_PEONY_ARRAY_VALUES]; - - while (get_non_trivial_token(token, f)) { - if (token[0] == TOKEN_HEADER_START) { - parse_header(token, f); - strcpy(material_template->name, token); - } else if (is_token_name(token)) { - n_values = parse_property( - token, f, prop_name, prop_value_types, prop_values - ); - - if (str::eq(prop_name, "shader_asset.vert_path")) { - strcpy( - material_template->shader_asset_vert_path, - prop_values[0].string_value - ); - } else if (str::eq(prop_name, "shader_asset.frag_path")) { - strcpy( - material_template->shader_asset_frag_path, - prop_values[0].string_value - ); - } else if (str::eq(prop_name, "shader_asset.geom_path")) { - strcpy( - material_template->shader_asset_geom_path, - prop_values[0].string_value - ); - } else if (str::eq(prop_name, "depth_shader_asset.vert_path")) { - strcpy( - material_template->depth_shader_asset_vert_path, - prop_values[0].string_value - ); - } else if (str::eq(prop_name, "depth_shader_asset.frag_path")) { - strcpy( - material_template->depth_shader_asset_frag_path, - prop_values[0].string_value - ); - } else if (str::eq(prop_name, "depth_shader_asset.geom_path")) { - strcpy( - material_template->depth_shader_asset_geom_path, - prop_values[0].string_value - ); - } else if (str::eq(prop_name, "albedo_static")) { - material_template->albedo_static = prop_values[0].vec4_value; - } else if (str::eq(prop_name, "metallic_static")) { - material_template->metallic_static = - prop_values[0].number_value; - } else if (str::eq(prop_name, "roughness_static")) { - material_template->roughness_static = - prop_values[0].number_value; - } else if (str::eq(prop_name, "ao_static")) { - material_template->ao_static = - prop_values[0].number_value; - } else if ( - strncmp(prop_name, TEXTURE_PREFIX, TEXTURE_PREFIX_LENGTH) == 0 - ) { - uint32 idx_texture = material_template->n_textures; - strcpy( - material_template->texture_uniform_names[idx_texture], - prop_name + TEXTURE_PREFIX_LENGTH - ); - material_template->texture_types[idx_texture] = - materials::texture_type_from_string(prop_values[0].string_value); - strcpy( - material_template->texture_paths[idx_texture], - prop_values[1].string_value - ); - material_template->n_textures++; - } else if ( - strncmp( - prop_name, BUILTIN_TEXTURE_PREFIX, BUILTIN_TEXTURE_PREFIX_LENGTH - ) == 0 - ) { - uint32 idx_texture = material_template->n_builtin_textures; - strcpy( - material_template->builtin_texture_names[idx_texture], - prop_name + BUILTIN_TEXTURE_PREFIX_LENGTH - ); - material_template->n_builtin_textures++; - } else { - logs::info("Unhandled prop_name %s with values:", prop_name); - range_named (idx_value, 0, n_values) { - print_value(prop_values[idx_value], prop_value_types[idx_value]); - } + get_value_from_token(token, f, &prop->values[prop->n_values]); + prop->n_values++; } - } else { - logs::info("Unhandled token: %s", token); } } - - fclose(f); } -bool32 peony_parser::parse_scene_file( - const char *path, - StackArray *entity_templates, - uint32 *n_entities -) { - *n_entities = 0; - int32 idx_entity = -1; +bool32 peony_parser::parse_file(PeonyFile *pf, char const *path) { + int32 idx_entry = -1; + PeonyFileEntry *entry = nullptr; FILE *f = fopen(path, "r"); - if (!f) { logs::error("Could not open file %s.", path); return false; } + defer { fclose(f); }; - EntityTemplate *entity_template = nullptr; char token[MAX_TOKEN_LENGTH]; - uint32 n_values; - char prop_name[MAX_TOKEN_LENGTH]; - PropValueType prop_value_types[MAX_N_PEONY_ARRAY_VALUES]; - PropValue prop_values[MAX_N_PEONY_ARRAY_VALUES]; while (get_non_trivial_token(token, f)) { if (token[0] == TOKEN_HEADER_START) { - idx_entity++; - entity_template = entity_templates->push(); - *entity_template = {}; + idx_entry++; + entry = &pf->entries[idx_entry]; parse_header(token, f); - strcpy( - entity_template->entity_debug_name, - token - ); + pstr_copy(entry->name, MAX_TOKEN_LENGTH, token); } else if (is_token_name(token)) { - if (entity_template == nullptr) { + if (!entry) { logs::fatal("Tried to parse file, but encountered data before header."); - assert(false); // A little hint for the compiler } - - n_values = parse_property( - token, f, prop_name, prop_value_types, prop_values - ); - - if (str::eq(prop_name, "model_path")) { - strcpy( - entity_template->model_path_or_builtin_model_name, - prop_values[0].string_value - ); - entity_template->model_source = ModelSource::file; - } else if (str::eq(prop_name, "builtin_model_name")) { - strcpy( - entity_template->model_path_or_builtin_model_name, - prop_values[0].string_value - ); - entity_template->model_source = ModelSource::data; - } else if (str::eq(prop_name, "materials")) { - range_named (idx_value, 0, n_values) { - strcpy( - *(entity_template->material_names.push()), - prop_values[idx_value].string_value - ); - } - } else if (str::eq(prop_name, "render_passes")) { - RenderPass render_pass = RenderPass::none; - range_named (idx_value, 0, n_values) { - render_pass = (RenderPass)( - (uint32)render_pass | - (uint32)models::render_pass_from_string( - prop_values[idx_value].string_value - ) - ); - } - entity_template->render_pass = render_pass; - } else if (str::eq(prop_name, "physics_component.obb.center")) { - entity_template->physics_component.obb.center = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "physics_component.obb.x_axis")) { - entity_template->physics_component.obb.x_axis = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "physics_component.obb.y_axis")) { - entity_template->physics_component.obb.y_axis = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "physics_component.obb.extents")) { - entity_template->physics_component.obb.extents = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "spatial_component.position")) { - entity_template->spatial_component.position = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "spatial_component.rotation")) { - entity_template->spatial_component.rotation = - glm::angleAxis( - radians(prop_values[0].vec4_value[0]), - v3( - prop_values[0].vec4_value[1], - prop_values[0].vec4_value[2], - prop_values[0].vec4_value[3] - ) - ); - } else if (str::eq(prop_name, "spatial_component.scale")) { - entity_template->spatial_component.scale = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "light_component.type")) { - entity_template->light_component.type = - lights::light_type_from_string(prop_values[0].string_value); - } else if (str::eq(prop_name, "light_component.direction")) { - entity_template->light_component.direction = prop_values[0].vec3_value; - } else if (str::eq(prop_name, "light_component.color")) { - entity_template->light_component.color = prop_values[0].vec4_value; - } else if (str::eq(prop_name, "light_component.attenuation")) { - entity_template->light_component.attenuation = prop_values[0].vec4_value; - } else if (str::eq(prop_name, "behavior_component.behavior")) { - entity_template->behavior_component.behavior = - behavior::behavior_from_string(prop_values[0].string_value); - } else { - logs::info("Unhandled prop_name %s with values:", prop_name); - range_named (idx_value, 0, n_values) { - print_value(prop_values[idx_value], prop_value_types[idx_value]); - } + PeonyFileProp *prop = &entry->props[entry->n_props]; + parse_property(prop, token, f); + entry->n_props++; + if (entry->n_props > MAX_N_ENTRY_PROPS) { + logs::fatal("Too many props in peony file"); + assert(false); } } else { logs::info("Unhandled token: %s", token); } } - fclose(f); - - *n_entities = idx_entity + 1; + pf->n_entries = idx_entry + 1; return true; } - - -void peony_parser::create_material_from_template( - Material *material, - MaterialTemplate *material_template, - BuiltinTextures *builtin_textures, - MemoryPool *memory_pool -) { - init_material(material, material_template->name); - - material->albedo_static = material_template->albedo_static; - material->metallic_static = material_template->metallic_static; - material->roughness_static = material_template->roughness_static; - material->ao_static = material_template->ao_static; - - if (!str::is_empty(material_template->shader_asset_vert_path)) { - shaders::init_shader_asset( - &material->shader_asset, - memory_pool, - material_template->name, - ShaderType::standard, - material_template->shader_asset_vert_path, - material_template->shader_asset_frag_path, - material_template->shader_asset_geom_path - ); - } - if (!str::is_empty(material_template->depth_shader_asset_vert_path)) { - shaders::init_shader_asset( - &material->depth_shader_asset, - memory_pool, - material_template->name, - ShaderType::depth, - material_template->depth_shader_asset_vert_path, - material_template->depth_shader_asset_frag_path, - material_template->depth_shader_asset_geom_path - ); - } - - for (uint32 idx = 0; idx < material_template->n_textures; idx++) { - Texture texture; - init_texture( - &texture, - material_template->texture_types[idx], - material_template->texture_paths[idx] - ); - add_texture_to_material( - material, - texture, - material_template->texture_uniform_names[idx] - ); - } - - for (uint32 idx = 0; idx < material_template->n_builtin_textures; idx++) { - const char *builtin_texture_name = - material_template->builtin_texture_names[idx]; - if (strcmp(builtin_texture_name, "g_position_texture") == 0) { - add_texture_to_material( - material, *builtin_textures->g_position_texture, builtin_texture_name - ); - } else if (strcmp(builtin_texture_name, "g_albedo_texture") == 0) { - add_texture_to_material( - material, *builtin_textures->g_albedo_texture, builtin_texture_name - ); - } else if (strcmp(builtin_texture_name, "shadowmaps_3d") == 0) { - add_texture_to_material( - material, *builtin_textures->shadowmaps_3d_texture, builtin_texture_name - ); - } else if (strcmp(builtin_texture_name, "shadowmaps_2d") == 0) { - add_texture_to_material( - material, *builtin_textures->shadowmaps_2d_texture, builtin_texture_name - ); - } else { - logs::fatal( - "Attempted to use unsupported built-in texture %s", - builtin_texture_name - ); - } - } -} - - -void peony_parser::create_model_loader_from_entity_template( - EntityTemplate *entity_template, - EntityHandle entity_handle, - Array *model_loaders -) { - ModelLoader *model_loader = model_loaders->push(); - - models::init_model_loader( - model_loader, - entity_template->model_source, - entity_template->model_path_or_builtin_model_name - ); - - assert( - sizeof(model_loader->material_names) == sizeof(entity_template->material_names) - ); - memcpy( - &model_loader->material_names, - &entity_template->material_names, - sizeof(entity_template->material_names) - ); -} - - -void peony_parser::create_entity_loader_from_entity_template( - EntityTemplate *entity_template, - EntityHandle entity_handle, - EntityLoaderSet *entity_loader_set -) { - EntityLoader *entity_loader = entity_loader_set->loaders[entity_handle]; - models::init_entity_loader( - entity_loader, - entity_template->entity_debug_name, - entity_template->model_path_or_builtin_model_name, - entity_template->render_pass, - entity_handle - ); - entity_loader->spatial_component = entity_template->spatial_component; - entity_loader->light_component = entity_template->light_component; - entity_loader->behavior_component = entity_template->behavior_component; - entity_loader->physics_component = entity_template->physics_component; -} diff --git a/src/peony_parser.hpp b/src/peony_parser.hpp index 5a91bf0..76d1331 100644 --- a/src/peony_parser.hpp +++ b/src/peony_parser.hpp @@ -1,12 +1,12 @@ #pragma once #include "types.hpp" -#include "constants.hpp" -#include "models.hpp" -#include "materials.hpp" namespace peony_parser { constexpr uint32 MAX_N_FILE_ENTRIES = 128; + constexpr uint32 MAX_N_ENTRY_PROPS = 32; + constexpr uint32 MAX_N_ARRAY_VALUES = 8; + constexpr uint32 MAX_TOKEN_LENGTH = 128; constexpr const char TOKEN_SPACE = ' '; constexpr const char TOKEN_NEWLINE = '\n'; @@ -21,87 +21,43 @@ namespace peony_parser { constexpr const char TOKEN_ELEMENT_SEPARATOR = ','; constexpr const char TOKEN_COMMENT_START = ';'; - constexpr const char *TEXTURE_PREFIX = "textures."; - constexpr size_t TEXTURE_PREFIX_LENGTH = 9; - constexpr const char *BUILTIN_TEXTURE_PREFIX = "builtin_textures."; - constexpr size_t BUILTIN_TEXTURE_PREFIX_LENGTH = 17; - - struct MaterialTemplate { - char name[MAX_TOKEN_LENGTH]; - char shader_asset_vert_path[MAX_TOKEN_LENGTH]; - char shader_asset_frag_path[MAX_TOKEN_LENGTH]; - char shader_asset_geom_path[MAX_TOKEN_LENGTH]; - char depth_shader_asset_vert_path[MAX_TOKEN_LENGTH]; - char depth_shader_asset_frag_path[MAX_TOKEN_LENGTH]; - char depth_shader_asset_geom_path[MAX_TOKEN_LENGTH]; - - v4 albedo_static = v4(-1.0f, -1.0f, -1.0f, -1.0f); - real32 metallic_static = -1.0f; - real32 roughness_static = -1.0f; - real32 ao_static = -1.0f; - - uint32 n_textures; - char texture_uniform_names[MAX_N_PEONY_ARRAY_VALUES][MAX_TOKEN_LENGTH]; - TextureType texture_types[MAX_N_PEONY_ARRAY_VALUES]; - char texture_paths[MAX_N_PEONY_ARRAY_VALUES][MAX_TOKEN_LENGTH]; + enum class PeonyFilePropValueType { + unknown, string, boolean, number, vec2, vec3, vec4 + }; - uint32 n_builtin_textures; - char builtin_texture_names[MAX_N_PEONY_ARRAY_VALUES][MAX_TOKEN_LENGTH]; + struct PeonyFilePropValue { + PeonyFilePropValueType type; + union { + char string_value[MAX_TOKEN_LENGTH]; + bool32 boolean_value; + real32 number_value; + v2 vec2_value; + v3 vec3_value; + v4 vec4_value; + }; }; - struct EntityTemplate { - char entity_debug_name[MAX_TOKEN_LENGTH]; - char model_path_or_builtin_model_name[MAX_TOKEN_LENGTH]; - ModelSource model_source; - StackArray material_names; - RenderPass render_pass; - // NOTE: The `entity_handle` and `parent_entity_handle` properties - // must be filled in later! - SpatialComponent spatial_component; - LightComponent light_component; - BehaviorComponent behavior_component; - PhysicsComponent physics_component; + struct PeonyFileProp { + char name[MAX_TOKEN_LENGTH]; + PeonyFilePropValue values[MAX_N_ARRAY_VALUES]; + uint32 n_values; }; - enum class PropValueType {unknown, string, boolean, number, vec2, vec3, vec4}; + struct PeonyFileEntry { + char name[MAX_TOKEN_LENGTH]; + PeonyFileProp props[MAX_N_ENTRY_PROPS]; + uint32 n_props; + }; - union PropValue { - char string_value[MAX_TOKEN_LENGTH]; - bool32 boolean_value; - real32 number_value; - v2 vec2_value; - v3 vec3_value; - v4 vec4_value; + struct PeonyFile { + PeonyFileEntry entries[MAX_N_FILE_ENTRIES]; + uint32 n_entries; }; - void get_material_path(char *path, const char *name); - void print_material_template(MaterialTemplate *material_template); - void print_entity_template(EntityTemplate *entity_template); - void parse_material_file( - const char *path, MaterialTemplate *material_template - ); - bool32 parse_scene_file( - const char *path, - StackArray *entity_templates, - uint32 *n_entities - ); - void create_material_from_template( - Material *material, - MaterialTemplate *material_template, - BuiltinTextures *builtin_textures, - MemoryPool *memory_pool - ); - void create_model_loader_from_entity_template( - EntityTemplate *entity_template, - EntityHandle entity_handle, - Array *model_loaders - ); - void create_entity_loader_from_entity_template( - EntityTemplate *entity_template, - EntityHandle entity_handle, - EntityLoaderSet *entity_loader_set - ); + bool32 parse_file(PeonyFile *pf, char const *path); } -using peony_parser::MaterialTemplate, peony_parser::EntityTemplate, - peony_parser::PropValueType, peony_parser::PropValue; +using peony_parser::PeonyFileEntry, + peony_parser::PeonyFileProp, + peony_parser::PeonyFilePropValue, + peony_parser::PeonyFile; diff --git a/src/peony_parser_utils.cpp b/src/peony_parser_utils.cpp new file mode 100644 index 0000000..db9d9a6 --- /dev/null +++ b/src/peony_parser_utils.cpp @@ -0,0 +1,291 @@ +#include "../src_external/pstr.h" +#include "peony_parser_utils.hpp" +#include "logs.hpp" +#include "constants.hpp" +#include "intrinsics.hpp" + + +char* peony_parser_utils::get_string(PeonyFileProp *prop) { + if (!prop) { return nullptr; } + return prop->values[0].string_value; +} + + +bool32* peony_parser_utils::get_boolean(PeonyFileProp *prop) { + if (!prop) { return nullptr; } + return &prop->values[0].boolean_value; +} + + +real32* peony_parser_utils::get_number(PeonyFileProp *prop) { + if (!prop) { return nullptr; } + return &prop->values[0].number_value; +} + + +v2* peony_parser_utils::get_vec2(PeonyFileProp *prop) { + if (!prop) { return nullptr; } + return &prop->values[0].vec2_value; +} + + +v3* peony_parser_utils::get_vec3(PeonyFileProp *prop) { + if (!prop) { return nullptr; } + return &prop->values[0].vec3_value; +} + + +v4* peony_parser_utils::get_vec4(PeonyFileProp *prop) { + if (!prop) { return nullptr; } + return &prop->values[0].vec4_value; +} + + +PeonyFileProp* peony_parser_utils::find_prop(PeonyFileEntry *entry, char const *name) { + range (0, entry->n_props) { + if (pstr_eq(name, entry->props[idx].name)) { + return &entry->props[idx]; + } + } + logs::warning("Could not find prop %s", name); + return nullptr; +} + + +void peony_parser_utils::get_unique_string_values_for_prop_name( + PeonyFile *pf, + Array *unique_values, + char const *prop_name +) { + uint32 n_unique_values = 0; + range_named (idx_entry, 0, pf->n_entries) { + PeonyFileEntry *entry = &pf->entries[idx_entry]; + PeonyFileProp *prop = find_prop(entry, prop_name); + if (!prop) { + continue; + } + range_named (idx_value, 0, prop->n_values) { + PeonyFilePropValue *value = &prop->values[idx_value]; + bool32 does_material_already_exist = false; + range_named (idx_used_material, 0, n_unique_values) { + if (pstr_eq(value->string_value, (*(*unique_values)[idx_used_material]))) { + does_material_already_exist = true; + break; + } + } + if (!does_material_already_exist) { + pstr_copy( + *(unique_values->push()), + MAX_COMMON_NAME_LENGTH, + value->string_value + ); + } + } + } +} + + +void peony_parser_utils::create_material_from_peony_file_entry( + Material *material, + PeonyFileEntry *entry, + BuiltinTextures *builtin_textures, + MemoryPool *memory_pool +) { + materials::init_material(material, entry->name); + + // We're calling `find_prop()` a lot here, which goes through the full + // list of props every time, and so this is kind of #slow. Not a huge deal, but + // good to keep in mind. + PeonyFileProp *prop; + + if ((prop = find_prop(entry, "albedo_static"))) { + material->albedo_static = *get_vec4(prop); + } + if ((prop = find_prop(entry, "metallic_static"))) { + material->metallic_static = *get_number(prop); + } + if ((prop = find_prop(entry, "roughness_static"))) { + material->roughness_static = *get_number(prop); + } + if ((prop = find_prop(entry, "ao_static"))) { + material->ao_static = *get_number(prop); + } + + if ((prop = find_prop(entry, "shader_asset.vert_path"))) { + if (!pstr_is_empty(get_string(prop))) { + shaders::init_shader_asset( + &material->shader_asset, + memory_pool, + entry->name, + ShaderType::standard, + get_string(find_prop(entry, "shader_asset.vert_path")), + get_string(find_prop(entry, "shader_asset.frag_path")), + get_string(find_prop(entry, "shader_asset.geom_path")) + ); + } + } + + if ((prop = find_prop(entry, "depth_shader_asset.vert_path"))) { + if (!pstr_is_empty(get_string(prop))) { + shaders::init_shader_asset( + &material->depth_shader_asset, + memory_pool, + entry->name, + ShaderType::depth, + get_string(find_prop(entry, "depth_shader_asset.vert_path")), + get_string(find_prop(entry, "depth_shader_asset.frag_path")), + get_string(find_prop(entry, "depth_shader_asset.geom_path")) + ); + } + } + + // Iterate through all props to get textures, since those could have any name + range (0, entry->n_props) { + PeonyFileProp *prop = &entry->props[idx]; + + if (pstr_starts_with(prop->name, TEXTURE_PREFIX)) { + // Handle a texture + Texture texture; + // The uniform name is the prop name without the prefix + // The first value is the type, and the second the path + // e.g. textures.foam_texture = [other, water_foam.png] + char const *texture_name = &prop->name[TEXTURE_PREFIX_LENGTH]; + init_texture( + &texture, + materials::texture_type_from_string(prop->values[0].string_value), + prop->values[1].string_value + ); + materials::add_texture_to_material( + material, + texture, + texture_name + ); + } else if (pstr_starts_with(prop->name, BUILTIN_TEXTURE_PREFIX)) { + // Handle a builtin texture + char const *builtin_texture_name = &prop->name[BUILTIN_TEXTURE_PREFIX_LENGTH]; + if (pstr_eq(builtin_texture_name, "g_position_texture")) { + materials::add_texture_to_material( + material, *builtin_textures->g_position_texture, builtin_texture_name + ); + } else if (pstr_eq(builtin_texture_name, "g_albedo_texture")) { + materials::add_texture_to_material( + material, *builtin_textures->g_albedo_texture, builtin_texture_name + ); + } else if (pstr_eq(builtin_texture_name, "shadowmaps_3d")) { + materials::add_texture_to_material( + material, *builtin_textures->shadowmaps_3d_texture, builtin_texture_name + ); + } else if (pstr_eq(builtin_texture_name, "shadowmaps_2d")) { + materials::add_texture_to_material( + material, *builtin_textures->shadowmaps_2d_texture, builtin_texture_name + ); + } else { + logs::fatal( + "Attempted to use unsupported built-in texture %s", + builtin_texture_name + ); + } + } + } +} + + +void peony_parser_utils::create_model_loader_from_peony_file_entry( + PeonyFileEntry *entry, + EntityHandle entity_handle, + ModelLoader *model_loader +) { + PeonyFileProp *model_path_prop = find_prop(entry, "model_path"); + assert(model_path_prop); + char const *model_path = get_string(model_path_prop); + + models::init_model_loader(model_loader, model_path); + + PeonyFileProp *materials_prop = find_prop(entry, "materials"); + model_loader->n_material_names = materials_prop->n_values; + range (0, materials_prop->n_values) { + pstr_copy( + model_loader->material_names[idx], + MAX_COMMON_NAME_LENGTH, + materials_prop->values[idx].string_value + ); + } +} + + +void peony_parser_utils::create_entity_loader_from_peony_file_entry( + PeonyFileEntry *entry, + EntityHandle entity_handle, + EntityLoader *entity_loader +) { + PeonyFileProp *model_path_prop = find_prop(entry, "model_path"); + assert(model_path_prop); + char const *model_path = get_string(model_path_prop); + + // Get render pass + RenderPass render_pass = RenderPass::none; + PeonyFileProp *render_passes_prop = find_prop(entry, "render_passes"); + if (render_passes_prop) { + range (0, render_passes_prop->n_values) { + render_pass = (RenderPass)( + (uint32)render_pass | + (uint32)models::render_pass_from_string( + render_passes_prop->values[idx].string_value + ) + ); + } + } else { + logs::warning( + "Loading EntityLoader with no RenderPasses, you probably don't want this?" + ); + } + + // Initialise everything except the components + models::init_entity_loader( + entity_loader, + entry->name, + model_path, + render_pass, + entity_handle + ); + + // Build PhysicsComponent, SpatialComponent, LightComponent, BehaviorComponent + range (0, entry->n_props) { + PeonyFileProp *prop = &entry->props[idx]; + if (pstr_eq(prop->name, "physics_component.obb.center")) { + entity_loader->physics_component.obb.center = *get_vec3(prop); + } else if (pstr_eq(prop->name, "physics_component.obb.x_axis")) { + entity_loader->physics_component.obb.x_axis = *get_vec3(prop); + } else if (pstr_eq(prop->name, "physics_component.obb.y_axis")) { + entity_loader->physics_component.obb.y_axis = *get_vec3(prop); + } else if (pstr_eq(prop->name, "physics_component.obb.extents")) { + entity_loader->physics_component.obb.extents = *get_vec3(prop); + } else if (pstr_eq(prop->name, "spatial_component.position")) { + entity_loader->spatial_component.position = *get_vec3(prop); + } else if (pstr_eq(prop->name, "spatial_component.rotation")) { + entity_loader->spatial_component.rotation = + glm::angleAxis( + radians((*get_vec4(prop))[0]), + v3( + (*get_vec4(prop))[1], + (*get_vec4(prop))[2], + (*get_vec4(prop))[3] + ) + ); + } else if (pstr_eq(prop->name, "spatial_component.scale")) { + entity_loader->spatial_component.scale = *get_vec3(prop); + } else if (pstr_eq(prop->name, "light_component.type")) { + entity_loader->light_component.type = + lights::light_type_from_string(get_string(prop)); + } else if (pstr_eq(prop->name, "light_component.direction")) { + entity_loader->light_component.direction = *get_vec3(prop); + } else if (pstr_eq(prop->name, "light_component.color")) { + entity_loader->light_component.color = *get_vec4(prop); + } else if (pstr_eq(prop->name, "light_component.attenuation")) { + entity_loader->light_component.attenuation = *get_vec4(prop); + } else if (pstr_eq(prop->name, "behavior_component.behavior")) { + entity_loader->behavior_component.behavior = + behavior::behavior_from_string(get_string(prop)); + } + } +} diff --git a/src/peony_parser_utils.hpp b/src/peony_parser_utils.hpp new file mode 100644 index 0000000..0632367 --- /dev/null +++ b/src/peony_parser_utils.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "array.hpp" +#include "peony_parser.hpp" +#include "models.hpp" +#include "materials.hpp" + +namespace peony_parser_utils { + constexpr const char *TEXTURE_PREFIX = "textures."; + constexpr size_t TEXTURE_PREFIX_LENGTH = 9; + constexpr const char *BUILTIN_TEXTURE_PREFIX = "builtin_textures."; + constexpr size_t BUILTIN_TEXTURE_PREFIX_LENGTH = 17; + + char* get_string(PeonyFileProp *prop); + bool32* get_boolean(PeonyFileProp *prop); + real32* get_number(PeonyFileProp *prop); + v2* get_vec2(PeonyFileProp *prop); + v3* get_vec3(PeonyFileProp *prop); + v4* get_vec4(PeonyFileProp *prop); + PeonyFileProp* find_prop(PeonyFileEntry *entry, char const *name); + void get_unique_string_values_for_prop_name( + PeonyFile *pf, + Array *unique_values, + char const *prop_name + ); + void create_material_from_peony_file_entry( + Material *material, + PeonyFileEntry *entry, + BuiltinTextures *builtin_textures, + MemoryPool *memory_pool + ); + void create_model_loader_from_peony_file_entry( + PeonyFileEntry *entry, + EntityHandle entity_handle, + ModelLoader *model_loader + ); + void create_entity_loader_from_peony_file_entry( + PeonyFileEntry *entry, + EntityHandle entity_handle, + EntityLoader *entity_loader + ); +} diff --git a/src/shaders.cpp b/src/shaders.cpp index cf528eb..0bf3a77 100644 --- a/src/shaders.cpp +++ b/src/shaders.cpp @@ -1,3 +1,4 @@ +#include "../src_external/pstr.h" #include "memory.hpp" #include "logs.hpp" #include "files.hpp" @@ -350,15 +351,27 @@ ShaderAsset* shaders::init_shader_asset( const char *vert_path, const char *frag_path, const char *geom_path ) { *shader_asset = {}; - strcpy(shader_asset->name, new_name); + pstr_copy(shader_asset->name, MAX_DEBUG_NAME_LENGTH, new_name); shader_asset->type = new_type; shader_asset->n_texture_units = 0; shader_asset->did_set_texture_uniforms = false; memset(shader_asset->texture_units, 0, sizeof(shader_asset->texture_units)); memset(shader_asset->texture_unit_types, 0, sizeof(shader_asset->texture_unit_types)); - strcpy(shader_asset->vert_path, vert_path); - strcpy(shader_asset->frag_path, frag_path); - strcpy(shader_asset->geom_path, geom_path); + if (!vert_path) { + logs::warning("Loading shader asset with no vertex shader"); + } + if (!frag_path) { + logs::warning("Loading shader asset with no fragment shader"); + } + if (vert_path) { + pstr_copy(shader_asset->vert_path, MAX_PATH, vert_path); + } + if (frag_path) { + pstr_copy(shader_asset->frag_path, MAX_PATH, frag_path); + } + if (geom_path) { + pstr_copy(shader_asset->geom_path, MAX_PATH, geom_path); + } load_shader_asset(shader_asset, memory_pool); return shader_asset; } diff --git a/src/state.hpp b/src/state.hpp index 70fe6ee..35b7b71 100644 --- a/src/state.hpp +++ b/src/state.hpp @@ -86,7 +86,7 @@ namespace state { Camera camera_main; Camera *camera_active; InputState input_state; - char current_scene_name[MAX_TOKEN_LENGTH]; + char current_scene_name[MAX_COMMON_NAME_LENGTH]; // NOTE: `t` and `dt` will not change when gameplay is paused. real64 t; // us -- 2.51.2