a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit 63795490e5ccc2c318b479d4eef189b575ce6c22
parent 4123538cf3d61f523768b99adee70d4322e7eb4f
Author: amin <dev@aminmesbah.com>
Date:   Mon, 10 Jun 2019 01:10:03 +0000

Use a simple render queue

FossilOrigin-Name: 1118b96dc3a3b8da59c10eb5c417e919cd0173457835ca3ea55ee8df5cd55a3f
Diffstat:
Msrc/game.c | 102++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/game.h | 7+++++++
2 files changed, 66 insertions(+), 43 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -5,6 +5,17 @@ #include "collision.c" #include "world.c" +#define RENDER_QUEUE_SIZE 512 +global_variable struct RenderJob g_render_queue[RENDER_QUEUE_SIZE]; +global_variable u32 g_render_queue_count = 0; + +internal void render_job_enqueue(struct RenderJob job) +{ + assert(g_render_queue_count + 1 < RENDER_QUEUE_SIZE); + g_render_queue[g_render_queue_count] = job; + g_render_queue_count++; +} + internal void game_init(struct GameMemory *game_memory, v2u framebuffer) { assert(sizeof(struct GameState) <= game_memory->buffer_size); @@ -198,13 +209,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga viewport.max = math_v2_a(viewport.min, viewport_size); } - glClearColor(0.1f, 0.1f, 0.1f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -#if 0 - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -#else - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif m4 view = math_m4_init_id(); // World origin is in the lower left @@ -241,8 +245,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga // game_render_tiles { - shader_use(&game_state->renderer.shader); - for (size_t y = 0; y < ROOM_TILE_DIM_Y; y++) { for (size_t x = 0; x < ROOM_TILE_DIM_X; x++) @@ -298,12 +300,12 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } } - shader_setv3(&game_state->renderer.shader, "color", &color); - shader_setm4(&game_state->renderer.shader, "model", &model); - shader_setm4(&game_state->renderer.shader, "view", &view); - shader_setm4(&game_state->renderer.shader, "projection", &projection); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + struct RenderJob j = { + .ebo = game_state->renderer.quad_ebo, + .color = color, + .model = model, + }; + render_job_enqueue(j); } } } @@ -573,9 +575,9 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } } - // game_render_player + + // render_player { - shader_use(&game_state->renderer.shader); struct Entity player = game_state->player; m4 model = math_m4_init_id(); @@ -584,13 +586,42 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga v3 color = (v3) { 1.0f, 0.0f, 1.0f }; - shader_setv3(&game_state->renderer.shader, "color", &color); - shader_setm4(&game_state->renderer.shader, "model", &model); - shader_setm4(&game_state->renderer.shader, "view", &view); - shader_setm4(&game_state->renderer.shader, "projection", &projection); + struct RenderJob j = { + .ebo = game_state->renderer.quad_ebo, + .color = color, + .model = model, + }; + render_job_enqueue(j); + + } - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); +#if 0 + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif + shader_use(&game_state->renderer.shader); + shader_setm4(&game_state->renderer.shader, "projection", &projection); + shader_setm4(&game_state->renderer.shader, "view", &view); + for (u32 i = 0; i < g_render_queue_count; i++) + { + struct RenderJob j = g_render_queue[i]; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, j.ebo); + shader_setv3(&game_state->renderer.shader, "color", &j.color); + shader_setm4(&game_state->renderer.shader, "model", &j.model); + if (j.ebo == game_state->renderer.quad_ebo) + { + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + else + { + glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, 0); + } } + + g_render_queue_count = 0; } internal void game_cleanup(struct GameMemory *game_memory) @@ -605,18 +636,6 @@ internal void game_cleanup(struct GameMemory *game_memory) internal void render_debug_quad(struct GameState *game_state, rect r, v3 color, m4 *view, m4 *projection) { - GLint initial_ebo = 0; - // TODO: Remove this potentially expensive call and just track the current - // EBO manually. - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &initial_ebo); - // NOTE(amin): If the GLint we get is less than zero, it will underflow - // when it gets converted to a GLuint as an argument to glBindBuffer. - assert(initial_ebo >= 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, game_state->renderer.rect_ebo); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - shader_use(&game_state->renderer.shader); - v2 dim = {r.max.x - r.min.x, r.max.y - r.min.y}; m4 model = math_m4_init_id(); @@ -624,15 +643,12 @@ internal void render_debug_quad(struct GameState *game_state, rect r, v3 color, model = math_translate(model, (v3) {r.min.x, r.min.y, 0.0f}); model = math_scale(model, (v3) {dim.width, dim.height, 1.0f}); - shader_setv3(&game_state->renderer.shader, "color", &color); - shader_setm4(&game_state->renderer.shader, "model", &model); - shader_setm4(&game_state->renderer.shader, "view", view); - shader_setm4(&game_state->renderer.shader, "projection", projection); - - glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, 0); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, initial_ebo); + struct RenderJob j = { + .ebo = game_state->renderer.rect_ebo, + .color = color, + .model = model, + }; + render_job_enqueue(j); } #ifdef PLATFORM_HOTLOAD_GAME_CODE diff --git a/src/game.h b/src/game.h @@ -29,6 +29,13 @@ static_assert(-1 == ~0, "Implementation doesn't use two's complement"); // One tile is one square meter #define TILE_SIZE 1.0f +struct RenderJob +{ + GLuint ebo; + v3 color; + m4 model; +}; + struct RendererState { GLuint vao;