diff --git a/README b/README index f46b998..901eb2a 100644 --- a/README +++ b/README @@ -54,20 +54,24 @@ _________________ .. 2.38 TODO Physics/Collision detection in 2d .. 2.39 TODO Complete gui integration .. 2.40 TODO Allow passsing base path as commandline argument? -.. 2.41 TODO Validate necessary assets at game launch -.. 2.42 TODO Variant type -.. 2.43 TODO Log and debug/stats output in gui -.. 2.44 TODO Editor -.. 2.45 TODO Event Subsystem -.. 2.46 TODO Keybindings for gui? -.. 2.47 DONE Compile and test on windows -.. 2.48 TODO Array based string type comptible with cstring(char*) -.. 2.49 DONE Fix mouse bugs -.. 2.50 DONE Fix -.. 2.51 TODO issues with opengl context showing 2.1 only -.. 2.52 TODO Improve this readme -.. 2.53 TODO ??? -.. 2.54 TODO Profit! +.. 2.41 DONE Resizable framebuffers and textures +.. 2.42 DONE Support for multiple color attachments in framebuffers? +.. 2.43 TODO Multisampled textures and framebuffers +.. 2.44 DONE Better way to store and manage textures attached to framebuffers +.. 2.45 TODO Validate necessary assets at game launch +.. 2.46 TODO Variant type +.. 2.47 TODO Log and debug/stats output in gui +.. 2.48 TODO Editor +.. 2.49 TODO Event Subsystem +.. 2.50 TODO Keybindings for gui? +.. 2.51 DONE Compile and test on windows +.. 2.52 TODO Array based string type comptible with cstring(char*) +.. 2.53 DONE Fix mouse bugs +.. 2.54 DONE Fix +.. 2.55 TODO issues with opengl context showing 2.1 only +.. 2.56 TODO Improve this readme +.. 2.57 TODO ??? +.. 2.58 TODO Profit! 1 Project Symmetry @@ -325,8 +329,7 @@ _________________ 2.39 TODO Complete gui integration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Font selection - - Font atlas proper cleanup + x Font selection x Font atlas proper cleanup - Decoupled event handling of gui and input if possible - Custom rendering for gui @@ -335,63 +338,85 @@ _________________ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.41 TODO Validate necessary assets at game launch +2.41 DONE Resizable framebuffers and textures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + - State "DONE" from "TODO" [2017-03-16 Thu 22:50] + + +2.42 DONE Support for multiple color attachments in framebuffers? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + - State "DONE" from "TODO" [2017-03-16 Thu 22:51] + + +2.43 TODO Multisampled textures and framebuffers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +2.44 DONE Better way to store and manage textures attached to framebuffers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + - State "DONE" from "TODO" [2017-03-16 Thu 22:51] + + +2.45 TODO Validate necessary assets at game launch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.42 TODO Variant type +2.46 TODO Variant type ~~~~~~~~~~~~~~~~~~~~~~ -2.43 TODO Log and debug/stats output in gui +2.47 TODO Log and debug/stats output in gui ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.44 TODO Editor +2.48 TODO Editor ~~~~~~~~~~~~~~~~ -2.45 TODO Event Subsystem +2.49 TODO Event Subsystem ~~~~~~~~~~~~~~~~~~~~~~~~~ -2.46 TODO Keybindings for gui? +2.50 TODO Keybindings for gui? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.47 DONE Compile and test on windows +2.51 DONE Compile and test on windows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - State "DONE" from "TODO" [2017-03-14 Tue 00:32] -2.48 TODO Array based string type comptible with cstring(char*) +2.52 TODO Array based string type comptible with cstring(char*) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.49 DONE Fix mouse bugs +2.53 DONE Fix mouse bugs ~~~~~~~~~~~~~~~~~~~~~~~~ - State "DONE" from "TODO" [2017-03-01 Wed 00:45] -2.50 DONE Fix +2.54 DONE Fix ~~~~~~~~~~~~~ -2.51 TODO issues with opengl context showing 2.1 only +2.55 TODO issues with opengl context showing 2.1 only ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - State "DONE" from "TODO" [2017-02-26 Sun 15:39] -2.52 TODO Improve this readme +2.56 TODO Improve this readme ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -2.53 TODO ??? +2.57 TODO ??? ~~~~~~~~~~~~~ -2.54 TODO Profit! +2.58 TODO Profit! ~~~~~~~~~~~~~~~~~ diff --git a/orgfile.org b/orgfile.org index 31e6268..e3fde0b 100644 --- a/orgfile.org +++ b/orgfile.org @@ -96,11 +96,18 @@ All the code in this repository is under GPLv3, see LICENSE for more information ** TODO Fix mouse bugs on windows ** TODO Physics/Collision detection in 2d ** TODO Complete gui integration -- Font selection -- Font atlas proper cleanup +x Font selection +x Font atlas proper cleanup - Decoupled event handling of gui and input if possible - Custom rendering for gui ** TODO Allow passsing base path as commandline argument? +** DONE Resizable framebuffers and textures +- State "DONE" from "TODO" [2017-03-16 Thu 22:50] +** DONE Support for multiple color attachments in framebuffers? +- State "DONE" from "TODO" [2017-03-16 Thu 22:51] +** TODO Multisampled textures and framebuffers +** DONE Better way to store and manage textures attached to framebuffers +- State "DONE" from "TODO" [2017-03-16 Thu 22:51] ** TODO Validate necessary assets at game launch ** TODO Variant type ** TODO Log and debug/stats output in gui diff --git a/src/camera.c b/src/camera.c index 6ec3a14..911ebc5 100644 --- a/src/camera.c +++ b/src/camera.c @@ -127,7 +127,12 @@ void camera_update_proj(struct Camera* camera) camera_update_view_proj(camera); } -void camera_attach_fbo(struct Camera* camera, int width, int height, int has_depth, int has_color) +void camera_attach_fbo(struct Camera* camera, + int width, + int height, + int has_depth, + int has_color, + int resizeable) { assert(width > 0 && height > 0 && camera); if(camera->fbo != -1) @@ -135,7 +140,7 @@ void camera_attach_fbo(struct Camera* camera, int width, int height, int has_dep log_error("camera:attach_fbo", "Camera already has fbo attached!"); return; } - camera->fbo = framebuffer_create(width, height, has_depth, has_color); + camera->fbo = framebuffer_create(width, height, has_depth, has_color, resizeable); if(camera->fbo > -1) { char tex_name[128]; @@ -168,9 +173,8 @@ void camera_attach_fbo(struct Camera* camera, int width, int height, int has_dep 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); - camera->fbo = framebuffer_create(width, height, 0, 1); - framebuffer_set_texture(camera->fbo, camera->render_tex, GL_COLOR_ATTACHMENT0); - framebuffer_set_texture(camera->fbo, camera->depth_tex, GL_DEPTH_ATTACHMENT); + framebuffer_set_texture(camera->fbo, camera->render_tex, FA_COLOR_ATTACHMENT0); + framebuffer_set_texture(camera->fbo, camera->depth_tex, FA_DEPTH_ATTACHMENT); } else { diff --git a/src/camera.h b/src/camera.h index 23d80fa..d282f1f 100644 --- a/src/camera.h +++ b/src/camera.h @@ -31,7 +31,12 @@ int camera_create(int node, int width, int height); void camera_update_view_proj(struct Camera* camera); void camera_update_view(struct Camera* camera); void camera_update_proj(struct Camera* camera); -void camera_attach_fbo(struct Camera* camera, int width, int height, int has_depth, int has_color); +void camera_attach_fbo(struct Camera* camera, + int width, + int height, + int has_depth, + int has_color, + int resizeable); void camera_set_primary_viewer(struct Camera* camera); #endif diff --git a/src/framebuffer.c b/src/framebuffer.c index 0de089d..737d4c4 100644 --- a/src/framebuffer.c +++ b/src/framebuffer.c @@ -7,13 +7,17 @@ #include +#define MAX_TEXTURE_ATTACHMENTS 3 /* Pointless define just to avoid VLA's and be compatible with msvc */ + struct FBO { uint handle; - uint renderbuffer; - int texture; + uint depth_renderbuffer; + uint color_renderbuffer; + int texture_attachments[MAX_TEXTURE_ATTACHMENTS]; int width; int height; + int resizeable; }; struct FBO* fbo_list; @@ -34,36 +38,50 @@ void framebuffer_cleanup(void) array_free(empty_indices); } -int framebuffer_create(int width, int height, int has_depth, int has_color) +int framebuffer_create(int width, int height, int has_depth, int has_color, int resizeable) { - int index = -1; - GLuint fbo; - GLuint renderbuffer; - + int index = -1; + GLuint fbo = 0; + GLuint depth_renderbuffer = 0; + GLuint color_renderbuffer = 0; + glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glGenRenderbuffers(1, &renderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, - GL_DEPTH_COMPONENT, - width, - height); - renderer_check_glerror("framebuffer:create"); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, - renderbuffer); - renderer_check_glerror("framebuffer:create"); - if(has_color) + if(has_depth) { - glDrawBuffer(GL_COLOR_ATTACHMENT0); + glGenRenderbuffers(1, &depth_renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, + GL_DEPTH_COMPONENT, + width, + height); + renderer_check_glerror("framebuffer:create:depth_renderbuffer"); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, + depth_renderbuffer); + renderer_check_glerror("framebuffer:create:depth_renderbuffer"); + glBindRenderbuffer(GL_RENDERBUFFER, 0); } - - if(has_depth) + + if(has_color) { - glDrawBuffer(GL_NONE); + glGenRenderbuffers(1, &color_renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, + GL_RGBA8, + width, + height); + renderer_check_glerror("framebuffer:create:color_renderbuffer"); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + color_renderbuffer); + renderer_check_glerror("framebuffer:create:color_renderbuffer"); + glBindRenderbuffer(GL_RENDERBUFFER, 0); } - + + glDrawBuffer(has_color ? GL_COLOR_ATTACHMENT0 : GL_NONE); renderer_check_glerror("framebuffer:create"); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if(status != GL_FRAMEBUFFER_COMPLETE) @@ -85,16 +103,16 @@ int framebuffer_create(int width, int height, int has_depth, int has_color) array_pop(empty_indices); } - framebuffer->handle = fbo; - framebuffer->renderbuffer = renderbuffer; - framebuffer->texture = -1; - framebuffer->width = width; - framebuffer->height = height; + framebuffer->handle = fbo; + framebuffer->depth_renderbuffer = depth_renderbuffer; + framebuffer->color_renderbuffer = color_renderbuffer; + framebuffer->width = width; + framebuffer->height = height; + framebuffer->resizeable = resizeable; + for(int i = 0; i < FA_NUM_ATTACHMENTS; i++) framebuffer->texture_attachments[i] = -1; log_message("Framebuffer created successfully"); } glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - return index; } @@ -102,15 +120,32 @@ void framebuffer_bind(int index) { assert(index < array_len(fbo_list) && index > -1); glBindFramebuffer(GL_FRAMEBUFFER, fbo_list[index].handle); + /* if(fbo_list[index].color_renderbuffer != 0) */ + /* glDrawBuffer(GL_COLOR_ATTACHMENT0); */ + /* else */ + /* glDrawBuffer(GL_NONE); */ } void framebuffer_remove(int index) { assert(index < array_len(fbo_list) && index > -1); struct FBO* fbo = &fbo_list[index]; - if(fbo->texture != -1) texture_remove(fbo->texture); - glDeleteRenderbuffers(1, &fbo->renderbuffer); + for(int i = 0; i < FA_NUM_ATTACHMENTS; i++) + { + if(fbo->texture_attachments[i] != -1) + { + texture_remove(fbo->texture_attachments[i]); + fbo->texture_attachments[i] = -1; + } + } + if(fbo->depth_renderbuffer != 0) glDeleteRenderbuffers(1, &fbo->depth_renderbuffer); + if(fbo->color_renderbuffer != 0) glDeleteRenderbuffers(1, &fbo->color_renderbuffer); glDeleteFramebuffers(1, &fbo->handle); + fbo->color_renderbuffer = 0; + fbo->depth_renderbuffer = 0; + fbo->handle = 0; + fbo->width = -1; + fbo->height = -1; } void framebuffer_unbind(void) @@ -124,40 +159,55 @@ int framebuffer_get_width(int index) return fbo_list[index].width; } -int framebuffer_get_height(int index) +int framebuffer_get_height(int index) { assert(index < array_len(fbo_list) && index > -1); return fbo_list[index].height; } -void framebuffer_set_texture(int index, int texture, int attachment) +void framebuffer_set_texture(int index, int texture, enum Framebuffer_Attachment attachment) { assert(index < array_len(fbo_list) && index > -1); + GLenum gl_attachment = -1; + switch(attachment) + { + case FA_COLOR_ATTACHMENT0: gl_attachment = GL_COLOR_ATTACHMENT0; break; + case FA_DEPTH_ATTACHMENT: gl_attachment = GL_DEPTH_ATTACHMENT; break; + default: log_error("framebuffer:set_texture", "Invalid attachment type"); return; + }; + + struct FBO* fbo = &fbo_list[index]; + int current_texture = fbo->texture_attachments[attachment]; + if(current_texture != -1) + { + texture_remove(current_texture); + fbo->texture_attachments[attachment] = -1; + } + + if(texture == -1) return; + GLint current_fbo = 0; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); renderer_check_glerror("framebuffer:set_texture:glGet"); framebuffer_bind(index); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, - attachment, + gl_attachment, GL_TEXTURE_2D, texture_get_texture_handle(texture), 0); - /* if(!renderer_check_glerror("framebuffer:set_texture:glFramebuffertexture")) */ - /* { */ - /* int current_fbo_tex = fbo_list[index].texture; */ - /* if(current_fbo_tex > -1) */ - /* texture_remove(current_fbo_tex); */ - - /* fbo_list[index].texture = texture; */ - /* texture_inc_refcount(texture); */ - /* } */ + renderer_check_glerror("framebuffer:set_texture:glFramebuffertexture2d"); + fbo->texture_attachments[attachment] = texture; + if(attachment == FA_COLOR_ATTACHMENT0) glDrawBuffer(GL_COLOR_ATTACHMENT0); glBindFramebuffer(GL_FRAMEBUFFER, current_fbo); } -int framebuffer_get_texture(int index) +int framebuffer_get_texture(int index, enum Framebuffer_Attachment attachment) { - assert(index < array_len(fbo_list) && index > -1); - return fbo_list[index].texture; + assert(index < array_len(fbo_list) && + index > -1 && + attachment < FA_NUM_ATTACHMENTS && + (int)attachment > -1); + return fbo_list[index].texture_attachments[attachment]; } uint framebuffer_get_gl_handle(int index) @@ -165,3 +215,86 @@ uint framebuffer_get_gl_handle(int index) assert(index < array_len(fbo_list) && index > -1); return fbo_list[index].handle; } + +void framebuffer_resize(int index, int width, int height) +{ + assert(index > -1 && index < array_len(fbo_list)); + width -= (width % 2); + height -= (height % 2); + GLint current_fbo = 0; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + renderer_check_glerror("framebuffer:resize:glGet"); + struct FBO* fbo = &fbo_list[index]; + if(!fbo->resizeable) return; + framebuffer_bind(index); + if(fbo->depth_renderbuffer != 0) + { + glBindRenderbuffer(GL_RENDERBUFFER, fbo->depth_renderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, + GL_DEPTH_COMPONENT, + width, + height); + renderer_check_glerror("framebuffer:resize:depth_renderbuffer"); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, + fbo->depth_renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + + if(fbo->color_renderbuffer != 0) + { + glBindRenderbuffer(GL_RENDERBUFFER, fbo->color_renderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, + GL_RGBA8, + width, + height); + renderer_check_glerror("framebuffer:resize:color_renderbuffer"); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + fbo->color_renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + + for(int i = 0; i < FA_NUM_ATTACHMENTS; i++) + { + if(fbo->texture_attachments[i] != -1) + { + int texture = fbo->texture_attachments[i]; + GLenum gl_attachment = -1; + switch(i) + { + case FA_COLOR_ATTACHMENT0: gl_attachment = GL_COLOR_ATTACHMENT0; break; + case FA_DEPTH_ATTACHMENT: gl_attachment = GL_DEPTH_ATTACHMENT; break; + default: log_error("framebuffer:resize", "Invalid attachment type"); continue; + }; + + texture_resize(texture, width, height, NULL); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, + gl_attachment, + GL_TEXTURE_2D, + texture_get_texture_handle(texture), + 0); + } + } + + glBindFramebuffer(GL_FRAMEBUFFER, current_fbo); + fbo->width = width; + fbo->height = height; + log_message("Resized framebuffer to %dx%d", width, height); +} + +void framebuffer_resize_all(int width, int height) +{ + for(int i = 0; i < array_len(fbo_list); i++) + { + if(fbo_list[i].resizeable) framebuffer_resize(i, width, height); + } +} + +void framebuffer_resizeable_set(int index, int resizeable) +{ + assert(index > -1 && index < array_len(fbo_list)); + fbo_list[index].resizeable = resizeable ? 1 : 0; +} diff --git a/src/framebuffer.h b/src/framebuffer.h index 6b49398..63451c8 100644 --- a/src/framebuffer.h +++ b/src/framebuffer.h @@ -3,16 +3,26 @@ #include "num_types.h" +enum Framebuffer_Attachment +{ + FA_COLOR_ATTACHMENT0 = 0, + FA_DEPTH_ATTACHMENT, + FA_NUM_ATTACHMENTS +}; + void framebuffer_init(void); void framebuffer_cleanup(void); -int framebuffer_create(int width, int height, int has_depth, int has_color); +int framebuffer_create(int width, int height, int has_depth, int has_color, int 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, int attachment); -int framebuffer_get_texture(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); +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); #endif diff --git a/src/game.c b/src/game.c index fdac34d..709362e 100644 --- a/src/game.c +++ b/src/game.c @@ -102,7 +102,7 @@ void scene_setup(void) render_width = 1024; render_height = 768; struct Camera* camera = entity_component_add(player, C_CAMERA, render_width, render_height); - camera_attach_fbo(camera, render_width, render_height, 1, 1); + camera_attach_fbo(camera, render_width, render_height, 1, 0, 1); vec4_fill(&camera->clear_color, 0.3f, 0.6f, 0.9f, 1.0f); camera_set_primary_viewer(camera); @@ -151,16 +151,16 @@ void scene_setup(void) transform_set_position(ground_tran, &pos); transform_scale(ground_tran, &scale_ground); - /* struct Entity* screen = scene_add_new("Screen", NULL); */ - /* struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); */ - /* screen_model->geometry_index = geom_find("Quad"); */ - /* struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); */ - /* struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM); */ - /* transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); */ - /* struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); */ - /* camera_attach_fbo(cam, 50, 50, 1, 1); */ - /* model_set_material_param(screen_model, "diffuse_color", &color); */ - /* model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); */ + struct Entity* screen = scene_add_new("Screen", NULL); + struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); + screen_model->geometry_index = geom_find("Quad"); + struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); + struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM); + transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); + struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); + camera_attach_fbo(cam, 128, 128, 1, 1, 0); + model_set_material_param(screen_model, "diffuse_color", &color); + model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); const int MAX_LIGHTS = 3; for(int i = 0; i < MAX_LIGHTS; i++) @@ -274,7 +274,7 @@ void debug(float dt) if(offset.x != 0 || offset.y != 0 || offset.z != 0) { transform_translate(transform, &offset, TS_LOCAL); - log_message("Position : %s", tostr_vec3(&transform->position)); + //log_message("Position : %s", tostr_vec3(&transform->position)); } if(input_key_state_get(KEY_SPACE, KS_PRESSED)) diff --git a/src/model.c b/src/model.c index babb7bb..5be6f56 100644 --- a/src/model.c +++ b/src/model.c @@ -20,8 +20,7 @@ #define MAX_NAME_LEN 64 static struct Model* model_list; -static int* empty_indices; -static int use_blinn = 1; +static int* empty_indices; struct Model* model_get(int index) { @@ -35,7 +34,7 @@ struct Model* model_get(int index) void model_init(void) { - model_list = array_new(struct Model); + model_list = array_new(struct Model); empty_indices = array_new(int); } diff --git a/src/platform.c b/src/platform.c index eb9a840..db44fb4 100644 --- a/src/platform.c +++ b/src/platform.c @@ -223,9 +223,8 @@ void platform_poll_events(int* out_quit) } case SDL_WINDOWEVENT: { - if(event.window.type == SDL_WINDOWEVENT_RESIZED) + if(event.window.event == SDL_WINDOWEVENT_RESIZED) { - /* Notify renderer here */ platform_state->on_windowresize_func(event.window.data1, event.window.data2); } } diff --git a/src/renderer.c b/src/renderer.c index afad03f..f43e519 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -23,6 +23,9 @@ static int quad_geo = -1; static int composition_shader = -1; static struct Render_Settings settings; +#define MAX_GUI_VERTEX_MEMORY 512 * 1024 +#define MAX_GUI_ELEMENT_MEMORY 128 * 1024 + void on_framebuffer_size_change(int width, int height); void renderer_init(void) @@ -39,16 +42,16 @@ void renderer_init(void) settings.fog.max_dist = 150.f; vec3_fill(&settings.fog.color, 60.f/255.f, 60.f/255.f, 75.f/255.f); vec3_fill(&settings.ambient_light, 0.1f, 0.1f, 0.12f); - settings.max_gui_vertex_memory = 512 * 1024; - settings.max_gui_element_memory = 128 * 1024; + settings.max_gui_vertex_memory = MAX_GUI_VERTEX_MEMORY; + settings.max_gui_element_memory = MAX_GUI_ELEMENT_MEMORY; gui_init(); /* Quad geometry for final render */ vec3* vertices = array_new(vec3); - vec2* uvs = array_new(vec2); - vec3* normals = array_new(vec3); - uint* indices = array_new(uint); + vec2* uvs = array_new(vec2); + vec3* normals = array_new(vec3); + uint* indices = array_new(uint); vec3 temp_v3; vec2 temp_v2; /* Vertices */ @@ -103,9 +106,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, 1); - framebuffer_set_texture(def_fbo, def_albedo_tex, GL_COLOR_ATTACHMENT0); - framebuffer_set_texture(def_fbo, def_depth_tex, GL_DEPTH_ATTACHMENT); + 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, GL_DEPTH_ATTACHMENT); */ composition_shader = shader_create("fbo.vert", "fbo.frag"); } @@ -118,11 +121,11 @@ void renderer_draw(void) if(camera->node < 0) continue; + /* if(camera->fbo == -1) continue; */ int fbo = camera->fbo == -1 ? def_fbo : camera->fbo; framebuffer_bind(fbo); { glViewport(0, 0, framebuffer_get_width(fbo), framebuffer_get_height(fbo)); - glDrawBuffer(GL_COLOR_ATTACHMENT0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearColor(camera->clear_color.x, @@ -135,7 +138,27 @@ void renderer_draw(void) model_render_all(camera); } framebuffer_unbind(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); } + + /* struct Camera* camera = camera_get_primary(); */ + /* { */ + /* int width, height; */ + /* struct Game_State* game_state = game_state_get(); */ + /* window_get_size(game_state->window, &width, &height); */ + /* glViewport(0, 0, width, height); */ + /* glEnable(GL_DEPTH_TEST); */ + /* glDepthFunc(GL_LEQUAL); */ + /* glClearColor(camera->clear_color.x, */ + /* camera->clear_color.y, */ + /* camera->clear_color.z, */ + /* camera->clear_color.w); */ + /* glEnable(GL_CULL_FACE ); */ + /* glCullFace(GL_BACK); */ + /* glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); */ + /* model_render_all(camera); */ + /* } */ int width, height; struct Game_State* game_state = game_state_get(); @@ -147,12 +170,10 @@ void renderer_draw(void) int final_render_tex = active_camera->render_tex == -1 ? def_albedo_tex : active_camera->render_tex; texture_bind(final_render_tex); geom_render(quad_geo); - shader_unbind(); texture_unbind(final_render_tex); + shader_unbind(); - renderer_check_glerror("Before Gui Render"); gui_render(NK_ANTI_ALIASING_ON, settings.max_gui_vertex_memory, settings.max_gui_element_memory); - renderer_check_glerror("After Gui Render"); } void renderer_cleanup(void) @@ -167,10 +188,12 @@ void renderer_cleanup(void) void on_framebuffer_size_change(int width, int height) { glViewport(0, 0, width, height); - struct Camera* camera = camera_get(0); + struct Camera* camera = camera_get(0); /* TODO: This is an ugly hack, remove it as soon as possible */ float aspect = (float)width / (float)height; camera->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f; camera_update_proj(camera); + //framebuffer_resize(def_fbo, width, height); + framebuffer_resize_all(width, height); } void renderer_set_clearcolor(float red, float green, float blue, float alpha) diff --git a/src/texture.c b/src/texture.c index 52c4d93..d299662 100644 --- a/src/texture.c +++ b/src/texture.c @@ -13,10 +13,13 @@ struct Texture { - char* name; - uint handle; - int ref_count; - int texture_unit; + char* name; + uint handle; + int ref_count; + int texture_unit; + GLenum format; + GLint internal_format; + GLenum type; }; #pragma pack(push, 1) @@ -42,10 +45,10 @@ static int* empty_indices; #define MAX_PIXEL_BYTES 5 -static int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt, int* internal_fmt); +static int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt, int* internal_format); static void debug_write_tga(struct Tga_Header* header, GLubyte* image_data); static void copy_tga_pixel(GLubyte* source, GLubyte* dest, size_t bytes_per_pixel); -static int create_gl_texture(uint* out_handle, int width, int height, int format, int int_fmt, int type, const void* data); +static int create_gl_texture(uint* out_handle, int width, int height, int format, int internal_format, int type, const void* data); void texture_init(void) { @@ -64,22 +67,21 @@ int texture_create_from_file(const char* filename, int texture_unit) return index; } /* If texture not already loaded then try to load it */ - char* full_path = str_new("textures/"); - full_path = str_concat(full_path, filename); + char* full_path = str_new("textures/%s", filename); FILE* file = io_file_open(full_path, "rb"); int img_load_success = -1; if(file) { /* Load texture here */ - int width, height, int_fmt, fmt; + int width, height, internal_format, fmt; GLubyte* img_data = NULL; - width = height = int_fmt = fmt = -1; - img_load_success = load_img(file, &img_data, &width, &height, &fmt, &int_fmt); + width = height = internal_format = fmt = -1; + img_load_success = load_img(file, &img_data, &width, &height, &fmt, &internal_format); if(img_load_success) { - index = texture_create(filename, texture_unit, width, height, fmt, int_fmt, GL_UNSIGNED_BYTE, img_data); + index = texture_create(filename, texture_unit, width, height, fmt, internal_format, GL_UNSIGNED_BYTE, img_data); if(index > -1) { texture_set_param(index, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -115,9 +117,12 @@ void texture_remove(int index) { glDeleteTextures(1, &texture->handle); if(texture->name) free(texture->name); - texture->name = NULL; - texture->ref_count = -1; - texture->texture_unit = -1; + texture->name = NULL; + texture->ref_count = -1; + texture->texture_unit = -1; + texture->format = -1; + texture->internal_format = -1; + texture->type = -1; array_push(empty_indices, index, int); } } @@ -162,7 +167,7 @@ void texture_unbind(int index) glBindTexture(GL_TEXTURE_2D, 0); } -int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt, int* internal_fmt) +int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt, int* internal_format) { int success = 0; struct Tga_Header header; @@ -278,13 +283,12 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt } } } - //debug_write_tga(&header, *image_data); - *height = header.height; - *width = header.width; - *fmt = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; - *internal_fmt = *fmt; - success = 1; + *height = header.height; + *width = header.width; + *fmt = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; + *internal_format = *fmt; + success = 1; } } else @@ -372,14 +376,14 @@ int texture_create(const char* name, int width, int height, int format, - int int_fmt, + int internal_format, int type, const void* data) { assert(name && texture_unit > -1 && texture_unit <= TU_SHADOWMAP4); - int index = -1; + int index = -1; uint handle = 0; - int success = create_gl_texture(&handle, width, height, format, int_fmt, type, data); + int success = create_gl_texture(&handle, width, height, format, internal_format, type, data); if(success) { struct Texture* new_tex = NULL; @@ -392,17 +396,26 @@ int texture_create(const char* name, else { new_tex = array_grow(texture_list, struct Texture); - index = array_len(texture_list) - 1; + index = array_len(texture_list) - 1; } - new_tex->name = str_new(name); - new_tex->handle = handle; - new_tex->ref_count = 1; - new_tex->texture_unit = texture_unit; + new_tex->name = str_new(name); + new_tex->handle = handle; + new_tex->ref_count = 1; + new_tex->texture_unit = texture_unit; + new_tex->format = format; + new_tex->internal_format = internal_format; + new_tex->type = type; } return index; } -int create_gl_texture(uint* out_handle, int width, int height, int format, int int_fmt, int type, const void* data) +int create_gl_texture(uint* out_handle, + int width, + int height, + int format, + int internal_format, + int type, + const void* data) { int success = 1; glGenTextures(1, out_handle); @@ -413,10 +426,35 @@ int create_gl_texture(uint* out_handle, int width, int height, int format, int i else { glBindTexture(GL_TEXTURE_2D, *out_handle); - glTexImage2D(GL_TEXTURE_2D, 0, int_fmt, width, height, 0, format, type, data); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, type, data); if(renderer_check_glerror("texture:create_gl_texture:glTexImage2d")) success = 0; glBindTexture(GL_TEXTURE_2D, 0); } return success; } + +void texture_resize(int index, int width, int height, const void* data) +{ + assert(index > -1 && index < array_len(texture_list)); + width -= (width % 2); + height -= (height % 2); + struct Texture* texture = &texture_list[index]; + + GLint curr_texture = 0; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_texture); + renderer_check_glerror("texture:set_param:glGetIntegerv"); + glBindTexture(GL_TEXTURE_2D, texture->handle); + renderer_check_glerror("texture:set_param:glBindTexture"); + glTexImage2D(GL_TEXTURE_2D, + 0, + texture->internal_format, + width, + height, + 0, + texture->format, + texture->type, + data); + if(curr_texture != 0) + glBindTexture(GL_TEXTURE_2D, curr_texture); +} diff --git a/src/texture.h b/src/texture.h index 8e0bc58..92b5f7b 100644 --- a/src/texture.h +++ b/src/texture.h @@ -27,8 +27,9 @@ int texture_create(const char* name, int width, int height, int format, - int int_fmt, + int internal_format, int type, const void* data); +void texture_resize(int index, int width, int height, const void* data); #endif