From ff1c84ddf5ad664c25a64056254de80e548c1d03 Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Fri, 26 Apr 2019 15:23:20 +1000 Subject: [PATCH] Implemented draw order for immediate mode rendering --- src/game/editor.c | 8 ++++---- src/game/game.c | 12 ++++++------ src/game/im_render.c | 29 ++++++++++++++++++++++++++--- src/game/im_render.h | 7 ++++--- src/game/renderer.c | 9 +++++---- src/game/renderer.h | 2 +- todo.txt | 3 +-- 7 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/game/editor.c b/src/game/editor.c index cbe7d11..3f4172c 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -122,7 +122,7 @@ void editor_init(struct Editor* editor) vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); vec4_fill(&editor->tool_mesh_color, 0.f, 0.3f, 1.f, 1.f); vec4_fill(&editor->selected_entity_colour, 0.f, 1.f, 0.f, 1.f); - vec4_fill(&editor->grid_color, 0.3f, 0.3f, 0.3f, 1.f); + vec4_fill(&editor->grid_color, 0.3f, 0.3f, 0.3f, 0.5f); debug_vars_list = array_new(struct Debug_Variable); empty_indices = array_new(int); @@ -187,7 +187,7 @@ void editor_render(struct Editor* editor, struct Camera * active_camera) transform_get_absolute_rot(editor->selected_entity, &rotation); } - im_begin(position, rotation, scale, editor->grid_color, GDM_LINES); + im_begin(position, rotation, scale, editor->grid_color, GDM_LINES, 0); float half_grid = editor->grid_num_lines * editor->grid_scale / 2.f; for(float i = 0; i <= editor->grid_num_lines * editor->grid_scale; i += editor->grid_scale) @@ -432,10 +432,10 @@ void editor_update(struct Editor* editor, float dt) { if(editor->current_mode == EDITOR_MODE_TRANSLATE) { - im_sphere(0.5f, editor->tool_mesh_position, (quat) { 0.f, 0.f, 0.f, 1.f }, editor->tool_mesh_color, GDM_TRIANGLES); + im_sphere(0.5f, editor->tool_mesh_position, (quat) { 0.f, 0.f, 0.f, 1.f }, editor->tool_mesh_color, GDM_TRIANGLES, 2); //im_box(editor->grid_scale, editor->grid_scale, editor->grid_scale, editor->tool_mesh_position, (quat) { 0.f, 0.f, 0.f, 1.f }, editor->tool_mesh_color, GDM_TRIANGLES); - im_begin(editor->tool_mesh_position, (quat) { 0.f, 0.f, 0.f, 1.f }, (vec3) { 1.f, 1.f, 1.f }, (vec4) { 0.f, 1.f, 1.f, 1.f }, GDM_LINES); + im_begin(editor->tool_mesh_position, (quat) { 0.f, 0.f, 0.f, 1.f }, (vec3) { 1.f, 1.f, 1.f }, (vec4) { 0.f, 1.f, 1.f, 1.f }, GDM_LINES, 3); switch(editor->current_axis) { case EDITOR_AXIS_XZ: diff --git a/src/game/game.c b/src/game/game.c index 754a789..128bdb6 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -408,7 +408,7 @@ void game_debug(float dt) quat im_rot = { 0.f, 0.f, 0.f, 1.f }; vec4 im_color = { 0.f, 1.f, 1.f, 1.f }; quat_identity(&im_rot); - im_begin(im_position, im_rot, im_scale, im_color, GL_LINES); + im_begin(im_position, im_rot, im_scale, im_color, GDM_LINES, 1); im_pos(0.f, 0.f, 0.f); im_pos(100.f, 100.f, 10.f); @@ -419,7 +419,7 @@ void game_debug(float dt) im_color.x = 1.f; im_color.y = 0.f; - im_begin(im_position, im_rot, im_scale, im_color, GL_TRIANGLES); + im_begin(im_position, im_rot, im_scale, im_color, GL_TRIANGLES, 1); float length = 200.f; @@ -458,7 +458,7 @@ void game_debug(float dt) im_end(); im_position.x = -30.f; - im_begin(im_position, im_rot, im_scale, im_color, GL_LINES); + im_begin(im_position, im_rot, im_scale, im_color, GL_LINES, 1); im_pos(0.f, 0.f, 0.f); im_pos(0.f, 0.f, 10.f); @@ -475,12 +475,12 @@ void game_debug(float dt) im_end(); vec4 prim_color = {1.f, 1.f, 0.f, 1.f}; - im_box(5.f, 2.f, 10.f, im_position, im_rot, prim_color, GDM_TRIANGLES); + im_box(5.f, 2.f, 10.f, im_position, im_rot, prim_color, GDM_TRIANGLES, 1); for(int i = 0; i < 10; i++) { im_position.x += i * 2.f; - im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES); + im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES, 1); } } @@ -1868,7 +1868,7 @@ void game_debug_gui(float dt) void game_render(void) { - renderer_draw(game_state->renderer, game_state->scene); + renderer_render(game_state->renderer, game_state->scene); } void game_cleanup(void) diff --git a/src/game/im_render.c b/src/game/im_render.c index 00bc028..4b29039 100755 --- a/src/game/im_render.c +++ b/src/game/im_render.c @@ -9,6 +9,7 @@ #include "geometry.h" #include +#include #define MAX_IM_VERTICES 2048 #define MAX_IM_GEOMETRIES (MAX_IM_VERTICES / 2) @@ -29,6 +30,7 @@ static struct IM_Geom* active_geom = NULL; static int active_vertex_index = 0; static void im_geom_reset(struct IM_Geom* geom); +static int im_sort_func(const void* p1, const void* p2); void im_init(void) { @@ -74,7 +76,7 @@ void im_cleanup(void) IM_State.im_shader = -1; } -void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode) +void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode, int draw_order) { if(active_geom) { @@ -87,6 +89,7 @@ void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mod active_geom->start_index = IM_State.curr_vertex; active_geom->type = IGT_DYNAMIC; active_geom->draw_mode = draw_mode; + active_geom->draw_order = draw_order; vec3_assign(&active_geom->position, &position); vec3_assign(&active_geom->scale, &scale); vec4_assign(&active_geom->color, &color); @@ -105,7 +108,7 @@ void im_pos(float x, float y, float z) active_vertex_index++; } -void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode) +void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order) { if(active_geom) { @@ -117,6 +120,7 @@ void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, im_geom_reset(active_geom); active_geom->type = IGT_PRIMITIVE; active_geom->draw_mode = draw_mode; + active_geom->draw_order = draw_order; active_geom->prim_geom_index = geom_create_from_file("cube.symbres"); vec3_assign(&active_geom->position, &position); vec3 scale = { x, y, z}; @@ -126,7 +130,7 @@ void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, active_geom = NULL; } -void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode) +void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order) { if(active_geom) { @@ -138,6 +142,7 @@ void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_ im_geom_reset(active_geom); active_geom->type = IGT_PRIMITIVE; active_geom->draw_mode = draw_mode; + active_geom->draw_order = draw_order; active_geom->prim_geom_index = geom_create_from_file("sphere.symbres"); vec3_assign(&active_geom->position, &position); vec3 scale = { radius, radius, radius }; @@ -167,6 +172,10 @@ void im_render(struct Camera* active_viewer) if(IM_State.curr_geom == -1) return; + /* Sort by draw order, geometries with lower draw order get drawn first */ + if(IM_State.curr_geom + 1 > 1) + qsort(IM_State.geometries, IM_State.curr_geom + 1, sizeof(struct IM_Geom), &im_sort_func); + shader_bind(IM_State.im_shader); { static mat4 mvp, translation, rotation, scale; @@ -224,4 +233,18 @@ void im_geom_reset(struct IM_Geom* geom) geom->num_vertices = 0; geom->prim_geom_index = -1; geom->draw_mode = -1; + geom->draw_order = -1; } + +int im_sort_func(const void* p1, const void* p2) +{ + struct IM_Geom* g1 = (struct IM_Geom*)p1; + struct IM_Geom* g2 = (struct IM_Geom*)p2; + if(g1->draw_order < g2->draw_order) + return -1; + else if(g1->draw_order == g2->draw_order) + return 0; + else + return 1; +} + diff --git a/src/game/im_render.h b/src/game/im_render.h index 8608cf9..6e3947c 100755 --- a/src/game/im_render.h +++ b/src/game/im_render.h @@ -32,16 +32,17 @@ struct IM_Geom }; int draw_mode; + int draw_order; }; struct Camera; void im_init(void); void im_cleanup(void); -void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode); +void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode, int draw_order); void im_pos(float x, float y, float z); -void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode); -void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode); +void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order); +void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order); void im_end(void); void im_render(struct Camera* active_viewer); diff --git a/src/game/renderer.c b/src/game/renderer.c index 3a19419..e99f79a 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -144,7 +144,7 @@ void renderer_init(struct Renderer* renderer) } } -void renderer_draw(struct Renderer* renderer, struct Scene* scene) +void renderer_render(struct Renderer* renderer, struct Scene* scene) { /* Render each camera output into it's framebuffer or to the default framebuffer */ for(int i = 0; i < MAX_CAMERAS; i++) @@ -394,14 +394,14 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene) case CST_SPHERE: { float radius = physics_cs_sphere_radius_get(mesh->collision.collision_shape); - im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES); + im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES, 1); } break; case CST_BOX: { float x = 0.f, y = 0.f, z = 0.f; physics_cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z); - im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES); + im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES, 1); }; break; default: break; @@ -442,12 +442,13 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene) quat abs_rot; transform_get_absolute_position(game_state->editor->selected_entity, &abs_pos); transform_get_absolute_rot(game_state->editor->selected_entity, &abs_rot); - im_sphere(1.f, abs_pos, abs_rot, game_state->editor->selected_entity_colour, GDM_TRIANGLES); + im_sphere(1.f, abs_pos, abs_rot, game_state->editor->selected_entity_colour, GDM_TRIANGLES, 1); } } } //Immediate mode geometry render + // Maybe try binding the old frame buffer, clear the drawing but let the depth buffer remain to check depth? im_render(active_camera); /* Render 2D stuff */ diff --git a/src/game/renderer.h b/src/game/renderer.h index 7836c80..3cb50fd 100755 --- a/src/game/renderer.h +++ b/src/game/renderer.h @@ -52,7 +52,7 @@ struct Renderer }; void renderer_init(struct Renderer* renderer); -void renderer_draw(struct Renderer* renderer, struct Scene* scene); +void renderer_render(struct Renderer* renderer, struct Scene* scene); void renderer_cleanup(struct Renderer* renderer); void renderer_clearcolor_set(float r, float g, float b, float a); void renderer_debug_draw_enabled(struct Renderer* renderer, bool enabled); diff --git a/todo.txt b/todo.txt index 7bc33b9..7d2aa6b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,4 @@ Todo: - - Add pre-render/post-render steps to deal with render order issues and culling lights before rendering - - Immediate mode render order, drawing axis and helpers on top of grid - Better, more accurate picking - Highlight if we are about to select an entity or perform the tool action like translate when mouse is hovered and an entity can be selected at that location - Display the projected position if we perform the action for example display what the new location would be right next to the tool mesh @@ -238,4 +236,5 @@ Done: * Display editor camera parameter adjustment in top bar * Display Transform mode selection in top bar * Display Axis selection in top bar + * Immediate mode render order, drawing axis and helpers on top of grid