diff --git a/README.md b/README.md index 0df8dae..e220781 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ - ## TODO - - Add camera fbo params into camera struct so they can be saved and loaded into file + - Implement sound/listener loading from scene file - Finish loading scene from file - Update makefiles to be able to compile the code in it's current state - Find a solution for the asset import/export situation by either updating the blender exporter or adding assimp as dependancy @@ -313,4 +313,6 @@ * Default keybindings as fallback * Implemented writing scene to file * Fixed space not being added after light entities are written to file by adding missing new-line - * Fixed error caused by the way eof was checked in scene file + * Fixed error caused by the way eof was checked in scene file + * Camera fbo params are now written to file when entity is saved + * Fixed several bugs with entity loading diff --git a/src/libsymmetry/camera.c b/src/libsymmetry/camera.c index c88f9af..0be17aa 100644 --- a/src/libsymmetry/camera.c +++ b/src/libsymmetry/camera.c @@ -100,9 +100,9 @@ void camera_update_proj(struct Entity* entity) void camera_attach_fbo(struct Entity* entity, int width, int height, - int has_depth, - int has_color, - int resizeable) + bool has_depth, + bool has_color, + bool resizeable) { assert(width > 0 && height > 0); struct Camera* camera = &entity->camera; @@ -127,7 +127,7 @@ void camera_attach_fbo(struct Entity* entity, texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); texture_set_param(camera->render_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); texture_set_param(camera->render_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - framebuffer_set_texture(camera->fbo, camera->render_tex, FA_COLOR_ATTACHMENT0); + framebuffer_texture_set(camera->fbo, camera->render_tex, FA_COLOR_ATTACHMENT0); } if(has_depth) @@ -145,7 +145,7 @@ void camera_attach_fbo(struct Entity* entity, texture_set_param(camera->depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - framebuffer_set_texture(camera->fbo, camera->depth_tex, FA_DEPTH_ATTACHMENT); + framebuffer_texture_set(camera->fbo, camera->depth_tex, FA_DEPTH_ATTACHMENT); } } else diff --git a/src/libsymmetry/camera.h b/src/libsymmetry/camera.h index ae21fc9..c1bad1d 100644 --- a/src/libsymmetry/camera.h +++ b/src/libsymmetry/camera.h @@ -1,6 +1,8 @@ #ifndef CAMERA_H #define CAMERA_H +#include "../common/num_types.h" + struct Entity; void camera_destroy(struct Entity* entity); @@ -11,9 +13,9 @@ void camera_update_proj(struct Entity* entity); void camera_attach_fbo(struct Entity* entity, int width, int height, - int has_depth, - int has_color, - int resizeable); + bool has_depth, + bool has_color, + bool resizeable); /* void camera_resize_all(int width, int height); */ #endif diff --git a/src/libsymmetry/editor.c b/src/libsymmetry/editor.c index 58c6224..aad42ef 100644 --- a/src/libsymmetry/editor.c +++ b/src/libsymmetry/editor.c @@ -276,6 +276,9 @@ void editor_update(float dt) nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); + nk_layout_row_dynamic(context, row_height, 2); + struct Entity* parent_ent = entity_get(entity->transform.parent); + nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); /* Transform */ { @@ -364,6 +367,29 @@ void editor_update(float dt) nk_tree_pop(context); } } + + /* Camera */ + if(entity->type == ET_CAMERA) + { + if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED)) + { + struct Camera* camera = &entity->camera; + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, "Fov", 45.f, &camera->fov, 90.f, 1.f, 5.f); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, "NearZ", 0.01f, &camera->nearz, camera->farz, 0.1f, 1.f); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, "FarZ", camera->nearz, &camera->farz, FLT_MAX, 1.f, 5.f); + + nk_tree_pop(context); + } + } } else { diff --git a/src/libsymmetry/entity.c b/src/libsymmetry/entity.c index 82516c9..3a876a5 100644 --- a/src/libsymmetry/entity.c +++ b/src/libsymmetry/entity.c @@ -8,6 +8,7 @@ #include "model.h" #include "material.h" #include "geometry.h" +#include "framebuffer.h" #include "../common/variant.h" #include "../common/common.h" @@ -237,7 +238,23 @@ bool entity_write(struct Entity* entity, FILE* file) fprintf(file, "fov: %.5f\n", entity->camera.fov); fprintf(file, "nearz: %.5f\n", entity->camera.nearz); fprintf(file, "farz: %.5f\n", entity->camera.farz); - fprintf(file, "render_texture: %s\n", entity->camera.render_tex == -1 ? "false" : "true"); + fprintf(file, "clear_color: %.5f %.5f %.5f %.5f\n", + entity->camera.clear_color.x, + entity->camera.clear_color.y, + entity->camera.clear_color.z, + entity->camera.clear_color.w); + if(entity->camera.fbo != -1) + { + fprintf(file, "has_fbo: true\n"); + fprintf(file, "fbo_height: %d\n", framebuffer_height_get(entity->camera.fbo)); + fprintf(file, "fbo_width: %d\n", framebuffer_width_get(entity->camera.fbo)); + fprintf(file, "fbo_has_render_tex: %s\n", entity->camera.render_tex == -1 ? "false" : "true"); + fprintf(file, "fbo_has_depth_tex: %s\n", entity->camera.depth_tex == -1 ? "false" : "true"); + } + else + { + fprintf(file, "has_fbo: false\n"); + } break; } case ET_STATIC_MESH: @@ -316,11 +333,13 @@ struct Entity* entity_read(FILE* file) .editor_selected = 0 }; - int current_line = 0; - char* material_name = NULL; - char* entity_name = NULL; - char* geometry_name = NULL; - char* parent_name = NULL; + int current_line = 0; + char* material_name = NULL; + char* entity_name = NULL; + char* geometry_name = NULL; + char* parent_name = NULL; + int camera_fbo_width = -1; + int camera_fbo_height = -1; char line_buffer[MAX_LINE_LEN]; char prop_str[MAX_ENTITY_PROP_NAME_LEN]; static struct Variant var_value = { .type = VT_NONE}; @@ -359,7 +378,7 @@ struct Entity* entity_read(FILE* file) entity_name = str_new(var_value.val_str); //variant_copy_out(&entity.name, &var_value); } - if(strncmp("parent", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + else if(strncmp("parent", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) { variant_from_str(&var_value, value_str, VT_STR); parent_name = str_new(var_value.val_str); @@ -424,11 +443,35 @@ struct Entity* entity_read(FILE* file) variant_from_str(&var_value, value_str, VT_FLOAT); variant_copy_out(&entity.camera.farz, &var_value); } - else if(strncmp("render_texture", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + else if(strncmp("has_fbo", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) { variant_from_str(&var_value, value_str, VT_BOOL); entity.camera.fbo = var_value.val_bool ? 0 : -1; - //variant_copy_out(&entity.camera.fbo, &var_value); + } + else if(strncmp("fbo_height", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + { + variant_from_str(&var_value, value_str, VT_INT); + variant_copy_out(&camera_fbo_height, &var_value); + } + else if(strncmp("fbo_width", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + { + variant_from_str(&var_value, value_str, VT_INT); + variant_copy_out(&camera_fbo_width, &var_value); + } + else if(strncmp("fbo_has_depth_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + { + variant_from_str(&var_value, value_str, VT_BOOL); + entity.camera.depth_tex = var_value.val_bool ? 0 : -1; + } + else if(strncmp("fbo_has_render_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + { + variant_from_str(&var_value, value_str, VT_BOOL); + entity.camera.render_tex = var_value.val_bool ? 0 : -1; + } + else if(strncmp("clear_color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) + { + variant_from_str(&var_value, value_str, VT_VEC4); + variant_copy_out(&entity.camera.clear_color, &var_value); } /* Light */ @@ -516,13 +559,17 @@ struct Entity* entity_read(FILE* file) variant_from_str(&var_value, value_str, VT_INT); variant_copy_out(&entity.sound_source.num_attached_buffers, &var_value); } + else + { + log_warning("Unknown entity property '%s' in line %d", prop_str, current_line); + } variant_free(&var_value); } /* Do the things after assignment */ struct Entity* parent_entity = NULL; - if(strcmp(parent_name, "NONE") == 0) + if(strcmp(parent_name, "NONE") != 0) parent_entity = entity_find(parent_name); struct Entity* new_entity = entity_create(entity_name, entity.type, parent_entity ? parent_entity->id : -1); @@ -536,11 +583,26 @@ struct Entity* entity_read(FILE* file) switch(new_entity->type) { case ET_CAMERA: - new_entity->camera.fbo = -1; /* TODO: FIX by storing fbo params in camera struct and writing them into file when saving */ + new_entity->camera.fbo = -1; + new_entity->camera.depth_tex = -1; new_entity->camera.render_tex = -1; - new_entity->camera.depth_tex = -1; + new_entity->camera.resizeable = false; + new_entity->camera.nearz = entity.camera.nearz; + new_entity->camera.farz = entity.camera.farz; + new_entity->camera.ortho = entity.camera.ortho; + new_entity->camera.fov = entity.camera.fov; + float aspect_ratio = (float)camera_fbo_width / (float)camera_fbo_height; + new_entity->camera.aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio; camera_update_view(new_entity); camera_update_proj(new_entity); + if(entity.camera.fbo != -1) + { + camera_attach_fbo(new_entity, camera_fbo_width, camera_fbo_height, + entity.camera.depth_tex == -1 ? false : true, + entity.camera.render_tex == -1 ? false : true, + entity.camera.resizeable); + } + vec4_assign(&new_entity->camera.clear_color, &entity.camera.clear_color); break; case ET_STATIC_MESH: model_create(new_entity, geometry_name, material_name); @@ -552,8 +614,8 @@ struct Entity* entity_read(FILE* file) light_add(new_entity); break; case ET_SOUND_SOURCE: - platform->sound.source_create(new_entity->sound_source.relative, - new_entity->sound_source.num_attached_buffers, + platform->sound.source_create(entity.sound_source.relative, + entity.sound_source.num_attached_buffers, &new_entity->sound_source.source_handle, &new_entity->sound_source.buffer_handles[0]); break; diff --git a/src/libsymmetry/framebuffer.c b/src/libsymmetry/framebuffer.c index e0becd8..51ef4d0 100644 --- a/src/libsymmetry/framebuffer.c +++ b/src/libsymmetry/framebuffer.c @@ -15,7 +15,7 @@ struct FBO int texture_attachments[FA_NUM_ATTACHMENTS]; int width; int height; - int resizeable; + bool resizeable; }; struct FBO* fbo_list; @@ -38,7 +38,7 @@ void framebuffer_cleanup(void) empty_indices = NULL; } -int framebuffer_create(int width, int height, int has_depth, int has_color, int resizeable) +int framebuffer_create(int width, int height, bool has_depth, bool has_color, bool resizeable) { int index = -1; GLuint fbo = 0; @@ -146,6 +146,7 @@ void framebuffer_remove(int index) fbo->handle = 0; fbo->width = -1; fbo->height = -1; + fbo->resizeable = false; } void framebuffer_unbind(void) @@ -153,19 +154,19 @@ void framebuffer_unbind(void) glBindFramebuffer(GL_FRAMEBUFFER, 0); } -int framebuffer_get_width(int index) +int framebuffer_width_get(int index) { assert(index < array_len(fbo_list) && index > -1); return fbo_list[index].width; } -int framebuffer_get_height(int index) +int framebuffer_height_get(int index) { assert(index < array_len(fbo_list) && index > -1); return fbo_list[index].height; } -void framebuffer_set_texture(int index, int texture, enum Framebuffer_Attachment attachment) +void framebuffer_texture_set(int index, int texture, enum Framebuffer_Attachment attachment) { assert(index < array_len(fbo_list) && index > -1); GLenum gl_attachment = -1; @@ -201,7 +202,7 @@ void framebuffer_set_texture(int index, int texture, enum Framebuffer_Attachment glBindFramebuffer(GL_FRAMEBUFFER, current_fbo); } -int framebuffer_get_texture(int index, enum Framebuffer_Attachment attachment) +int framebuffer_texture_get(int index, enum Framebuffer_Attachment attachment) { assert(index < array_len(fbo_list) && index > -1 && @@ -210,7 +211,7 @@ int framebuffer_get_texture(int index, enum Framebuffer_Attachment attachment) return fbo_list[index].texture_attachments[attachment]; } -uint framebuffer_get_gl_handle(int index) +uint framebuffer_gl_handle_get(int index) { assert(index < array_len(fbo_list) && index > -1); return fbo_list[index].handle; @@ -293,8 +294,8 @@ void framebuffer_resize_all(int width, int height) } } -void framebuffer_resizeable_set(int index, int resizeable) +void framebuffer_resizeable_set(int index, bool resizeable) { assert(index > -1 && index < array_len(fbo_list)); - fbo_list[index].resizeable = resizeable ? 1 : 0; + fbo_list[index].resizeable = resizeable ? true : false; } diff --git a/src/libsymmetry/framebuffer.h b/src/libsymmetry/framebuffer.h index 5a00e64..debd3b5 100644 --- a/src/libsymmetry/framebuffer.h +++ b/src/libsymmetry/framebuffer.h @@ -12,17 +12,17 @@ enum Framebuffer_Attachment void framebuffer_init(void); void framebuffer_cleanup(void); -int framebuffer_create(int width, int height, int has_depth, int has_color, int resizeable); +int framebuffer_create(int width, int height, bool has_depth, bool has_color, bool resizeable); void framebuffer_bind(int index); void framebuffer_remove(int index); void framebuffer_unbind(void); -int framebuffer_get_width(int index); -int framebuffer_get_height(int index); -void framebuffer_set_texture(int index, int texture, enum Framebuffer_Attachment attachment); -int framebuffer_get_texture(int index, enum Framebuffer_Attachment attachment); -uint framebuffer_get_gl_handle(int index); +int framebuffer_width_get(int index); +int framebuffer_height_get(int index); +void framebuffer_texture_set(int index, int texture, enum Framebuffer_Attachment attachment); +int framebuffer_texture_get(int index, enum Framebuffer_Attachment attachment); +uint framebuffer_gl_handle_get(int index); void framebuffer_resize(int index, int width, int height); void framebuffer_resize_all(int width, int height); -void framebuffer_resizeable_set(int index, int resizeable); +void framebuffer_resizeable_set(int index, bool resizeable); #endif diff --git a/src/libsymmetry/renderer.c b/src/libsymmetry/renderer.c index afe7521..a3a720f 100644 --- a/src/libsymmetry/renderer.c +++ b/src/libsymmetry/renderer.c @@ -108,9 +108,9 @@ void renderer_init(void) texture_set_param(def_depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); texture_set_param(def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - def_fbo = framebuffer_create(width, height, 1, 0, 1); - framebuffer_set_texture(def_fbo, def_albedo_tex, FA_COLOR_ATTACHMENT0); - framebuffer_set_texture(def_fbo, def_depth_tex, FA_DEPTH_ATTACHMENT); + def_fbo = framebuffer_create(width, height, true, false, true); + framebuffer_texture_set(def_fbo, def_albedo_tex, FA_COLOR_ATTACHMENT0); + framebuffer_texture_set(def_fbo, def_depth_tex, FA_DEPTH_ATTACHMENT); composition_shader = shader_create("fbo.vert", "fbo.frag"); debug_shader = shader_create("debug.vert", "debug.frag"); @@ -132,7 +132,7 @@ void renderer_draw(struct Entity* active_viewer) int fbo = camera->fbo == -1 ? def_fbo : camera->fbo; framebuffer_bind(fbo); { - glViewport(0, 0, framebuffer_get_width(fbo), framebuffer_get_height(fbo)); + glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo)); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearColor(camera->clear_color.x, diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c index 396e16d..f3a4da0 100644 --- a/src/libsymmetry/scene.c +++ b/src/libsymmetry/scene.c @@ -13,8 +13,8 @@ static int root_node = -1; void scene_init(void) { /* Add root node to scene */ - struct Entity* root = entity_create("ROOT", ET_ROOT, -1); - root_node = root->id; + /* struct Entity* root = entity_create("ROOT", ET_ROOT, -1); */ + /* root_node = root->id; */ } struct Entity* scene_add_new(const char* name, const int type)