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. 225
      src/framebuffer.c
  6. 16
      src/framebuffer.h
  7. 24
      src/game.c
  8. 5
      src/model.c
  9. 3
      src/platform.c
  10. 49
      src/renderer.c
  11. 102
      src/texture.c
  12. 3
      src/texture.h

@ -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!
~~~~~~~~~~~~~~~~~

@ -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

@ -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
{

@ -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

@ -7,13 +7,17 @@
#include <assert.h>
#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, &current_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, &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"
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

@ -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))

@ -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);
}

@ -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);
}
}

@ -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,8 +138,28 @@ 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();
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;
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)

@ -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);
}

@ -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

Loading…
Cancel
Save