Added support for resizeable framebuffers and textures. Improved management of textures/renderbuffers attached to framebuffers

dev
Shariq Shah 9 years ago
parent 19da9025a5
commit 6909a1cda6
  1. 85
      README
  2. 11
      orgfile.org
  3. 14
      src/camera.c
  4. 7
      src/camera.h
  5. 203
      src/framebuffer.c
  6. 16
      src/framebuffer.h
  7. 24
      src/game.c
  8. 1
      src/model.c
  9. 3
      src/platform.c
  10. 43
      src/renderer.c
  11. 68
      src/texture.c
  12. 3
      src/texture.h

@ -54,20 +54,24 @@ _________________
.. 2.38 TODO Physics/Collision detection in 2d .. 2.38 TODO Physics/Collision detection in 2d
.. 2.39 TODO Complete gui integration .. 2.39 TODO Complete gui integration
.. 2.40 TODO Allow passsing base path as commandline argument? .. 2.40 TODO Allow passsing base path as commandline argument?
.. 2.41 TODO Validate necessary assets at game launch .. 2.41 DONE Resizable framebuffers and textures
.. 2.42 TODO Variant type .. 2.42 DONE Support for multiple color attachments in framebuffers?
.. 2.43 TODO Log and debug/stats output in gui .. 2.43 TODO Multisampled textures and framebuffers
.. 2.44 TODO Editor .. 2.44 DONE Better way to store and manage textures attached to framebuffers
.. 2.45 TODO Event Subsystem .. 2.45 TODO Validate necessary assets at game launch
.. 2.46 TODO Keybindings for gui? .. 2.46 TODO Variant type
.. 2.47 DONE Compile and test on windows .. 2.47 TODO Log and debug/stats output in gui
.. 2.48 TODO Array based string type comptible with cstring(char*) .. 2.48 TODO Editor
.. 2.49 DONE Fix mouse bugs .. 2.49 TODO Event Subsystem
.. 2.50 DONE Fix .. 2.50 TODO Keybindings for gui?
.. 2.51 TODO issues with opengl context showing 2.1 only .. 2.51 DONE Compile and test on windows
.. 2.52 TODO Improve this readme .. 2.52 TODO Array based string type comptible with cstring(char*)
.. 2.53 TODO ??? .. 2.53 DONE Fix mouse bugs
.. 2.54 TODO Profit! .. 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 1 Project Symmetry
@ -325,8 +329,7 @@ _________________
2.39 TODO Complete gui integration 2.39 TODO Complete gui integration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Font selection x Font selection x Font atlas proper cleanup
- Font atlas proper cleanup
- Decoupled event handling of gui and input if possible - Decoupled event handling of gui and input if possible
- Custom rendering for gui - 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] - 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] - 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] - 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!
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

@ -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 Fix mouse bugs on windows
** TODO Physics/Collision detection in 2d ** TODO Physics/Collision detection in 2d
** TODO Complete gui integration ** TODO Complete gui integration
- Font selection x Font selection
- Font atlas proper cleanup x Font atlas proper cleanup
- Decoupled event handling of gui and input if possible - Decoupled event handling of gui and input if possible
- Custom rendering for gui - Custom rendering for gui
** TODO Allow passsing base path as commandline argument? ** 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 Validate necessary assets at game launch
** TODO Variant type ** TODO Variant type
** TODO Log and debug/stats output in gui ** TODO Log and debug/stats output in gui

@ -127,7 +127,12 @@ void camera_update_proj(struct Camera* camera)
camera_update_view_proj(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); assert(width > 0 && height > 0 && camera);
if(camera->fbo != -1) 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!"); log_error("camera:attach_fbo", "Camera already has fbo attached!");
return; 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) if(camera->fbo > -1)
{ {
char tex_name[128]; 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_MODE, GL_COMPARE_REF_TO_TEXTURE);
texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 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, FA_COLOR_ATTACHMENT0);
framebuffer_set_texture(camera->fbo, camera->render_tex, GL_COLOR_ATTACHMENT0); framebuffer_set_texture(camera->fbo, camera->depth_tex, FA_DEPTH_ATTACHMENT);
framebuffer_set_texture(camera->fbo, camera->depth_tex, GL_DEPTH_ATTACHMENT);
} }
else else
{ {

@ -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_proj(struct Camera* camera);
void camera_update_view(struct Camera* camera); void camera_update_view(struct Camera* camera);
void camera_update_proj(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); void camera_set_primary_viewer(struct Camera* camera);
#endif #endif

@ -7,13 +7,17 @@
#include <assert.h> #include <assert.h>
#define MAX_TEXTURE_ATTACHMENTS 3 /* Pointless define just to avoid VLA's and be compatible with msvc */
struct FBO struct FBO
{ {
uint handle; uint handle;
uint renderbuffer; uint depth_renderbuffer;
int texture; uint color_renderbuffer;
int texture_attachments[MAX_TEXTURE_ATTACHMENTS];
int width; int width;
int height; int height;
int resizeable;
}; };
struct FBO* fbo_list; struct FBO* fbo_list;
@ -34,36 +38,50 @@ void framebuffer_cleanup(void)
array_free(empty_indices); 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; int index = -1;
GLuint fbo; GLuint fbo = 0;
GLuint renderbuffer; GLuint depth_renderbuffer = 0;
GLuint color_renderbuffer = 0;
glGenFramebuffers(1, &fbo); glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenRenderbuffers(1, &renderbuffer); if(has_depth)
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); {
glGenRenderbuffers(1, &depth_renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT,
width, width,
height); height);
renderer_check_glerror("framebuffer:create"); renderer_check_glerror("framebuffer:create:depth_renderbuffer");
glFramebufferRenderbuffer(GL_FRAMEBUFFER, glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, GL_RENDERBUFFER,
renderbuffer); depth_renderbuffer);
renderer_check_glerror("framebuffer:create"); renderer_check_glerror("framebuffer:create:depth_renderbuffer");
if(has_color) glBindRenderbuffer(GL_RENDERBUFFER, 0);
{
glDrawBuffer(GL_COLOR_ATTACHMENT0);
} }
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"); renderer_check_glerror("framebuffer:create");
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) if(status != GL_FRAMEBUFFER_COMPLETE)
@ -86,15 +104,15 @@ int framebuffer_create(int width, int height, int has_depth, int has_color)
} }
framebuffer->handle = fbo; framebuffer->handle = fbo;
framebuffer->renderbuffer = renderbuffer; framebuffer->depth_renderbuffer = depth_renderbuffer;
framebuffer->texture = -1; framebuffer->color_renderbuffer = color_renderbuffer;
framebuffer->width = width; framebuffer->width = width;
framebuffer->height = height; 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"); log_message("Framebuffer created successfully");
} }
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
return index; return index;
} }
@ -102,15 +120,32 @@ void framebuffer_bind(int index)
{ {
assert(index < array_len(fbo_list) && index > -1); assert(index < array_len(fbo_list) && index > -1);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_list[index].handle); 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) void framebuffer_remove(int index)
{ {
assert(index < array_len(fbo_list) && index > -1); assert(index < array_len(fbo_list) && index > -1);
struct FBO* fbo = &fbo_list[index]; struct FBO* fbo = &fbo_list[index];
if(fbo->texture != -1) texture_remove(fbo->texture); for(int i = 0; i < FA_NUM_ATTACHMENTS; i++)
glDeleteRenderbuffers(1, &fbo->renderbuffer); {
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); 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) void framebuffer_unbind(void)
@ -130,34 +165,49 @@ int framebuffer_get_height(int index)
return fbo_list[index].height; 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); 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; GLint current_fbo = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
renderer_check_glerror("framebuffer:set_texture:glGet"); renderer_check_glerror("framebuffer:set_texture:glGet");
framebuffer_bind(index); framebuffer_bind(index);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
attachment, gl_attachment,
GL_TEXTURE_2D, GL_TEXTURE_2D,
texture_get_texture_handle(texture), texture_get_texture_handle(texture),
0); 0);
/* if(!renderer_check_glerror("framebuffer:set_texture:glFramebuffertexture")) */ renderer_check_glerror("framebuffer:set_texture:glFramebuffertexture2d");
/* { */ fbo->texture_attachments[attachment] = texture;
/* int current_fbo_tex = fbo_list[index].texture; */ if(attachment == FA_COLOR_ATTACHMENT0) glDrawBuffer(GL_COLOR_ATTACHMENT0);
/* if(current_fbo_tex > -1) */
/* texture_remove(current_fbo_tex); */
/* fbo_list[index].texture = texture; */
/* texture_inc_refcount(texture); */
/* } */
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo); 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); assert(index < array_len(fbo_list) &&
return fbo_list[index].texture; index > -1 &&
attachment < FA_NUM_ATTACHMENTS &&
(int)attachment > -1);
return fbo_list[index].texture_attachments[attachment];
} }
uint framebuffer_get_gl_handle(int index) 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); assert(index < array_len(fbo_list) && index > -1);
return fbo_list[index].handle; 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, &current_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;
}

@ -3,16 +3,26 @@
#include "num_types.h" #include "num_types.h"
enum Framebuffer_Attachment
{
FA_COLOR_ATTACHMENT0 = 0,
FA_DEPTH_ATTACHMENT,
FA_NUM_ATTACHMENTS
};
void framebuffer_init(void); void framebuffer_init(void);
void framebuffer_cleanup(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_bind(int index);
void framebuffer_remove(int index); void framebuffer_remove(int index);
void framebuffer_unbind(void); void framebuffer_unbind(void);
int framebuffer_get_width(int index); int framebuffer_get_width(int index);
int framebuffer_get_height(int index); int framebuffer_get_height(int index);
void framebuffer_set_texture(int index, int texture, int attachment); void framebuffer_set_texture(int index, int texture, enum Framebuffer_Attachment attachment);
int framebuffer_get_texture(int index); int framebuffer_get_texture(int index, enum Framebuffer_Attachment attachment);
uint framebuffer_get_gl_handle(int index); 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 #endif

@ -102,7 +102,7 @@ void scene_setup(void)
render_width = 1024; render_width = 1024;
render_height = 768; render_height = 768;
struct Camera* camera = entity_component_add(player, C_CAMERA, render_width, render_height); 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); vec4_fill(&camera->clear_color, 0.3f, 0.6f, 0.9f, 1.0f);
camera_set_primary_viewer(camera); camera_set_primary_viewer(camera);
@ -151,16 +151,16 @@ void scene_setup(void)
transform_set_position(ground_tran, &pos); transform_set_position(ground_tran, &pos);
transform_scale(ground_tran, &scale_ground); transform_scale(ground_tran, &scale_ground);
/* struct Entity* screen = scene_add_new("Screen", NULL); */ struct Entity* screen = scene_add_new("Screen", NULL);
/* struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); */ struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL);
/* screen_model->geometry_index = geom_find("Quad"); */ screen_model->geometry_index = geom_find("Quad");
/* struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); */ 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); */ struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM);
/* transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); */ transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD);
/* struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); */ struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50);
/* camera_attach_fbo(cam, 50, 50, 1, 1); */ 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_color", &color);
/* model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); */ model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex);
const int MAX_LIGHTS = 3; const int MAX_LIGHTS = 3;
for(int i = 0; i < MAX_LIGHTS; i++) 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) if(offset.x != 0 || offset.y != 0 || offset.z != 0)
{ {
transform_translate(transform, &offset, TS_LOCAL); 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)) if(input_key_state_get(KEY_SPACE, KS_PRESSED))

@ -21,7 +21,6 @@
static struct Model* model_list; static struct Model* model_list;
static int* empty_indices; static int* empty_indices;
static int use_blinn = 1;
struct Model* model_get(int index) struct Model* model_get(int index)
{ {

@ -223,9 +223,8 @@ void platform_poll_events(int* out_quit)
} }
case SDL_WINDOWEVENT: 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); platform_state->on_windowresize_func(event.window.data1, event.window.data2);
} }
} }

@ -23,6 +23,9 @@ static int quad_geo = -1;
static int composition_shader = -1; static int composition_shader = -1;
static struct Render_Settings settings; 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 on_framebuffer_size_change(int width, int height);
void renderer_init(void) void renderer_init(void)
@ -39,8 +42,8 @@ void renderer_init(void)
settings.fog.max_dist = 150.f; 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.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); vec3_fill(&settings.ambient_light, 0.1f, 0.1f, 0.12f);
settings.max_gui_vertex_memory = 512 * 1024; settings.max_gui_vertex_memory = MAX_GUI_VERTEX_MEMORY;
settings.max_gui_element_memory = 128 * 1024; settings.max_gui_element_memory = MAX_GUI_ELEMENT_MEMORY;
gui_init(); gui_init();
@ -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_MODE, GL_COMPARE_REF_TO_TEXTURE);
texture_set_param(def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); texture_set_param(def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
def_fbo = framebuffer_create(width, height, 1, 1); def_fbo = framebuffer_create(width, height, 1, 0, 1);
framebuffer_set_texture(def_fbo, def_albedo_tex, GL_COLOR_ATTACHMENT0); framebuffer_set_texture(def_fbo, def_albedo_tex, FA_COLOR_ATTACHMENT0);
framebuffer_set_texture(def_fbo, def_depth_tex, GL_DEPTH_ATTACHMENT); /* framebuffer_set_texture(def_fbo, def_depth_tex, GL_DEPTH_ATTACHMENT); */
composition_shader = shader_create("fbo.vert", "fbo.frag"); composition_shader = shader_create("fbo.vert", "fbo.frag");
} }
@ -118,11 +121,11 @@ void renderer_draw(void)
if(camera->node < 0) if(camera->node < 0)
continue; continue;
/* if(camera->fbo == -1) continue; */
int fbo = camera->fbo == -1 ? def_fbo : camera->fbo; int fbo = camera->fbo == -1 ? def_fbo : camera->fbo;
framebuffer_bind(fbo); framebuffer_bind(fbo);
{ {
glViewport(0, 0, framebuffer_get_width(fbo), framebuffer_get_height(fbo)); glViewport(0, 0, framebuffer_get_width(fbo), framebuffer_get_height(fbo));
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glClearColor(camera->clear_color.x, glClearColor(camera->clear_color.x,
@ -135,8 +138,28 @@ void renderer_draw(void)
model_render_all(camera); model_render_all(camera);
} }
framebuffer_unbind(); 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; int width, height;
struct Game_State* game_state = game_state_get(); struct Game_State* game_state = game_state_get();
window_get_size(game_state->window, &width, &height); window_get_size(game_state->window, &width, &height);
@ -147,12 +170,10 @@ void renderer_draw(void)
int final_render_tex = active_camera->render_tex == -1 ? def_albedo_tex : active_camera->render_tex; int final_render_tex = active_camera->render_tex == -1 ? def_albedo_tex : active_camera->render_tex;
texture_bind(final_render_tex); texture_bind(final_render_tex);
geom_render(quad_geo); geom_render(quad_geo);
shader_unbind();
texture_unbind(final_render_tex); 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); 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) void renderer_cleanup(void)
@ -167,10 +188,12 @@ void renderer_cleanup(void)
void on_framebuffer_size_change(int width, int height) void on_framebuffer_size_change(int width, int height)
{ {
glViewport(0, 0, width, 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; float aspect = (float)width / (float)height;
camera->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f; camera->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f;
camera_update_proj(camera); 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) void renderer_set_clearcolor(float red, float green, float blue, float alpha)

@ -17,6 +17,9 @@ struct Texture
uint handle; uint handle;
int ref_count; int ref_count;
int texture_unit; int texture_unit;
GLenum format;
GLint internal_format;
GLenum type;
}; };
#pragma pack(push, 1) #pragma pack(push, 1)
@ -42,10 +45,10 @@ static int* empty_indices;
#define MAX_PIXEL_BYTES 5 #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 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 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) void texture_init(void)
{ {
@ -64,22 +67,21 @@ int texture_create_from_file(const char* filename, int texture_unit)
return index; return index;
} }
/* If texture not already loaded then try to load it */ /* If texture not already loaded then try to load it */
char* full_path = str_new("textures/"); char* full_path = str_new("textures/%s", filename);
full_path = str_concat(full_path, filename);
FILE* file = io_file_open(full_path, "rb"); FILE* file = io_file_open(full_path, "rb");
int img_load_success = -1; int img_load_success = -1;
if(file) if(file)
{ {
/* Load texture here */ /* Load texture here */
int width, height, int_fmt, fmt; int width, height, internal_format, fmt;
GLubyte* img_data = NULL; GLubyte* img_data = NULL;
width = height = int_fmt = fmt = -1; width = height = internal_format = fmt = -1;
img_load_success = load_img(file, &img_data, &width, &height, &fmt, &int_fmt); img_load_success = load_img(file, &img_data, &width, &height, &fmt, &internal_format);
if(img_load_success) 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) if(index > -1)
{ {
texture_set_param(index, GL_TEXTURE_MIN_FILTER, GL_LINEAR); texture_set_param(index, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -118,6 +120,9 @@ void texture_remove(int index)
texture->name = NULL; texture->name = NULL;
texture->ref_count = -1; texture->ref_count = -1;
texture->texture_unit = -1; texture->texture_unit = -1;
texture->format = -1;
texture->internal_format = -1;
texture->type = -1;
array_push(empty_indices, index, int); array_push(empty_indices, index, int);
} }
} }
@ -162,7 +167,7 @@ void texture_unbind(int index)
glBindTexture(GL_TEXTURE_2D, 0); 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; int success = 0;
struct Tga_Header header; struct Tga_Header header;
@ -278,12 +283,11 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt
} }
} }
} }
//debug_write_tga(&header, *image_data); //debug_write_tga(&header, *image_data);
*height = header.height; *height = header.height;
*width = header.width; *width = header.width;
*fmt = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; *fmt = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA;
*internal_fmt = *fmt; *internal_format = *fmt;
success = 1; success = 1;
} }
} }
@ -372,14 +376,14 @@ int texture_create(const char* name,
int width, int width,
int height, int height,
int format, int format,
int int_fmt, int internal_format,
int type, int type,
const void* data) const void* data)
{ {
assert(name && texture_unit > -1 && texture_unit <= TU_SHADOWMAP4); assert(name && texture_unit > -1 && texture_unit <= TU_SHADOWMAP4);
int index = -1; int index = -1;
uint handle = 0; 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) if(success)
{ {
struct Texture* new_tex = NULL; struct Texture* new_tex = NULL;
@ -398,11 +402,20 @@ int texture_create(const char* name,
new_tex->handle = handle; new_tex->handle = handle;
new_tex->ref_count = 1; new_tex->ref_count = 1;
new_tex->texture_unit = texture_unit; new_tex->texture_unit = texture_unit;
new_tex->format = format;
new_tex->internal_format = internal_format;
new_tex->type = type;
} }
return index; 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; int success = 1;
glGenTextures(1, out_handle); glGenTextures(1, out_handle);
@ -413,10 +426,35 @@ int create_gl_texture(uint* out_handle, int width, int height, int format, int i
else else
{ {
glBindTexture(GL_TEXTURE_2D, *out_handle); 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")) if(renderer_check_glerror("texture:create_gl_texture:glTexImage2d"))
success = 0; success = 0;
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
return success; 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);
}

@ -27,8 +27,9 @@ int texture_create(const char* name,
int width, int width,
int height, int height,
int format, int format,
int int_fmt, int internal_format,
int type, int type,
const void* data); const void* data);
void texture_resize(int index, int width, int height, const void* data);
#endif #endif

Loading…
Cancel
Save