commit bd88d22d902bd6e582766d4b5681a4e7a9386e82
parent 63795490e5ccc2c318b479d4eef189b575ce6c22
Author: amin <dev@aminmesbah.com>
Date: Mon, 10 Jun 2019 01:59:33 +0000
Split rendering code into module
FossilOrigin-Name: e2a20963b3ca6477eb7b824ee5f27b9d6279e0d1cf6ace008b2d8db15866ec08
Diffstat:
M | src/game.c | | | 136 | ++++++++++--------------------------------------------------------------------- |
M | src/game.h | | | 18 | +----------------- |
M | src/memory.c | | | 1 | + |
A | src/render.c | | | 125 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/render.h | | | 21 | +++++++++++++++++++++ |
5 files changed, 164 insertions(+), 137 deletions(-)
diff --git a/src/game.c b/src/game.c
@@ -3,19 +3,9 @@
#include "shader.c"
#include "memory.c"
#include "collision.c"
+#include "render.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);
@@ -109,57 +99,9 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
}
}
- // set up and load tiles
- {
- GLfloat quad_vertices[] = {
- 0.5f, 0.5f,
- 0.5f, -0.5f,
- -0.5f, -0.5f,
- -0.5f, 0.5f,
- };
-
- GLuint quad_elements[] = { 0, 1, 3, 1, 2, 3 };
- GLuint rect_elements[] = { 0, 1, 1, 2, 2, 3, 3, 0 };
-
- GLuint vao;
- GLuint quad_vbo;
- GLuint quad_ebo;
- GLuint rect_ebo;
- glGenVertexArrays(1, &vao);
- glGenBuffers(1, &quad_vbo);
- glGenBuffers(1, &quad_ebo);
- glGenBuffers(1, &rect_ebo);
-
- // NOTE(amin): We will leave this bound for the duration of the game.
- // There should not be any calls to glBindVertexArray(0).
- glBindVertexArray(vao);
-
- glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW);
- glVertexAttribPointer(
- 0, // Data location
- 2, // Number of values
- GL_FLOAT, // Data type
- GL_FALSE, // Normalize data
- 2 * sizeof(GLfloat), // Stride
- (GLvoid*)0 // Position data offset (0)
- );
-
- glEnableVertexAttribArray(0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_elements), quad_elements, GL_STATIC_DRAW);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rect_ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rect_elements), rect_elements, GL_STATIC_DRAW);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ebo);
-
- game_state->renderer.vao = vao;
- game_state->renderer.quad_vbo = quad_vbo;
- game_state->renderer.quad_ebo = quad_ebo;
- game_state->renderer.rect_ebo = rect_ebo;
- }
+ render_init(&game_state->renderer, &game_state->world_allocator);
+ // game_shader_load
{
struct PlatformApi platform = game_memory->platform;
char *v_source = platform.platform_read_entire_file("shader/main_v.glsl");
@@ -216,9 +158,10 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
view = math_scale(view, (v3) {1.0f, -1.0f, 1.0f});
view = math_translate(view, (v3) {viewport.min.x, viewport.min.y, 0.0f});
view = math_scale(view, (v3) {ppm, ppm, 1.0f});
+ game_state->renderer.view = view;
// Screen origin is in the upper left
- m4 projection = math_projection_ortho(0.0f, framebuffer.width, framebuffer.height, 0.0f, -1.0f, 0.0f);
+ game_state->renderer.projection = math_projection_ortho(0.0f, framebuffer.width, framebuffer.height, 0.0f, -1.0f, 0.0f);
v2i current_room_i = game_state->player.pos.room;
struct Room *r = world_room_get(game_state->world, current_room_i);
@@ -305,7 +248,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
.color = color,
.model = model,
};
- render_job_enqueue(j);
+ render_job_enqueue(&game_state->renderer, j);
}
}
}
@@ -363,7 +306,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
// game_detect_collisions
{
-#define RENDER_COLLISION_DEBUG_QUAD(r, c) render_debug_quad(game_state, (r), (c), &view, &projection);
+#define RENDER_COLLISION_DEBUG_QUAD(r, c) render_debug_quad(&game_state->renderer, (r), (c));
v2 player_delta = math_v2f_m(player->velocity, dt);
v2 new_p = math_v2_a(player->pos.local, player_delta);
@@ -575,7 +518,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
}
}
-
// render_player
{
struct Entity player = game_state->player;
@@ -586,69 +528,23 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
v3 color = (v3) { 1.0f, 0.0f, 1.0f };
- struct RenderJob j = {
- .ebo = game_state->renderer.quad_ebo,
- .color = color,
- .model = model,
- };
- render_job_enqueue(j);
-
- }
-
- 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);
- }
+ render_job_enqueue(
+ &game_state->renderer,
+ (struct RenderJob) {
+ .ebo = game_state->renderer.quad_ebo,
+ .color = color,
+ .model = model,
+ });
}
- g_render_queue_count = 0;
+ render_jobs(&game_state->renderer);
}
internal void game_cleanup(struct GameMemory *game_memory)
{
assert(sizeof(struct GameState) <= game_memory->buffer_size);
struct GameState *game_state = (struct GameState *)game_memory->buffer;
- glDeleteVertexArrays(1, &game_state->renderer.vao);
- glDeleteBuffers(1, &game_state->renderer.quad_vbo);
- glDeleteBuffers(1, &game_state->renderer.quad_ebo);
- glDeleteBuffers(1, &game_state->renderer.rect_ebo);
-}
-
-internal void render_debug_quad(struct GameState *game_state, rect r, v3 color, m4 *view, m4 *projection)
-{
- v2 dim = {r.max.x - r.min.x, r.max.y - r.min.y};
-
- m4 model = math_m4_init_id();
- model = math_translate(model, (v3) {dim.x * 0.5f, dim.y * 0.5f, 0.0f});
- model = math_translate(model, (v3) {r.min.x, r.min.y, 0.0f});
- model = math_scale(model, (v3) {dim.width, dim.height, 1.0f});
-
- struct RenderJob j = {
- .ebo = game_state->renderer.rect_ebo,
- .color = color,
- .model = model,
- };
- render_job_enqueue(j);
+ render_cleanup(&game_state->renderer);
}
#ifdef PLATFORM_HOTLOAD_GAME_CODE
diff --git a/src/game.h b/src/game.h
@@ -21,6 +21,7 @@
#include "am_math.h"
#include "shader.h"
#include "memory.h"
+#include "render.h"
#include "world.h"
#include "platform.h"
@@ -29,22 +30,6 @@ 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;
- GLuint quad_vbo;
- GLuint quad_ebo;
- GLuint rect_ebo;
- struct Shader shader;
-};
-
// TODO: Move this to world.h
struct AbsolutePos
{
@@ -70,4 +55,3 @@ struct GameState
internal void game_init(struct GameMemory *game_memory, v2u framebuffer);
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);
diff --git a/src/memory.c b/src/memory.c
@@ -1,4 +1,5 @@
#define mem_st_alloc_struct(allocator, type) mem_st_alloc((allocator), sizeof(type), alignof(type))
+#define mem_st_alloc_buffer(allocator, type, count) mem_st_alloc((allocator), sizeof(type) * (count), alignof(type))
// TODO: test that alignment is working properly
internal inline uintptr_t mem_align_address(uintptr_t address, size_t alignment)
diff --git a/src/render.c b/src/render.c
@@ -0,0 +1,125 @@
+internal void render_init(struct RendererState *renderer, struct StackAllocator *allocator)
+{
+ GLfloat quad_vertices[] = {
+ 0.5f, 0.5f,
+ 0.5f, -0.5f,
+ -0.5f, -0.5f,
+ -0.5f, 0.5f,
+ };
+
+ GLuint quad_elements[] = { 0, 1, 3, 1, 2, 3 };
+ GLuint rect_elements[] = { 0, 1, 1, 2, 2, 3, 3, 0 };
+
+ GLuint vao;
+ GLuint quad_vbo;
+ GLuint quad_ebo;
+ GLuint rect_ebo;
+ glGenVertexArrays(1, &vao);
+ glGenBuffers(1, &quad_vbo);
+ glGenBuffers(1, &quad_ebo);
+ glGenBuffers(1, &rect_ebo);
+
+ // NOTE(amin): We will leave this bound for the duration of the game.
+ // There should not be any calls to glBindVertexArray(0).
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW);
+ glVertexAttribPointer(
+ 0, // Data location
+ 2, // Number of values
+ GL_FLOAT, // Data type
+ GL_FALSE, // Normalize data
+ 2 * sizeof(GLfloat), // Stride
+ (GLvoid*)0 // Position data offset (0)
+ );
+
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_elements), quad_elements, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rect_ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rect_elements), rect_elements, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ebo);
+
+ renderer->vao = vao;
+ renderer->quad_vbo = quad_vbo;
+ renderer->quad_ebo = quad_ebo;
+ renderer->rect_ebo = rect_ebo;
+ renderer->queue = mem_st_alloc_buffer(allocator, struct RenderJob, RENDER_QUEUE_SIZE);
+ renderer->queue_count = 0;
+}
+
+internal void render_jobs(struct RendererState *renderer)
+{
+ 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(&renderer->shader);
+ shader_setm4(&renderer->shader, "projection", &renderer->projection);
+ shader_setm4(&renderer->shader, "view", &renderer->view);
+
+ GLuint current_ebo = renderer->quad_ebo;
+ for (u32 i = 0; i < renderer->queue_count; i++)
+ {
+ struct RenderJob j = renderer->queue[i];
+ if (current_ebo != j.ebo)
+ {
+ current_ebo = j.ebo;
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, j.ebo);
+ }
+ shader_setv3(&renderer->shader, "color", &j.color);
+ shader_setm4(&renderer->shader, "model", &j.model);
+ if (j.ebo == renderer->quad_ebo)
+ {
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ }
+ else
+ {
+ glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, 0);
+ }
+ }
+
+ renderer->queue_count = 0;
+}
+
+internal void render_job_enqueue(struct RendererState *renderer, struct RenderJob job)
+{
+ assert(renderer);
+ assert(renderer->queue);
+ assert(renderer->queue_count + 1 < RENDER_QUEUE_SIZE);
+ renderer->queue[renderer->queue_count] = job;
+ renderer->queue_count++;
+}
+
+internal void render_debug_quad(struct RendererState *renderer, rect r, v3 color)
+{
+ v2 dim = {r.max.x - r.min.x, r.max.y - r.min.y};
+
+ m4 model = math_m4_init_id();
+ model = math_translate(model, (v3) {dim.x * 0.5f, dim.y * 0.5f, 0.0f});
+ model = math_translate(model, (v3) {r.min.x, r.min.y, 0.0f});
+ model = math_scale(model, (v3) {dim.width, dim.height, 1.0f});
+
+ struct RenderJob j = {
+ .ebo = renderer->rect_ebo,
+ .color = color,
+ .model = model,
+ };
+ render_job_enqueue(renderer, j);
+}
+
+internal void render_cleanup(struct RendererState *renderer)
+{
+ glDeleteVertexArrays(1, &renderer->vao);
+ glDeleteBuffers(1, &renderer->quad_vbo);
+ glDeleteBuffers(1, &renderer->quad_ebo);
+ glDeleteBuffers(1, &renderer->rect_ebo);
+}
diff --git a/src/render.h b/src/render.h
@@ -0,0 +1,21 @@
+#define RENDER_QUEUE_SIZE 512
+
+struct RenderJob
+{
+ GLuint ebo;
+ v3 color;
+ m4 model;
+};
+
+struct RendererState
+{
+ GLuint vao;
+ GLuint quad_vbo;
+ GLuint quad_ebo;
+ GLuint rect_ebo;
+ m4 projection;
+ m4 view;
+ struct Shader shader;
+ struct RenderJob *queue;
+ u32 queue_count;
+};