commit c39c262c868d24698f5a6a7c26e41610f947b60a
parent bd88d22d902bd6e582766d4b5681a4e7a9386e82
Author: amin <dev@aminmesbah.com>
Date: Mon, 10 Jun 2019 03:04:27 +0000
Sort render job queue based on layer
I'm very suspicious at how this seems to be working upon the very first
compile.
FossilOrigin-Name: 3fe01d1b137585327cba2f5cb176b2e2b6fd9c677a3b36cf3255f818b18ab5bb
Diffstat:
4 files changed, 88 insertions(+), 29 deletions(-)
diff --git a/src/game.c b/src/game.c
@@ -152,21 +152,23 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
}
- m4 view = math_m4_init_id();
- // World origin is in the lower left
- view = math_translate(view, (v3) {0.0f, framebuffer.height, 0.0f});
- 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;
+ {
+ m4 view = math_m4_init_id();
+ // World origin is in the lower left
+ view = math_translate(view, (v3) {0.0f, framebuffer.height, 0.0f});
+ 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
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);
+ struct Room *current_room = world_room_get(game_state->world, current_room_i);
- assert(r);
+ assert(current_room);
// game_print_player_chunk
{
@@ -177,14 +179,14 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
printf("Current Player Room: ");
math_print(current_room_i);
printf("Current Actual Room: ");
- math_print(r->index);
+ math_print(current_room->index);
printf("Chunk Index: ");
math_print(c->index);
}
- assert(math_v2i_eq(current_room_i, r->index));
+ assert(math_v2i_eq(current_room_i, current_room->index));
- u32 *tiles = r->tiles;
+ u32 *tiles = current_room->tiles;
// game_render_tiles
{
@@ -238,17 +240,18 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
if (player_is_in_tile && solid)
{
color = (v3) {0.8f, 0.4f, 0.4f};
- // TODO: re-enable this
- //assert(false);
+ assert(false);
}
}
- struct RenderJob j = {
- .ebo = game_state->renderer.quad_ebo,
- .color = color,
- .model = model,
- };
- render_job_enqueue(&game_state->renderer, j);
+ render_job_enqueue(
+ &game_state->renderer,
+ (struct RenderJob) {
+ .ebo = game_state->renderer.quad_ebo,
+ .color = color,
+ .model = model,
+ .layer = RENDER_LAYER_TILES,
+ });
}
}
}
@@ -534,10 +537,12 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
.ebo = game_state->renderer.quad_ebo,
.color = color,
.model = model,
+ .layer = RENDER_LAYER_PLAYER,
});
}
- render_jobs(&game_state->renderer);
+ render_jobs_sort(&game_state->renderer, &game_state->world_allocator);
+ render_jobs_draw(&game_state->renderer);
}
internal void game_cleanup(struct GameMemory *game_memory)
diff --git a/src/memory.c b/src/memory.c
@@ -1,5 +1,6 @@
#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))
+#define mem_move_buffer(d, s, t, c) mem_move((d), (s), sizeof(t) * (c))
// TODO: test that alignment is working properly
internal inline uintptr_t mem_align_address(uintptr_t address, size_t alignment)
@@ -44,3 +45,8 @@ internal void mem_st_free_all(struct StackAllocator *allocator)
{
allocator->used = 0;
}
+
+internal void mem_move(void *dest, void *source, size_t num_bytes)
+{
+ memmove(dest, source, num_bytes);
+}
diff --git a/src/render.c b/src/render.c
@@ -51,7 +51,7 @@ internal void render_init(struct RendererState *renderer, struct StackAllocator
renderer->queue_count = 0;
}
-internal void render_jobs(struct RendererState *renderer)
+internal void render_jobs_draw(struct RendererState *renderer)
{
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
@@ -90,6 +90,42 @@ internal void render_jobs(struct RendererState *renderer)
renderer->queue_count = 0;
}
+internal void render_jobs_sort(struct RendererState *renderer, struct StackAllocator *allocator)
+{
+ size_t marker = mem_st_get_marker(allocator);
+
+ struct RenderJob *queue = renderer->queue;
+
+ size_t layer_pop_count[NUM_RENDER_LAYERS] = {0};
+ for (size_t i = 0; i < renderer->queue_count; i++)
+ {
+ struct RenderJob j = queue[i];
+ assert(j.layer < NUM_RENDER_LAYERS);
+ layer_pop_count[j.layer] += 1;
+ }
+
+ struct RenderJob *sorted = mem_st_alloc_buffer(allocator, struct RenderJob, renderer->queue_count);
+ size_t layer_pop_count_sorted[NUM_RENDER_LAYERS] = {0};
+ for (size_t i = 0; i < renderer->queue_count; i++)
+ {
+ struct RenderJob j = queue[i];
+
+ size_t insertion_index = 0;
+ for (enum RenderLayer l = RENDER_LAYER_TILES; l < j.layer; l++)
+ {
+ insertion_index += layer_pop_count[l];
+ }
+ insertion_index += layer_pop_count_sorted[j.layer];
+
+ assert(layer_pop_count_sorted[j.layer] < layer_pop_count[j.layer]);
+ sorted[insertion_index] = j;
+ layer_pop_count_sorted[j.layer] += 1;
+ }
+
+ mem_move_buffer(queue, sorted, struct RenderJob, renderer->queue_count);
+ mem_st_free_to_marker(allocator, marker);
+}
+
internal void render_job_enqueue(struct RendererState *renderer, struct RenderJob job)
{
assert(renderer);
@@ -108,12 +144,14 @@ internal void render_debug_quad(struct RendererState *renderer, 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});
- struct RenderJob j = {
- .ebo = renderer->rect_ebo,
- .color = color,
- .model = model,
- };
- render_job_enqueue(renderer, j);
+ render_job_enqueue(
+ renderer,
+ (struct RenderJob) {
+ .ebo = renderer->rect_ebo,
+ .color = color,
+ .model = model,
+ .layer = RENDER_LAYER_DEBUG,
+ });
}
internal void render_cleanup(struct RendererState *renderer)
diff --git a/src/render.h b/src/render.h
@@ -1,10 +1,20 @@
#define RENDER_QUEUE_SIZE 512
+enum RenderLayer
+{
+ RENDER_LAYER_TILES = 0,
+ RENDER_LAYER_DEBUG,
+ RENDER_LAYER_PLAYER,
+
+ NUM_RENDER_LAYERS,
+};
+
struct RenderJob
{
GLuint ebo;
v3 color;
m4 model;
+ enum RenderLayer layer;
};
struct RendererState
@@ -17,5 +27,5 @@ struct RendererState
m4 view;
struct Shader shader;
struct RenderJob *queue;
- u32 queue_count;
+ size_t queue_count;
};