diff --git a/assets/entities/Suzanne.symtres b/assets/entities/Suzanne.symtres old mode 100644 new mode 100755 index e4419a3..344a9e5 --- a/assets/entities/Suzanne.symtres +++ b/assets/entities/Suzanne.symtres @@ -2,8 +2,13 @@ Entity { type : 6 material : 0 + diffuse_color : 1.000 0.000 1.000 1.000 geometry : suzanne.symbres + specular : 1.0000 active : true - name : Suzanne_0 + diffuse_texture : white.tga + diffuse : 0.5000 + specular_strength : 1.0000 + name : Suzanne_Saved } diff --git a/assets/entities/default.symtres b/assets/entities/default.symtres new file mode 100755 index 0000000..40e7c2b --- /dev/null +++ b/assets/entities/default.symtres @@ -0,0 +1,14 @@ +Entity +{ + type : 6 + material : 0 + diffuse_color : 1.000 0.000 1.000 1.000 + geometry : suzanne.symbres + specular : 1.0000 + active : true + diffuse_texture : default.tga + diffuse : 1.0000 + specular_strength : 1.0000 + name : Suzanne_Default +} + diff --git a/src/common/array.h b/src/common/array.h index 77da38f..dc5acf3 100755 --- a/src/common/array.h +++ b/src/common/array.h @@ -20,7 +20,7 @@ int array_copy_(void* arr_src, void** arr_dest); #define array_grow(array, type) (type*) array_grow_((void**)&array) #define array_push(array, value, type) {type* new_val = array_grow(array, type); \ *new_val = value;} -#define array_get_last(array, type) (type*) (&array[array_len(array)]) +#define array_get_last(array, type) (type*) (&array[array_len(array) - 1]) #define array_set_last(array, val, type) {type* last = array_get_last(array, type); \ *last = val} #define array_pop(array) array_pop_((void**)&array) diff --git a/src/game/console.c b/src/game/console.c index 4689812..aea88f4 100755 --- a/src/game/console.c +++ b/src/game/console.c @@ -15,6 +15,7 @@ static struct nk_color console_message_color[CMT_MAX]; static int console_filter(const struct nk_text_edit *box, nk_rune unicode); +static void console_command_scene_empty(struct Console* console, const char* command); static void console_command_scene_save(struct Console* console, const char* command); static void console_command_scene_load(struct Console* console, const char* command); static void console_command_entity_save(struct Console* console, const char* command); @@ -45,6 +46,7 @@ void console_init(struct Console* console) } console->console_commands = hashmap_new(); + hashmap_ptr_set(console->console_commands, "scene_empty", &console_command_scene_empty); hashmap_ptr_set(console->console_commands, "scene_save", &console_command_scene_save); hashmap_ptr_set(console->console_commands, "scene_load", &console_command_scene_load); hashmap_ptr_set(console->console_commands, "entity_save", &console_command_entity_save); @@ -266,3 +268,14 @@ void console_command_scene_load(struct Console* console, const char* command) if(!scene_load(game_state_get()->scene, full_filename, DIRT_INSTALL)) log_error("scene_load", "Command failed"); } + +void console_command_scene_empty(struct Console* console, const char* command) +{ + char filename[MAX_FILENAME_LEN]; + memset(filename, '\0', MAX_FILENAME_LEN); + + struct Scene* scene = game_state_get()->scene; + scene_destroy(scene); + scene_post_update(scene); + scene_init(scene); +} diff --git a/src/game/editor.c b/src/game/editor.c index a9219a7..55046e9 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -174,9 +174,12 @@ void editor_init_camera(struct Editor* editor, struct Hashmap* cvars) editor_camera->clear_color.z = 0.9f; editor_camera->clear_color.w = 1.f; - int render_width = hashmap_int_get(cvars, "render_width"); - int render_height = hashmap_int_get(cvars, "render_height"); - camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); + if(editor_camera->fbo == -1) + { + int render_width = hashmap_int_get(cvars, "render_width"); + int render_height = hashmap_int_get(cvars, "render_height"); + camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); + } vec3 cam_pos = {5.f, 20.f, 50.f}; transform_translate(editor_camera, &cam_pos, TS_WORLD); @@ -1328,10 +1331,10 @@ void editor_camera_update(struct Editor* editor, float dt) { struct Game_State* game_state = game_state_get(); struct Gui* gui = game_state->gui; - if(game_state->console->visible) + if(game_state->console->visible || nk_item_is_any_active(&gui->context)) return; - struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; + struct Camera* editor_camera = &game_state->scene->cameras[CAM_EDITOR]; static float total_up_down_rot = 0.f; float move_speed = editor->camera_move_speed, turn_speed = editor->camera_turn_speed; float turn_up_down = 0.f; @@ -1347,7 +1350,7 @@ void editor_camera_update(struct Editor* editor, float dt) if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed; if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed; - if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED) && !nk_item_is_any_active(&game_state_get()->gui->context)) + if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED) && !nk_item_is_any_active(&gui->context)) { const float scale = 0.5f; int cursor_lr, cursor_ud; @@ -1488,10 +1491,16 @@ void editor_widget_color_combov4(struct nk_context* context, vec4* color, int wi void editor_cleanup(struct Editor* editor) { - event_manager_unsubscribe(game_state_get()->event_manager, EVT_MOUSEBUTTON_PRESSED, &editor_on_mousebutton_press); - event_manager_unsubscribe(game_state_get()->event_manager, EVT_MOUSEBUTTON_RELEASED, &editor_on_mousebutton_release); + struct Event_Manager* event_manager = game_state_get()->event_manager; + event_manager_unsubscribe(event_manager, EVT_MOUSEBUTTON_PRESSED, &editor_on_mousebutton_press); + event_manager_unsubscribe(event_manager, EVT_MOUSEBUTTON_RELEASED, &editor_on_mousebutton_release); + event_manager_unsubscribe(event_manager, EVT_MOUSEMOTION, &editor_on_mousemotion); + event_manager_unsubscribe(event_manager, EVT_KEY_PRESSED, &editor_on_key_press); + event_manager_unsubscribe(event_manager, EVT_KEY_RELEASED, &editor_on_key_release); + for(int i = 0; i < array_len(debug_vars_list); i++) - editor_debugvar_slot_remove(i); + editor_debugvar_slot_remove(i); + array_free(debug_vars_list); array_free(empty_indices); } diff --git a/src/game/entity.c b/src/game/entity.c index 4d92b9c..f6facea 100755 --- a/src/game/entity.c +++ b/src/game/entity.c @@ -506,7 +506,14 @@ struct Entity* entity_load(const char* filename, int directory_type) if(new_entity) { if(i == 0) + { + new_entity->archetype_index = scene_entity_archetype_add(game_state_get()->scene, filename); parent_entity = new_entity; + } + // We don't want this entity to be saved when we're saving the scene because + // this entity and its parent will be loaded from this same file next time the scene is loaded + if(i != 0) + new_entity->flags |= EF_TRANSIENT; num_entites_loaded++; log_message("Entity %s loaded from %s", new_entity->name, filename); } diff --git a/src/game/framebuffer.c b/src/game/framebuffer.c index f61f5d4..3441e44 100755 --- a/src/game/framebuffer.c +++ b/src/game/framebuffer.c @@ -95,6 +95,7 @@ int framebuffer_create(int width, int height, bool has_depth, bool has_color, bo { index = *array_get_last(empty_indices, int); array_pop(empty_indices); + framebuffer = &fbo_list[index]; } framebuffer->handle = fbo; diff --git a/src/game/game.c b/src/game/game.c index 41204be..c25ab37 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -102,10 +102,10 @@ bool game_init(struct Window* window, struct Hashmap* cvars) gui_init(game_state->gui); console_init(game_state->console); geom_init(); - physics_init(); - physics_gravity_set(0.f, -9.8f, 0.f); - physics_body_set_moved_callback(entity_rigidbody_on_move); - physics_body_set_collision_callback(entity_rigidbody_on_collision); + //physics_init(); + //physics_gravity_set(0.f, -9.8f, 0.f); + //physics_body_set_moved_callback(entity_rigidbody_on_move); + //physics_body_set_collision_callback(entity_rigidbody_on_collision); sound_init(game_state->sound); renderer_init(game_state->renderer); @@ -115,6 +115,7 @@ bool game_init(struct Window* window, struct Hashmap* cvars) /* Debug scene setup */ //game_scene_setup(); + scene_load(game_state->scene, "scenes/default.symtres", DIRT_INSTALL); game_state->is_initialized = true; return game_state->is_initialized; } @@ -557,7 +558,7 @@ void game_update(float dt, bool* window_should_close) scene_update(game_state->scene, dt); if(game_state->game_mode == GAME_MODE_GAME) { - physics_step(dt); + //physics_step(dt); } else if(game_state->game_mode == GAME_MODE_EDITOR) { @@ -1912,7 +1913,7 @@ void game_cleanup(void) texture_cleanup(); shader_cleanup(); sound_cleanup(game_state->sound); - physics_cleanup(); + //physics_cleanup(); event_manager_cleanup(game_state->event_manager); free(game_state->editor); diff --git a/src/game/player.c b/src/game/player.c index 9761930..f6dce16 100755 --- a/src/game/player.c +++ b/src/game/player.c @@ -40,9 +40,13 @@ void player_init(struct Player* player, struct Scene* scene) player->camera_node->base.flags |= EF_TRANSIENT; player->mesh->base.flags |= EF_TRANSIENT; - int render_width = hashmap_int_get(config, "render_width"); - int render_height = hashmap_int_get(config, "render_height"); - camera_attach_fbo(player_camera, render_width, render_height, true, true, true); + if(player_camera->fbo == -1) + { + int render_width = hashmap_int_get(config, "render_width"); + int render_height = hashmap_int_get(config, "render_height"); + camera_attach_fbo(player_camera, render_width, render_height, true, true, true); + } + transform_parent_set(player_camera, player, true); vec3 cam_translation = {0.f, 20.f, 2.f}; @@ -58,6 +62,7 @@ void player_init(struct Player* player, struct Scene* scene) void player_destroy(struct Player* player) { entity_reset(player, player->base.id); + scene_entity_base_remove(game_state_get()->scene, &player->base); player->base.flags = EF_NONE; } diff --git a/src/game/renderer.c b/src/game/renderer.c index a2852ff..f53e5ed 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -459,8 +459,11 @@ void renderer_on_framebuffer_size_changed(const struct Event* event) for(int i = 0; i < MAX_CAMERAS; i++) { struct Camera* viewer = &scene->cameras[i]; - viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f; - camera_update_proj(viewer); + if(viewer->resizeable) + { + viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f; + camera_update_proj(viewer); + } } framebuffer_resize_all(width, height); diff --git a/src/game/scene.c b/src/game/scene.c index 8d3b38d..b1966a5 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -279,7 +279,6 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser while(count < max_length) { //((char*)entity) += stride * count; - ((char*)entity) += stride; if(!(entity->flags & EF_TRANSIENT) && (entity->flags & EF_ACTIVE)) { @@ -295,6 +294,7 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser } } count++; + ((char*)entity) += stride; } } @@ -634,6 +634,7 @@ void scene_light_remove(struct Scene* scene, struct Light* light) void scene_camera_remove(struct Scene* scene, struct Camera* camera) { assert(scene && camera); + camera_reset(camera); scene_entity_base_remove(scene, &camera->base); } @@ -926,3 +927,36 @@ bool scene_save_(const char* filename, int directory_type) return success; } + +int scene_entity_archetype_add(struct Scene* scene, const char* filename) +{ + // check if we have already added this archetype, if we have, return that index + // otherwise add it and return the index + int index = -1; + for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) + { + if(strncmp(filename, &scene->entity_archetypes[i][0], MAX_FILENAME_LEN) == 0) + { + index = i; + break; + } + } + + if(index == -1) + { + for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) + { + if(scene->entity_archetypes[i][0] == '\0') + { + strncpy(&scene->entity_archetypes[i][0], filename, MAX_FILENAME_LEN); + index = i; + break; + } + } + } + + if(index == -1) + log_warning("Out of archetype indices!"); + + return index; +} diff --git a/src/game/scene.h b/src/game/scene.h index cc10b94..4227434 100755 --- a/src/game/scene.h +++ b/src/game/scene.h @@ -56,6 +56,7 @@ struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent); void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent +int scene_entity_archetype_add(struct Scene* scene, const char* filename); void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results); diff --git a/todo.txt b/todo.txt index d407d1e..1418c97 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,7 @@ Todo: - - Save default entity archetype to be loaded when there is not other archetype or in case of an error as fallback + - Fix cameras not resizing to current resolution when scene is loaded/reloaded + - Allow renaming scene objects in editor + - Add parameter to entity_load command that renames the newly loaded object to whatever the second specified parameter is - Bring back debug variable display in editor and allow showing colours, textures etc - Implment/Test reading/writing scene that has a mixture of default entites and entity archetypes - Serialize player, camera properties to file @@ -18,6 +20,7 @@ Todo: - Better, more accurate picking - Editor related messages/notifications in the bottom status bar ? Disable entity picking when tool is in use or only allow picking when pressing ALT + ? Maybe remove physics engine and ode all together if we're not using it or investigate the memory leaks that it causes if we're going to keep it? - Disable editor event recievers on game mode change - Editor Undo - Duplicate with Ctrl-D @@ -123,6 +126,7 @@ Bugs: - Fix shader preprocessor failing when the file in //include directive is empty - Fix bug with blinn shader reaching maximum uniform number on mac - Fix delete in editor not working when the cursor is hovering over scene heirarchy window + - Investigate memory leaks caused by nuklear or opengl related operations in gui_update Done: * Input @@ -337,4 +341,6 @@ Done: * Implemented flags that specify whether an entity should be written to file or not for example to avoid writing cameras and player to file * In editor, only show entities with specific flags * Fixed bugs with meshes being registered to uninitialized materials and not rendering - * Added EF_SKIP_RENDER flag to allow entites to skip rendering \ No newline at end of file + * Added EF_SKIP_RENDER flag to allow entites to skip rendering + * Save default entity archetype to be loaded when there is not other archetype or in case of an error as fallback + * Ensure cameras are not initialized multiple times \ No newline at end of file