From 355423d1f6cd364f17c29486b669c8f33c4b77f6 Mon Sep 17 00:00:00 2001 From: talha Date: Mon, 10 Feb 2025 23:44:23 +0500 Subject: 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 --- source/main.cpp | 323 +++---------------------------------------- source/renderer/renderer.cpp | 281 +++++++++++++++++++++++++++++++++++++ source/renderer/renderer.h | 24 ++++ source/todo.txt | 6 +- 4 files changed, 330 insertions(+), 304 deletions(-) create mode 100644 source/renderer/renderer.cpp create mode 100644 source/renderer/renderer.h (limited to 'source') 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 -- cgit v1.2.3