summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortalha <sarcxd@gmail.com>2025-02-10 23:44:23 +0500
committertalha <sarcxd@gmail.com>2025-02-10 23:44:23 +0500
commit355423d1f6cd364f17c29486b669c8f33c4b77f6 (patch)
tree4bf40c9e2104db02c0c409ced55f4d964ee9d30b
parent9e616600198f5b2fe0e68d2456222ba1d8b2435b (diff)
updated rect calculations, separated renderer logic:
- position now starts from left bottom corner, to make drawing easier - moved quad rendering functions to their own files
-rwxr-xr-xsource/main.cpp323
-rw-r--r--source/renderer/renderer.cpp281
-rw-r--r--source/renderer/renderer.h24
-rw-r--r--source/todo.txt6
4 files changed, 330 insertions, 304 deletions
diff --git a/source/main.cpp b/source/main.cpp
index d6e1394..80dc6db 100755
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -198,6 +198,9 @@ struct GLRenderer {
TextState ui_text;
};
+#include "renderer/renderer.h"
+#include "renderer/renderer.cpp"
+
struct Controller {
b8 move_up;
b8 move_down;
@@ -279,8 +282,8 @@ Rect rect(Vec3 position, Vec2 size) {
r.lb.x = position.x;
r.lb.y = position.y;
- r.rt.x = position.x + 2.0f*size.x;
- r.rt.y = position.y + 2.0f*size.y;
+ r.rt.x = position.x + size.x;
+ r.rt.y = position.y + size.y;
return r;
}
@@ -469,283 +472,6 @@ void load_level(GameState *state, Arena *level_arena, Str256 level_path) {
SDL_free(level_data);
}
-u32 gl_shader_program(char* vs, char* fs)
-{
- int status;
- char info_log[512];
-
-
- // =============
- // vertex shader
- u32 vertex_shader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertex_shader, 1, &vs, NULL);
- glCompileShader(vertex_shader);
-
- glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
- if (status == 0)
- {
- glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
- printf("== ERROR: Vertex Shader Compilation Failed ==\n");
- printf("%s\n", info_log);
- }
-
-
- // ===============
- // fragment shader
- u32 fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragment_shader, 1, &fs, NULL);
- glCompileShader(fragment_shader);
-
- glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status);
- if (status == 0)
- {
- glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
- printf("== ERROR: Fragment Shader Compilation Failed ==\n");
- printf("%s\n", info_log);
- }
-
-
- // ==============
- // shader program
- u32 shader_program = glCreateProgram();
-
- glAttachShader(shader_program, vertex_shader);
- glAttachShader(shader_program, fragment_shader);
- glLinkProgram(shader_program);
-
- glGetProgramiv(shader_program, GL_LINK_STATUS, &status);
- if(status == 0)
- {
- glGetProgramInfoLog(shader_program, 512, NULL, info_log);
- printf("== ERROR: Shader Program Linking Failed\n");
- printf("%s\n", info_log);
- }
-
- glDeleteShader(vertex_shader);
- glDeleteShader(fragment_shader);
-
- return shader_program;
-}
-
-u32 gl_shader_program_from_path(const char* vspath, const char* fspath)
-{
- size_t read_count;
- char* vs = (char*)SDL_LoadFile(vspath, &read_count);
- if (read_count == 0)
- {
- printf("Error! Failed to read vertex shader file at path %s\n", vspath);
- return 0;
- }
-
- char* fs = (char*)SDL_LoadFile(fspath, &read_count);
- if (read_count == 0)
- {
- printf("Error! Failed to read fragment shader file at path %s\n", vspath);
- return 0;
- }
-
- u32 shader_program = gl_shader_program(vs, fs);
-
- SDL_free(vs);
- SDL_free(fs);
- return shader_program;
-}
-
-u32 gl_setup_colored_quad(u32 sp)
-{
- // @todo: make this use index buffer maybe?
- r32 vertices[] = {
- -1.0f, -1.0f, 0.0f, // bottom-left
- 1.0f, -1.0f, 0.0f, // bottom-right
- 1.0f, 1.0f, 0.0f, // top-right
- 1.0f, 1.0f, 0.0f, // top-right
- -1.0f, 1.0f, 0.0f, // top-left
- -1.0f, -1.0f, 0.0f, // bottom-left
- };
- u32 vao, vbo;
- glGenVertexArrays(1, &vao);
- glGenBuffers(1, &vbo);
-
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(r32), (void*)0);
-
- glBindVertexArray(0);
-
- // now return or store the vao, vbo state somewhere
- return vao;
-}
-
-void gl_setup_colored_quad_optimized(
- GLRenderer* renderer,
- u32 sp
-) {
- // @todo: make this use index buffer maybe?
- glGenVertexArrays(1, &renderer->cq_batch_vao);
- glGenBuffers(1, &renderer->cq_batch_vbo);
-
- glBindVertexArray(renderer->cq_batch_vao);
- glBindBuffer(GL_ARRAY_BUFFER, renderer->cq_batch_vbo);
- glBufferData(
- GL_ARRAY_BUFFER, (
- renderer->cq_pos_batch.capacity + renderer->cq_color_batch.capacity
- ) * sizeof(r32), NULL, GL_DYNAMIC_DRAW
- );
-
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(r32), (void*)0);
-
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(
- 1, 3, GL_FLOAT, GL_FALSE,
- 3 * sizeof(r32), (void*)(renderer->cq_pos_batch.capacity*sizeof(r32))
- );
-
- glBindVertexArray(0);
-}
-
-void gl_cq_flush(GLRenderer* renderer) {
- glUseProgram(renderer->cq_batch_sp);
- glEnable(GL_DEPTH_TEST);
-
- glUniformMatrix4fv(
- glGetUniformLocation(renderer->cq_batch_sp, "View"),
- 1, GL_FALSE, (renderer->cam_view).buffer
- );
-
- glUniformMatrix4fv(
- glGetUniformLocation(renderer->cq_batch_sp, "Projection"),
- 1, GL_FALSE, (renderer->cam_proj).buffer
- );
-
- glBindBuffer(GL_ARRAY_BUFFER, renderer->cq_batch_vbo);
-
- // fill batch data
- // position batch
- glBufferSubData(
- GL_ARRAY_BUFFER,
- 0,
- renderer->cq_pos_batch.capacity*sizeof(r32),
- renderer->cq_pos_batch.buffer
- );
-
- // color batch
- glBufferSubData(
- GL_ARRAY_BUFFER,
- renderer->cq_pos_batch.capacity*sizeof(r32),
- renderer->cq_color_batch.capacity*sizeof(r32),
- (void*)renderer->cq_color_batch.buffer
- );
-
- glBindVertexArray(renderer->cq_batch_vao);
- glDrawArrays(GL_TRIANGLES, 0, renderer->cq_batch_count*6);
-
- array_clear(&renderer->cq_pos_batch);
- array_clear(&renderer->cq_color_batch);
- renderer->cq_batch_count = 0;
-}
-
-void gl_draw_colored_quad_optimized(
- GLRenderer* renderer,
- Vec3 position,
- Vec2 size,
- Vec3 color
-) {
- Vec4 vertices[6] = {
- Vec4{-1.0f, -1.0f, 0.0f, 1.0f},// bottom-left
- Vec4{ 1.0f, -1.0f, 0.0f, 1.0f},// bottom-right
- Vec4{ 1.0f, 1.0f, 0.0f, 1.0f},// top-right
- Vec4{ 1.0f, 1.0f, 0.0f, 1.0f},// top-right
- Vec4{-1.0f, 1.0f, 0.0f, 1.0f},// top-left
- Vec4{-1.0f, -1.0f, 0.0f, 1.0f} // bottom-left
- };
-
- // setting quad size
- Mat4 model = diag4m(1.0);
- Mat4 scale = scaling_matrix4m(size.x, size.y, 0.0f);
- model = multiply4m(scale, model);
- // setting quad position
- Mat4 translation = translation_matrix4m(position.x + size.x, position.y + size.y, position.z);
- model = multiply4m(translation, model);
-
- Vec4 model_pos;
- model_pos = multiply4mv(model, vertices[0]);
- vertices[0] = model_pos;
- model_pos = multiply4mv(model, vertices[1]);
- vertices[1] = model_pos;
- model_pos = multiply4mv(model, vertices[2]);
- vertices[2] = model_pos;
- model_pos = multiply4mv(model, vertices[3]);
- vertices[3] = model_pos;
- model_pos = multiply4mv(model, vertices[4]);
- vertices[4] = model_pos;
- model_pos = multiply4mv(model, vertices[5]);
- vertices[5] = model_pos;
-
- array_insert(&renderer->cq_pos_batch, vertices[0].data, 4);
- array_insert(&renderer->cq_pos_batch, vertices[1].data, 4);
- array_insert(&renderer->cq_pos_batch, vertices[2].data, 4);
- array_insert(&renderer->cq_pos_batch, vertices[3].data, 4);
- array_insert(&renderer->cq_pos_batch, vertices[4].data, 4);
- array_insert(&renderer->cq_pos_batch, vertices[5].data, 4);
-
- // initialise color to be per vertex to allow batching
- array_insert(&renderer->cq_color_batch, color.data, 3);
- array_insert(&renderer->cq_color_batch, color.data, 3);
- array_insert(&renderer->cq_color_batch, color.data, 3);
- array_insert(&renderer->cq_color_batch, color.data, 3);
- array_insert(&renderer->cq_color_batch, color.data, 3);
- array_insert(&renderer->cq_color_batch, color.data, 3);
-
- renderer->cq_batch_count++;
-
- if(renderer->cq_batch_count == BATCH_SIZE) {
- gl_cq_flush(renderer);
- }
-}
-
-void gl_draw_colored_quad(
- GLRenderer* renderer,
- Vec3 position,
- Vec2 size,
- Vec3 color
-) {
- glEnable(GL_DEPTH_TEST);
- glUseProgram(renderer->cq_sp);
- if (renderer->cq_init == 0)
- {
- glUniformMatrix4fv(
- glGetUniformLocation(renderer->cq_sp, "Projection"),
- 1, GL_FALSE, (renderer->cam_proj).buffer
- );
- renderer->cq_init = 1;
- }
- // setting quad size
- Mat4 model = diag4m(1.0);
- Mat4 scale = scaling_matrix4m(size.x, size.y, 0.0f);
- model = multiply4m(scale, model);
- // setting quad position
- Mat4 translation = translation_matrix4m(position.x, position.y, position.z);
- model = multiply4m(translation, model);
- // setting color
- glUniform3fv(glGetUniformLocation(renderer->cq_sp, "Color"), 1, color.data);
-
- glUniformMatrix4fv(
- glGetUniformLocation(renderer->cq_sp, "Model"),
- 1, GL_FALSE, model.buffer
- );
-
- glUniformMatrix4fv(
- glGetUniformLocation(renderer->cq_sp, "View"),
- 1, GL_FALSE, (renderer->cam_view).buffer
- );
-
- glBindVertexArray(renderer->cq_vao);
- glDrawArrays(GL_TRIANGLES, 0, 6);
-}
-
void gl_setup_text(TextState* state, FT_Face font_face)
{
FT_Set_Pixel_Sizes(font_face, state->pixel_size, state->pixel_size);
@@ -949,14 +675,6 @@ void update_camera(GLRenderer *renderer) {
}
}
-Vec3 get_world_position_from_percent(GameState state, Vec3 v) {
- Vec3 world_pos = v;
- world_pos.x = state.render_scale.x*state.world_size.x*v.x/100.0f;
- world_pos.y = state.render_scale.y*state.world_size.y*v.y/100.0f;
-
- return world_pos;
-}
-
Vec2 get_screen_position_from_percent(GameState state, Vec2 v) {
Vec2 screen_pos = v;
screen_pos.x = state.render_scale.x*state.screen_size.x*v.x/100.0f;
@@ -965,14 +683,6 @@ Vec2 get_screen_position_from_percent(GameState state, Vec2 v) {
return screen_pos;
}
-Vec3 get_screen_position_from_percent(GameState state, Vec3 v) {
- Vec3 screen_pos = v;
- screen_pos.x = state.render_scale.x*state.screen_size.x*v.x/100.0f;
- screen_pos.y = state.render_scale.y*state.screen_size.y*v.y/100.0f;
-
- return screen_pos;
-}
-
int main(int argc, char* argv[])
{
u32 base_scr_width = 1024;
@@ -1125,7 +835,7 @@ int main(int argc, char* argv[])
);
// @section: gameplay variables
- r32 motion_scale = 2.0f*render_scale;
+ r32 motion_scale = 2.0f;
r32 gravity_diry = 1.0f;
r32 fall_accelx = 3.0f*motion_scale;
r32 move_accelx = 4.0f*motion_scale;
@@ -1145,13 +855,14 @@ int main(int argc, char* argv[])
// object placement should be in pixels
// in order to scale to different resolutions it should be multiplied by
// scaling factor
- Vec2 atom_size = Vec2{32.0f, 32.0f};
+ Vec2 atom_size = Vec2{64.0f, 64.0f};
GameState state = {0};
state.atom_size = atom_size;
state.world_size = Vec2{(r32)scr_width, (r32)scr_height};
state.screen_size = Vec2{(r32)scr_width, (r32)scr_height};
state.render_scale = vec2(render_scale);
+ Vec2 camera_screen_size = state.screen_size * state.render_scale;
// @todo: rename rect members (makes more sense)
// tl -> lt
@@ -1159,7 +870,7 @@ int main(int argc, char* argv[])
{
// @step: calculate_camera_bounds
Vec2 cam_lb = Vec2{renderer.cam_pos.x, renderer.cam_pos.y};
- Vec2 cam_rt = Vec2{renderer.cam_pos.x + state.screen_size.x, renderer.cam_pos.y + state.screen_size.y};
+ Vec2 cam_rt = Vec2{renderer.cam_pos.x + camera_screen_size.x, renderer.cam_pos.y + camera_screen_size.y};
state.camera_bounds.lb = cam_lb;
state.camera_bounds.rt = cam_rt;
}
@@ -1187,6 +898,7 @@ int main(int argc, char* argv[])
renderer.cam_pos.y = player.position.y;
effective_force = 0.0f;
player_velocity = Vec2{0.0f, 0.0f};
+ gravity_diry = 1.0f;
}
// gameplay camera movement stuff
@@ -1306,6 +1018,7 @@ int main(int argc, char* argv[])
renderer.cam_pos.y = player.position.y;
effective_force = 0.0f;
player_velocity = Vec2{0.0f, 0.0f};
+ gravity_diry = 1.0f;
}
}
#if CAM_MANUAL_MOVE
@@ -1378,6 +1091,7 @@ int main(int argc, char* argv[])
renderer.cam_pos.y = player.position.y;
effective_force = 0.0f;
player_velocity = Vec2{0.0f, 0.0f};
+ gravity_diry = 1.0f;
}
}
@@ -1773,8 +1487,8 @@ int main(int argc, char* argv[])
// @step: player is at the edge of the screen
// get players visible bounds (padding around the player to consider it be visible for the camera)
- Vec2 vis_lb = player.bounds.lb - (Vec2{20.0f, 40.0f} * state.render_scale);
- Vec2 vis_rt = player.bounds.rt + (Vec2{20.0f, 40.0f} * state.render_scale);
+ Vec2 vis_lb = player.bounds.lb - (Vec2{40.0f, 60.0f} * state.render_scale);
+ Vec2 vis_rt = player.bounds.rt + (Vec2{40.0f, 60.0f} * state.render_scale);
Rect vis_bounds;
vis_bounds.lb = vis_lb;
vis_bounds.rt = vis_rt;
@@ -1867,7 +1581,7 @@ int main(int argc, char* argv[])
{
// @step: calculate_camera_bounds
Vec2 cam_lb = Vec2{renderer.cam_pos.x, renderer.cam_pos.y};
- Vec2 cam_rt = Vec2{renderer.cam_pos.x + state.screen_size.x, renderer.cam_pos.y + state.screen_size.y};
+ Vec2 cam_rt = Vec2{renderer.cam_pos.x + camera_screen_size.x, renderer.cam_pos.y + camera_screen_size.y};
state.camera_bounds.lb = cam_lb;
state.camera_bounds.rt = cam_rt;
}
@@ -1898,10 +1612,15 @@ int main(int argc, char* argv[])
// render_entities
for (int i = 0; i < state.game_level.entity_count; i++) {
Entity entity = state.game_level.entities[i];
+ Vec3 entity_center = Vec3{
+ entity.position.x + entity.size.x/2.0f,
+ entity.position.y + entity.size.y/2.0f,
+ entity.position.z
+ };
Vec3 color = entity_colors[entity.type];
gl_draw_colored_quad_optimized(
&renderer,
- entity.position,
+ entity_center,
entity.size,
color
);
diff --git a/source/renderer/renderer.cpp b/source/renderer/renderer.cpp
new file mode 100644
index 0000000..669ac2d
--- /dev/null
+++ b/source/renderer/renderer.cpp
@@ -0,0 +1,281 @@
+#include "renderer.h"
+
+u32 gl_shader_program(char* vs, char* fs)
+{
+ int status;
+ char info_log[512];
+
+
+ // =============
+ // vertex shader
+ u32 vertex_shader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertex_shader, 1, &vs, NULL);
+ glCompileShader(vertex_shader);
+
+ glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
+ if (status == 0)
+ {
+ glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
+ printf("== ERROR: Vertex Shader Compilation Failed ==\n");
+ printf("%s\n", info_log);
+ }
+
+
+ // ===============
+ // fragment shader
+ u32 fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragment_shader, 1, &fs, NULL);
+ glCompileShader(fragment_shader);
+
+ glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status);
+ if (status == 0)
+ {
+ glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
+ printf("== ERROR: Fragment Shader Compilation Failed ==\n");
+ printf("%s\n", info_log);
+ }
+
+
+ // ==============
+ // shader program
+ u32 shader_program = glCreateProgram();
+
+ glAttachShader(shader_program, vertex_shader);
+ glAttachShader(shader_program, fragment_shader);
+ glLinkProgram(shader_program);
+
+ glGetProgramiv(shader_program, GL_LINK_STATUS, &status);
+ if(status == 0)
+ {
+ glGetProgramInfoLog(shader_program, 512, NULL, info_log);
+ printf("== ERROR: Shader Program Linking Failed\n");
+ printf("%s\n", info_log);
+ }
+
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+
+ return shader_program;
+}
+
+u32 gl_shader_program_from_path(const char* vspath, const char* fspath)
+{
+ size_t read_count;
+ char* vs = (char*)SDL_LoadFile(vspath, &read_count);
+ if (read_count == 0)
+ {
+ printf("Error! Failed to read vertex shader file at path %s\n", vspath);
+ return 0;
+ }
+
+ char* fs = (char*)SDL_LoadFile(fspath, &read_count);
+ if (read_count == 0)
+ {
+ printf("Error! Failed to read fragment shader file at path %s\n", vspath);
+ return 0;
+ }
+
+ u32 shader_program = gl_shader_program(vs, fs);
+
+ SDL_free(vs);
+ SDL_free(fs);
+ return shader_program;
+}
+
+u32 gl_setup_colored_quad(u32 sp)
+{
+ // @todo: make this use index buffer maybe?
+ r32 vertices[] = {
+ -1.0f, -1.0f, 0.0f, // bottom-left
+ 1.0f, -1.0f, 0.0f, // bottom-right
+ 1.0f, 1.0f, 0.0f, // top-right
+ 1.0f, 1.0f, 0.0f, // top-right
+ -1.0f, 1.0f, 0.0f, // top-left
+ -1.0f, -1.0f, 0.0f, // bottom-left
+ };
+ u32 vao, vbo;
+ glGenVertexArrays(1, &vao);
+ glGenBuffers(1, &vbo);
+
+ glBindVertexArray(vao);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(r32), (void*)0);
+
+ glBindVertexArray(0);
+
+ // now return or store the vao, vbo state somewhere
+ return vao;
+}
+
+void gl_draw_colored_quad(
+ GLRenderer* renderer,
+ Vec3 position,
+ Vec2 size,
+ Vec3 color
+) {
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(renderer->cq_sp);
+ if (renderer->cq_init == 0)
+ {
+ glUniformMatrix4fv(
+ glGetUniformLocation(renderer->cq_sp, "Projection"),
+ 1, GL_FALSE, (renderer->cam_proj).buffer
+ );
+ renderer->cq_init = 1;
+ }
+ // setting quad size
+ Mat4 model = diag4m(1.0);
+ Mat4 scale = scaling_matrix4m(size.x, size.y, 0.0f);
+ model = multiply4m(scale, model);
+ // setting quad position
+ Mat4 translation = translation_matrix4m(position.x, position.y, position.z);
+ model = multiply4m(translation, model);
+ // setting color
+ glUniform3fv(glGetUniformLocation(renderer->cq_sp, "Color"), 1, color.data);
+
+ glUniformMatrix4fv(
+ glGetUniformLocation(renderer->cq_sp, "Model"),
+ 1, GL_FALSE, model.buffer
+ );
+
+ glUniformMatrix4fv(
+ glGetUniformLocation(renderer->cq_sp, "View"),
+ 1, GL_FALSE, (renderer->cam_view).buffer
+ );
+
+ glBindVertexArray(renderer->cq_vao);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+void gl_setup_colored_quad_optimized(
+ GLRenderer* renderer,
+ u32 sp
+) {
+ // @todo: make this use index buffer maybe?
+ glGenVertexArrays(1, &renderer->cq_batch_vao);
+ glGenBuffers(1, &renderer->cq_batch_vbo);
+
+ glBindVertexArray(renderer->cq_batch_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, renderer->cq_batch_vbo);
+ glBufferData(
+ GL_ARRAY_BUFFER, (
+ renderer->cq_pos_batch.capacity + renderer->cq_color_batch.capacity
+ ) * sizeof(r32), NULL, GL_DYNAMIC_DRAW
+ );
+
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(r32), (void*)0);
+
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(
+ 1, 3, GL_FLOAT, GL_FALSE,
+ 3 * sizeof(r32), (void*)(renderer->cq_pos_batch.capacity*sizeof(r32))
+ );
+
+ glBindVertexArray(0);
+}
+
+void gl_draw_colored_quad_optimized(
+ GLRenderer* renderer,
+ Vec3 position,
+ Vec2 size,
+ Vec3 color
+) {
+ Vec4 vertices[6] = {
+ Vec4{-1.0f, -1.0f, 0.0f, 1.0f},// bottom-left
+ Vec4{ 1.0f, -1.0f, 0.0f, 1.0f},// bottom-right
+ Vec4{ 1.0f, 1.0f, 0.0f, 1.0f},// top-right
+ Vec4{ 1.0f, 1.0f, 0.0f, 1.0f},// top-right
+ Vec4{-1.0f, 1.0f, 0.0f, 1.0f},// top-left
+ Vec4{-1.0f, -1.0f, 0.0f, 1.0f} // bottom-left
+ };
+
+ // setting quad size
+ Mat4 model = diag4m(1.0);
+ // @note: this is necessary because clip space is {-1,-1} to {1,1}
+ // So, by scaling with the original size we get scaling range of {-32, -32}, {32, 32}
+ // doubling our size.
+ Mat4 scale = scaling_matrix4m(size.x/2.0f, size.y/2.0f, 0.0f);
+ model = multiply4m(scale, model);
+ // setting quad position
+ Mat4 translation = translation_matrix4m(position.x, position.y, position.z);
+ model = multiply4m(translation, model);
+
+ Vec4 model_pos;
+ model_pos = multiply4mv(model, vertices[0]);
+ vertices[0] = model_pos;
+ model_pos = multiply4mv(model, vertices[1]);
+ vertices[1] = model_pos;
+ model_pos = multiply4mv(model, vertices[2]);
+ vertices[2] = model_pos;
+ model_pos = multiply4mv(model, vertices[3]);
+ vertices[3] = model_pos;
+ model_pos = multiply4mv(model, vertices[4]);
+ vertices[4] = model_pos;
+ model_pos = multiply4mv(model, vertices[5]);
+ vertices[5] = model_pos;
+
+ array_insert(&renderer->cq_pos_batch, vertices[0].data, 4);
+ array_insert(&renderer->cq_pos_batch, vertices[1].data, 4);
+ array_insert(&renderer->cq_pos_batch, vertices[2].data, 4);
+ array_insert(&renderer->cq_pos_batch, vertices[3].data, 4);
+ array_insert(&renderer->cq_pos_batch, vertices[4].data, 4);
+ array_insert(&renderer->cq_pos_batch, vertices[5].data, 4);
+
+ // initialise color to be per vertex to allow batching
+ array_insert(&renderer->cq_color_batch, color.data, 3);
+ array_insert(&renderer->cq_color_batch, color.data, 3);
+ array_insert(&renderer->cq_color_batch, color.data, 3);
+ array_insert(&renderer->cq_color_batch, color.data, 3);
+ array_insert(&renderer->cq_color_batch, color.data, 3);
+ array_insert(&renderer->cq_color_batch, color.data, 3);
+
+ renderer->cq_batch_count++;
+
+ if(renderer->cq_batch_count == BATCH_SIZE) {
+ gl_cq_flush(renderer);
+ }
+}
+
+void gl_cq_flush(GLRenderer* renderer) {
+ glUseProgram(renderer->cq_batch_sp);
+ glEnable(GL_DEPTH_TEST);
+
+ glUniformMatrix4fv(
+ glGetUniformLocation(renderer->cq_batch_sp, "View"),
+ 1, GL_FALSE, (renderer->cam_view).buffer
+ );
+
+ glUniformMatrix4fv(
+ glGetUniformLocation(renderer->cq_batch_sp, "Projection"),
+ 1, GL_FALSE, (renderer->cam_proj).buffer
+ );
+
+ glBindBuffer(GL_ARRAY_BUFFER, renderer->cq_batch_vbo);
+
+ // fill batch data
+ // position batch
+ glBufferSubData(
+ GL_ARRAY_BUFFER,
+ 0,
+ renderer->cq_pos_batch.capacity*sizeof(r32),
+ renderer->cq_pos_batch.buffer
+ );
+
+ // color batch
+ glBufferSubData(
+ GL_ARRAY_BUFFER,
+ renderer->cq_pos_batch.capacity*sizeof(r32),
+ renderer->cq_color_batch.capacity*sizeof(r32),
+ (void*)renderer->cq_color_batch.buffer
+ );
+
+ glBindVertexArray(renderer->cq_batch_vao);
+ glDrawArrays(GL_TRIANGLES, 0, renderer->cq_batch_count*6);
+
+ array_clear(&renderer->cq_pos_batch);
+ array_clear(&renderer->cq_color_batch);
+ renderer->cq_batch_count = 0;
+}
diff --git a/source/renderer/renderer.h b/source/renderer/renderer.h
new file mode 100644
index 0000000..db7cdd4
--- /dev/null
+++ b/source/renderer/renderer.h
@@ -0,0 +1,24 @@
+#pragma once
+
+u32 gl_shader_program(char *vs, char *fs);
+u32 gl_shader_program_from_path(const char *vspath, const char *fspath);
+
+u32 gl_setup_colored_quad(u32 sp);
+void gl_draw_colored_quad(
+ GLRenderer* renderer,
+ Vec3 position,
+ Vec2 size,
+ Vec3 color
+ );
+
+void gl_setup_colored_quad_optimized(
+ GLRenderer* renderer,
+ u32 sp
+ );
+void gl_draw_colored_quad_optimised(
+ GLRenderer* renderer,
+ Vec3 position,
+ Vec2 size,
+ Vec3 color
+ );
+void gl_cq_flush(GLRenderer *renderer);
diff --git a/source/todo.txt b/source/todo.txt
index 90d4117..0228778 100644
--- a/source/todo.txt
+++ b/source/todo.txt
@@ -27,9 +27,12 @@ DONE:
- Better level format, not having to specify the level element count
in the level file.
- Added invert gravity mechanic
+- teleport block mechanic
DOING:
-- teleport block mechanic
+- improve level design features
+ * add lines for easier distinction
+ * get world position via mouse
BLOCKED:
- Audio: figure out what the correct audio sound for jumping will be.
@@ -37,6 +40,5 @@ BLOCKED:
TODO:
- Update camera follower for centering player in view (with limits) after
a few seconds (maybe like 2 seconds)
-- make movement grid based? let's see but probably not
- Implement Broad Phase Collision for efficient collision handling, let's see
- vectorize math library with simd