From 4a091cea9a5cfdf5bd4da66b90b0140c528441c6 Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Sat, 18 Mar 2017 00:16:12 +0500 Subject: [PATCH] Added toggleable draw modes, GL_TRIANGLES, GL_POINTS and GL_LINES along with initial work on debug rendering --- assets/shaders/debug.frag | 10 ++++++ assets/shaders/debug.vert | 10 ++++++ orgfile.org | 1 + src/game.c | 10 +++--- src/geometry.c | 76 +++++++++++++++++++++++---------------- src/geometry.h | 15 ++++++-- src/model.c | 36 ++++++++----------- src/model.h | 26 +++++++------- src/renderer.c | 41 ++++++++++++++++----- 9 files changed, 145 insertions(+), 80 deletions(-) create mode 100644 assets/shaders/debug.frag create mode 100644 assets/shaders/debug.vert diff --git a/assets/shaders/debug.frag b/assets/shaders/debug.frag new file mode 100644 index 0000000..f752302 --- /dev/null +++ b/assets/shaders/debug.frag @@ -0,0 +1,10 @@ +//include version.glsl + +uniform vec3 wireframe_color; + +out vec4 frag_color; + +void main() +{ + frag_color = vec4(wireframe_color, 1.0); +} diff --git a/assets/shaders/debug.vert b/assets/shaders/debug.vert new file mode 100644 index 0000000..c0d262d --- /dev/null +++ b/assets/shaders/debug.vert @@ -0,0 +1,10 @@ +//include version.glsl + +uniform mat4 mvp; + +in vec3 vPosition; + +void main() +{ + gl_Position = mvp * vec4(vPosition, 1.0); +} diff --git a/orgfile.org b/orgfile.org index e3fde0b..e67dd85 100644 --- a/orgfile.org +++ b/orgfile.org @@ -101,6 +101,7 @@ 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? +** TODO Sprite sheet animations ** DONE Resizable framebuffers and textures - State "DONE" from "TODO" [2017-03-16 Thu 22:50] ** DONE Support for multiple color attachments in framebuffers? diff --git a/src/game.c b/src/game.c index ef4012d..b6da507 100644 --- a/src/game.c +++ b/src/game.c @@ -93,10 +93,9 @@ void scene_setup(void) game_state->player_node = player->node; vec3 viewer_pos = {10, 4, 100}; struct Transform* viewer_tran = entity_component_get(player, C_TRANSFORM); - struct Model* player_model = entity_component_add(player, C_MODEL, "sphere.pamesh", NULL); - vec4 color = {0.f, 1.f, 1.f, 1.f }; - model_set_material_param(player_model, "diffuse_color", &color); - vec4_fill(&color, 1.f, 1.f, 1.f, 1.f); + /* struct Model* player_model = entity_component_add(player, C_MODEL, "sphere.pamesh", NULL); */ + /* model_set_material_param(player_model, "diffuse_color", &color); */ + /* vec4_fill(&color, 1.f, 1.f, 1.f, 1.f); */ transform_set_position(viewer_tran, &viewer_pos); int render_width, render_height; render_width = 1024; @@ -105,7 +104,8 @@ void scene_setup(void) camera_attach_fbo(camera, render_width, render_height, 1, 1, 1); vec4_fill(&camera->clear_color, 0.3f, 0.6f, 0.9f, 1.0f); camera_set_primary_viewer(camera); - + + vec4 color = {0.f, 1.f, 1.f, 1.f }; struct Entity* new_ent = scene_add_new("Model_Entity", NULL); struct Transform* tran = entity_component_get(new_ent, C_TRANSFORM); vec3 position = {0, 0, -5}; diff --git a/src/geometry.c b/src/geometry.c index d782983..f1579c7 100644 --- a/src/geometry.c +++ b/src/geometry.c @@ -16,20 +16,20 @@ struct Geometry { - char* filename; - int draw_indexed; - uint vao; - uint vertex_vbo; - uint uv_vbo; - uint normal_vbo; - uint color_vbo; - uint index_vbo; - int ref_count; - vec3* vertices; - vec3* vertex_colors; - vec3* normals; - vec2* uvs; - uint* indices; + char* filename; + int draw_indexed; + uint vao; + uint vertex_vbo; + uint uv_vbo; + uint normal_vbo; + uint color_vbo; + uint index_vbo; + int ref_count; + vec3* vertices; + vec3* vertex_colors; + vec3* normals; + vec2* uvs; + uint* indices; struct Bounding_Box bounding_box; struct Bounding_Sphere bounding_sphere; }; @@ -37,17 +37,22 @@ struct Geometry /* Data */ static struct Geometry* geometry_list; -static int* empty_indices; +static int* empty_indices; +static GLenum* draw_modes; -static int load_from_file(struct Geometry* geometry, const char* filename); -static void create_vao(struct Geometry* geometry); +static int load_from_file(struct Geometry* geometry, const char* filename); +static void create_vao(struct Geometry* geometry); static struct Geometry* generate_new_index(int* out_new_index); -static void generate_bounding_volume(int geomtry_index); +static void generate_bounding_volume(int geomtry_index); void geom_init(void) { geometry_list = array_new(struct Geometry); empty_indices = array_new(int); + draw_modes = array_new_cap(GLenum, GDM_NUM_DRAWMODES); + draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; + draw_modes[GDM_LINES] = GL_LINES; + draw_modes[GDM_POINTS] = GL_POINTS; } int geom_find(const char* filename) @@ -138,7 +143,12 @@ int geom_create_from_file(const char* name) return index; } -int geom_create(const char* name, vec3* vertices, vec2* uvs, vec3* normals, uint* indices, vec3* vertex_colors) +int geom_create(const char* name, + vec3* vertices, + vec2* uvs, + vec3* normals, + uint* indices, + vec3* vertex_colors) { assert(name && vertices && uvs && normals && indices); int index = -1; @@ -180,12 +190,12 @@ void geom_remove(int index) geometry->ref_count--; if(geometry->ref_count < 0) { - if(geometry->indices) array_free(geometry->indices); - if(geometry->vertices) array_free(geometry->vertices); - if(geometry->uvs) array_free(geometry->uvs); - if(geometry->normals) array_free(geometry->normals); + if(geometry->indices) array_free(geometry->indices); + if(geometry->vertices) array_free(geometry->vertices); + if(geometry->uvs) array_free(geometry->uvs); + if(geometry->normals) array_free(geometry->normals); if(geometry->vertex_colors) array_free(geometry->vertex_colors); - if(geometry->filename) free(geometry->filename); + if(geometry->filename) free(geometry->filename); geometry->indices = NULL; geometry->vertices = NULL; geometry->uvs = NULL; @@ -205,14 +215,14 @@ void geom_cleanup(void) array_free(geometry_list); array_free(empty_indices); + array_free(draw_modes); } static int load_from_file(struct Geometry* geometry, const char* filename) { assert(filename); int success = 1; - char* full_path = str_new("models/"); - full_path = str_concat(full_path, filename); + char* full_path = str_new("models/%s", filename); FILE* file = io_file_open(full_path, "rb"); free(full_path); @@ -334,19 +344,23 @@ static void create_vao(struct Geometry* geometry) glBindVertexArray(0); } -void geom_render(int index) +void geom_render(int index, enum Geometry_Draw_Mode draw_mode) { + assert((int)draw_mode > -1 && draw_mode < GDM_NUM_DRAWMODES); struct Geometry* geo = &geometry_list[index]; glBindVertexArray(geo->vao); if(geo->draw_indexed) - glDrawElements(GL_TRIANGLES, array_len(geo->indices), GL_UNSIGNED_INT, (void*)0); + glDrawElements(draw_modes[draw_mode], array_len(geo->indices), GL_UNSIGNED_INT, (void*)0); else - glDrawArrays(GL_TRIANGLES, 0, array_len(geo->vertices)); + glDrawArrays(draw_modes[draw_mode], 0, array_len(geo->vertices)); glBindVertexArray(0); } -void geom_render_in_frustum(int index, vec4* frustum, struct Transform* transform) +void geom_render_in_frustum(int index, + vec4* frustum, + struct Transform* transform, + enum Geometry_Draw_Mode draw_mode) { struct Geometry* geometry = &geometry_list[index]; int intersection = bv_intersect_frustum_sphere(frustum, &geometry->bounding_sphere, transform); @@ -354,6 +368,6 @@ void geom_render_in_frustum(int index, vec4* frustum, struct Transform* transfor { intersection = bv_intersect_frustum_box(frustum, &geometry->bounding_box, transform); if(intersection == IT_INTERSECT || intersection == IT_INSIDE) - geom_render(index); + geom_render(index, draw_mode); } } diff --git a/src/geometry.h b/src/geometry.h index cfb867c..20b8e79 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -6,13 +6,24 @@ struct Transform; +enum Geometry_Draw_Mode +{ + GDM_TRIANGLES = 0, + GDM_LINES, + GDM_POINTS, + GDM_NUM_DRAWMODES +}; + void geom_init(void); int geom_create_from_file(const char* name); int geom_find(const char* filename); void geom_remove(int index); void geom_cleanup(void); -void geom_render(int index); -void geom_render_in_frustum(int index, vec4* frustum, struct Transform* transform); +void geom_render(int index, enum Geometry_Draw_Mode); +void geom_render_in_frustum(int index, + vec4* frustum, + struct Transform* transform, + enum Geometry_Draw_Mode draw_mode); int geom_create(const char* name, vec3* vertices, vec2* uvs, diff --git a/src/model.c b/src/model.c index 5be6f56..4724fe8 100644 --- a/src/model.c +++ b/src/model.c @@ -1,7 +1,6 @@ #include "model.h" #include "array.h" #include "log.h" -#include "geometry.h" #include "camera.h" #include "entity.h" #include "shader.h" @@ -107,7 +106,7 @@ void model_cleanup(void) array_free(empty_indices); } -void model_render_all(struct Camera* camera) +void model_render_all(struct Camera* camera, enum Geometry_Draw_Mode draw_mode) { static mat4 mvp; struct Material* material_list = material_get_all_materials(); @@ -269,7 +268,7 @@ void model_render_all(struct Camera* camera) /* Render the geometry */ //geom_render_in_frustum(model->geometry_index, &camera->frustum[0], transform); - geom_render(model->geometry_index); + geom_render(model->geometry_index, draw_mode); for(int k = 0; k < array_len(model->material_params); k++) { @@ -341,29 +340,17 @@ int model_get_material_param(struct Model* model, const char* name, void* value_ for(int i = 0; i < array_len(model->material_params); i++) { struct Material_Param* param = &model->material_params[i]; - struct Uniform* uniform = &material->model_params[param->uniform_index]; + struct Uniform* uniform = &material->model_params[param->uniform_index]; if(strcmp(uniform->name, name) == 0) { switch(uniform->type) { - case UT_INT: - *((int*)value_out) = *((int*)param->value); - break; - case UT_FLOAT: - *((float*)value_out) = *((float*)param->value); - break; - case UT_VEC2: - vec2_assign((vec2*)value_out, (vec2*)param->value); - break; - case UT_VEC3: - vec3_assign((vec3*)value_out, (vec3*)param->value); - break; - case UT_VEC4: - vec4_assign((vec4*)value_out, (vec4*)param->value); - break; - case UT_MAT4: - mat4_assign((mat4*)value_out, (mat4*)param->value); - break; + case UT_INT: *((int*)value_out) = *((int*)param->value); break; + case UT_FLOAT: *((float*)value_out) = *((float*)param->value); break; + case UT_VEC2: vec2_assign((vec2*)value_out, (vec2*)param->value); break; + case UT_VEC3: vec3_assign((vec3*)value_out, (vec3*)param->value); break; + case UT_VEC4: vec4_assign((vec4*)value_out, (vec4*)param->value); break; + case UT_MAT4: mat4_assign((mat4*)value_out, (mat4*)param->value); break; } break; /* break for */ success = 1; @@ -371,3 +358,8 @@ int model_get_material_param(struct Model* model, const char* name, void* value_ } return success; } + +struct Model* model_get_all(void) +{ + return model_list; +} diff --git a/src/model.h b/src/model.h index 0c804c6..8e83ebd 100644 --- a/src/model.h +++ b/src/model.h @@ -1,26 +1,28 @@ -#ifndef model_H -#define model_H +#ifndef MODEL_H +#define MODEL_H #include "linmath.h" +#include "geometry.h" struct Camera; struct Material_Param; struct Model { - int node; - int geometry_index; - int material; + int node; + int geometry_index; + int material; struct Material_Param* material_params; }; struct Model* model_get(int index); -void model_init(void); -int model_create(int node, const char* geo_name, const char* material_name); -void model_remove(int index); -void model_cleanup(void); -void model_render_all(struct Camera* camera); -int model_set_material_param(struct Model* model, const char* name, void* value); -int model_get_material_param(struct Model* model, const char* name, void* value_out); +struct Model* model_get_all(void); +void model_init(void); +int model_create(int node, const char* geo_name, const char* material_name); +void model_remove(int index); +void model_cleanup(void); +void model_render_all(struct Camera* camera, enum Geometry_Draw_Mode draw_mode); +int model_set_material_param(struct Model* model, const char* name, void* value); +int model_get_material_param(struct Model* model, const char* name, void* value_out); #endif diff --git a/src/renderer.c b/src/renderer.c index f43e519..dbd7fda 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -16,11 +16,12 @@ #include "game.h" #include "gui.h" -static int def_fbo = -1; -static int def_albedo_tex = -1; -static int def_depth_tex = -1; -static int quad_geo = -1; +static int def_fbo = -1; +static int def_albedo_tex = -1; +static int def_depth_tex = -1; +static int quad_geo = -1; static int composition_shader = -1; +static int debug_shader = -1; static struct Render_Settings settings; #define MAX_GUI_VERTEX_MEMORY 512 * 1024 @@ -108,8 +109,9 @@ void renderer_init(void) 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); */ + framebuffer_set_texture(def_fbo, def_depth_tex, FA_DEPTH_ATTACHMENT); composition_shader = shader_create("fbo.vert", "fbo.frag"); + debug_shader = shader_create("debug.vert", "debug.frag"); } void renderer_draw(void) @@ -135,7 +137,7 @@ void renderer_draw(void) glEnable(GL_CULL_FACE ); glCullFace(GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - model_render_all(camera); + model_render_all(camera, GDM_TRIANGLES); } framebuffer_unbind(); glDisable(GL_DEPTH_TEST); @@ -169,10 +171,34 @@ void renderer_draw(void) struct Camera* active_camera = camera_get_primary(); 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); + geom_render(quad_geo, GDM_TRIANGLES); texture_unbind(final_render_tex); shader_unbind(); + /* Debug Pass */ + shader_bind(debug_shader); + { + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + static vec3 wireframe_color = {0, 1, 0}; + static mat4 mvp; + shader_set_uniform_vec3(debug_shader, "wireframe_color", &wireframe_color); + struct Model* model_list = model_get_all(); + for(int i = 0; i < array_len(model_list); i++) + { + struct Model* model = &model_list[i]; + struct Entity* entity = entity_get(model->node); + struct Transform* transform = entity_component_get(entity, C_TRANSFORM); + int geometry = model->geometry_index; + mat4_identity(&mvp); + mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); + shader_set_uniform_mat4(debug_shader, "mvp", &mvp); + geom_render(geometry, GDM_LINES); + } + } + shader_unbind(); + gui_render(NK_ANTI_ALIASING_ON, settings.max_gui_vertex_memory, settings.max_gui_element_memory); } @@ -192,7 +218,6 @@ void on_framebuffer_size_change(int width, int height) 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); }