partially done work on total source tree rework, separation of engine context and game context, generalization of renderer for different backends as well as web platform target

This commit is contained in:
2024-09-16 09:07:01 +03:00
parent ca0305feab
commit 551d60ef85
59 changed files with 2892 additions and 890 deletions

View File

@@ -0,0 +1,150 @@
#include "twn_rendering_c.h"
#include "townengine/twn_rendering.h"
#include "townengine/textures/internal_api.h"
#include "townengine/context.h"
#include "townengine/camera.h"
#include "twn_rendering_platform.h"
#include <SDL2/SDL.h>
#include <stb_ds.h>
#ifdef EMSCRIPTEN
#include <GLES2/gl2.h>
#else
#include <glad/glad.h>
#endif
#include <stddef.h>
#include <tgmath.h>
/* TODO: have a default initialized one */
t_matrix4 camera_projection_matrix;
t_matrix4 camera_look_at_matrix;
void render_queue_clear(void) {
/* this doesn't even _deserve_ a TODO */
/* if you're gonna remove it, this is also being done in main.c */
for (size_t i = 0; i < arrlenu(ctx.render_queue_2d); ++i) {
if (ctx.render_queue_2d[i].type == PRIMITIVE_2D_TEXT) {
free(ctx.render_queue_2d[i].text.text);
}
}
/* since i don't intend to free the queues, */
/* it's faster and simpler to just "start over" */
/* and start overwriting the existing data */
arrsetlen(ctx.render_queue_2d, 0);
for (size_t i = 0; i < hmlenu(ctx.uncolored_mesh_batches); ++i)
arrsetlen(ctx.uncolored_mesh_batches[i].value.primitives, 0);
}
/* rectangle */
void push_rectangle(t_frect rect, t_color color) {
struct rect_primitive rectangle = {
.rect = rect,
.color = color,
};
struct primitive_2d primitive = {
.type = PRIMITIVE_2D_RECT,
.rect = rectangle,
};
arrput(ctx.render_queue_2d, primitive);
}
static void render_2d(void) {
use_2d_pipeline();
const size_t render_queue_len = arrlenu(ctx.render_queue_2d);
size_t batch_count = 0;
for (size_t i = 0; i < render_queue_len; ++i) {
const struct primitive_2d *current = &ctx.render_queue_2d[i];
switch (current->type) {
case PRIMITIVE_2D_SPRITE: {
const struct sprite_batch batch =
collect_sprite_batch(current, render_queue_len - i);
/* TODO: what's even the point? just use OR_EQUAL comparison */
set_depth_range((double)batch_count / UINT16_MAX, 1.0);
render_sprites(current, batch);
i += batch.size - 1; ++batch_count;
break;
}
case PRIMITIVE_2D_RECT:
render_rectangle(&current->rect);
break;
case PRIMITIVE_2D_CIRCLE:
render_circle(&current->circle);
break;
case PRIMITIVE_2D_TEXT:
render_text(&current->text);
break;
}
}
}
static void render_space(void) {
/* nothing to do, abort */
/* as space pipeline isn't used we can have fewer changes and initialization costs */
if (hmlenu(ctx.uncolored_mesh_batches) == 0)
return;
use_space_pipeline();
for (size_t i = 0; i < hmlenu(ctx.uncolored_mesh_batches); ++i) {
draw_uncolored_space_traingle_batch(&ctx.uncolored_mesh_batches[i].value,
ctx.uncolored_mesh_batches[i].key);
}
}
void render(void) {
textures_update_atlas(&ctx.texture_cache);
/* fit rendering context onto the resizable screen */
if (ctx.window_size_has_changed) {
if ((float)ctx.window_w / (float)ctx.window_h > RENDER_BASE_RATIO) {
float ratio = (float)ctx.window_h / (float)RENDER_BASE_HEIGHT;
int w = (int)((float)RENDER_BASE_WIDTH * ratio);
setup_viewport(
ctx.window_w / 2 - w / 2,
0,
w,
ctx.window_h
);
} else {
float ratio = (float)ctx.window_w / (float)RENDER_BASE_WIDTH;
int h = (int)((float)RENDER_BASE_HEIGHT * ratio);
setup_viewport(
0,
ctx.window_h / 2 - h / 2,
ctx.window_w,
h
);
}
}
clear_draw_buffer();
render_space();
render_2d();
swap_buffers();
}
void set_camera(const t_camera *const camera) {
/* TODO: skip recaulculating if it's the same? */
camera_projection_matrix = camera_perspective(camera);
camera_look_at_matrix = camera_look_at(camera);
}