From 894355810995472652b83b9f18345d0c8c9fc3d2 Mon Sep 17 00:00:00 2001 From: Brett Date: Sun, 14 Apr 2024 17:34:56 -0400 Subject: [PATCH] z indexing on 2d objects --- CMakeLists.txt | 2 +- include/blt/gfx/renderer/2d_textured.vert | 3 +- include/blt/gfx/renderer/batch_2d_renderer.h | 77 +++++++++++--------- include/blt/gfx/state.h | 2 +- libraries/BLT | 2 +- libraries/imgui | 2 +- libraries/openal-soft | 2 +- src/blt/gfx/renderer/batch_2d_renderer.cpp | 44 ++++++++++- 8 files changed, 90 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de7d632..96086ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.25) -set(BLT_GRAPHICS_VERSION 0.9.7) +set(BLT_GRAPHICS_VERSION 0.9.8) set(BLT_GRAPHICS_TEST_VERSION 0.0.1) project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION}) diff --git a/include/blt/gfx/renderer/2d_textured.vert b/include/blt/gfx/renderer/2d_textured.vert index 9547b35..786d0ab 100644 --- a/include/blt/gfx/renderer/2d_textured.vert +++ b/include/blt/gfx/renderer/2d_textured.vert @@ -20,9 +20,10 @@ layout (std140) uniform GlobalMatrices }; uniform mat4 model; +uniform float z_index; void main() { - gl_Position = ortho * model * vec4(vertex, 1.0); + gl_Position = ortho * model * vec4(vertex.xy, z_index, 1.0); pos = vertex.xy; uv = uv_in; } diff --git a/include/blt/gfx/renderer/batch_2d_renderer.h b/include/blt/gfx/renderer/batch_2d_renderer.h index 1864671..a321ac6 100644 --- a/include/blt/gfx/renderer/batch_2d_renderer.h +++ b/include/blt/gfx/renderer/batch_2d_renderer.h @@ -36,15 +36,15 @@ namespace blt::gfx struct rectangle2d_t { blt::vec2f pos, size; - float rotation = 0; + blt::f32 rotation = 0; - rectangle2d_t(float x, float y, float width, float height, float rotation): pos(x, y), size(width, height), rotation(rotation) + rectangle2d_t(blt::f32 x, blt::f32 y, blt::f32 width, blt::f32 height, blt::f32 rotation): pos(x, y), size(width, height), rotation(rotation) {} - rectangle2d_t(float x, float y, float width, float height): pos(x, y), size(width, height) + rectangle2d_t(blt::f32 x, blt::f32 y, blt::f32 width, blt::f32 height): pos(x, y), size(width, height) {} - rectangle2d_t(blt::vec2f pos, blt::vec2f size, float rotation): pos(pos), size(size), rotation(rotation) + rectangle2d_t(blt::vec2f pos, blt::vec2f size, blt::f32 rotation): pos(pos), size(size), rotation(rotation) {} rectangle2d_t(blt::vec2f pos, blt::vec2f size): pos(pos), size(size) @@ -55,18 +55,18 @@ namespace blt::gfx { blt::vec2f p1; blt::vec2f p2; - float thickness = 1; + blt::f32 thickness = 1; - line2d_t(float px1, float py1, float px2, float py2): p1(px1, py1), p2(px2, py2) + line2d_t(blt::f32 px1, blt::f32 py1, blt::f32 px2, blt::f32 py2): p1(px1, py1), p2(px2, py2) {} line2d_t(blt::vec2f p1, blt::vec2f p2): p1(p1), p2(p2) {} - line2d_t(float px1, float py1, float px2, float py2, float thickness): p1(px1, py1), p2(px2, py2), thickness(thickness) + line2d_t(blt::f32 px1, blt::f32 py1, blt::f32 px2, blt::f32 py2, blt::f32 thickness): p1(px1, py1), p2(px2, py2), thickness(thickness) {} - line2d_t(blt::vec2f p1, blt::vec2f p2, float thickness): p1(p1), p2(p2), thickness(thickness) + line2d_t(blt::vec2f p1, blt::vec2f p2, blt::f32 thickness): p1(p1), p2(p2), thickness(thickness) {} }; @@ -110,22 +110,29 @@ namespace blt::gfx } }; + template struct render_object_t { - std::string texture; - blt::vec4 color; - blt::vec4 texture_blend_factor; - std::variant t; + blt::f32 z_index; + T obj; + + render_object_t(float z_index, T obj): z_index(z_index), obj(obj) + {} }; + using rectangle2d_obj_t = render_object_t; + using point2d_obj_t = render_object_t; + using line2d_obj_t = render_object_t; private: vertex_array* square_vao = nullptr; vertex_array* line_vao = nullptr; shader_t* square_shader = nullptr; shader_t* point_shader = nullptr; resource_manager& resources; - // z-index -> draw object - std::map> draw_objects; + // texture -> color -> blend factor -> list of rectangles + blt::hashmap_t, vec_hash>, vec_hash>> complex_rectangles; + blt::hashmap_t, vec_hash>, vec_hash>> complex_points; + blt::hashmap_t, vec_hash>, vec_hash>> complex_lines; size_t draw_count_ = 0; public: explicit batch_renderer_2d(resource_manager& resources): resources(resources) @@ -133,58 +140,58 @@ namespace blt::gfx void create(); - inline void drawRectangle(std::string_view texture, const rectangle2d_t& rectangle, blt::i32 z_index = 0) + inline void drawRectangle(std::string_view texture, const rectangle2d_t& rectangle, blt::f32 z_index = 0) { const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 full{1, 1, 1, 1}; - draw_objects[z_index].push_back(render_object_t{std::string(texture), empty, full, rectangle}); + complex_rectangles[texture][empty][full].emplace_back(z_index, rectangle); } - inline void drawRectangle(const blt::vec4& color, const rectangle2d_t& rectangle, blt::i32 z_index = 0) + inline void drawRectangle(const blt::vec4& color, const rectangle2d_t& rectangle, blt::f32 z_index = 0) { const static blt::vec4 empty{0, 0, 0, 0}; - draw_objects[z_index].push_back(render_object_t{"", color, empty, rectangle}); + complex_rectangles[""][color][empty].emplace_back(z_index, rectangle); } - inline void drawRectangle(const draw_state& draw_info, const rectangle2d_t& rectangle, blt::i32 z_index = 0) + inline void drawRectangle(const draw_state& draw_info, const rectangle2d_t& rectangle, blt::f32 z_index = 0) { - draw_objects[z_index].push_back(render_object_t{draw_info.texture_name, draw_info.color, draw_info.blend, rectangle}); + complex_rectangles[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(z_index, rectangle); } - inline void drawLine(std::string_view texture, const line2d_t& line, blt::i32 z_index = 0) + inline void drawLine(std::string_view texture, const line2d_t& line, blt::f32 z_index = 0) { const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 full{1, 1, 1, 1}; - draw_objects[z_index].push_back(render_object_t{std::string(texture), empty, full, line}); + complex_lines[texture][empty][full].emplace_back(z_index, line); } - inline void drawLine(const blt::vec4& color, const line2d_t& line, blt::i32 z_index = 0) + inline void drawLine(const blt::vec4& color, const line2d_t& line, blt::f32 z_index = 0) { const static blt::vec4 empty{0, 0, 0, 0}; - draw_objects[z_index].push_back(render_object_t{"", color, empty, line}); + complex_lines[""][color][empty].emplace_back(z_index, line); } - inline void drawLine(const draw_state& draw_info, const line2d_t& line, blt::i32 z_index = 0) + inline void drawLine(const draw_state& draw_info, const line2d_t& line, blt::f32 z_index = 0) { - draw_objects[z_index].push_back(render_object_t{draw_info.texture_name, draw_info.color, draw_info.blend, line}); + complex_lines[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(z_index, line); } - inline void drawPoint(std::string_view texture, const point2d_t& point, blt::i32 z_index = 0) + inline void drawPoint(std::string_view texture, const point2d_t& point, blt::f32 z_index = 0) { const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 full{1, 1, 1, 1}; - draw_objects[z_index].push_back(render_object_t{std::string(texture), empty, full, point}); + complex_points[texture][empty][full].emplace_back(z_index, point); } - inline void drawPoint(const blt::vec4& color, const point2d_t& point, blt::i32 z_index = 0) + inline void drawPoint(const blt::vec4& color, const point2d_t& point, blt::f32 z_index = 0) { const static blt::vec4 empty{0, 0, 0, 0}; - draw_objects[z_index].push_back(render_object_t{"", color, empty, point}); + complex_points[""][color][empty].emplace_back(z_index, point); } - inline void drawPoint(const draw_state& draw_info, const point2d_t& point, blt::i32 z_index = 0) + inline void drawPoint(const draw_state& draw_info, const point2d_t& point, blt::f32 z_index = 0) { - draw_objects[z_index].push_back(render_object_t{draw_info.texture_name, draw_info.color, draw_info.blend, point}); + complex_points[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(z_index, point); } template @@ -206,19 +213,19 @@ namespace blt::gfx } template - inline void drawRectangle(const T& render_info, blt::i32 z_index, P... p) + inline void drawRectangle(const T& render_info, blt::f32 z_index, P... p) { drawRectangle(render_info, {p...}, z_index); } template - inline void drawPoint(const T& render_info, blt::i32 z_index, P... p) + inline void drawPoint(const T& render_info, blt::f32 z_index, P... p) { drawPoint(render_info, {p...}, z_index); } template - inline void drawLine(const T& render_info, blt::i32 z_index, P... p) + inline void drawLine(const T& render_info, blt::f32 z_index, P... p) { drawLine(render_info, {p...}, z_index); } diff --git a/include/blt/gfx/state.h b/include/blt/gfx/state.h index a99336b..1ef9c4e 100644 --- a/include/blt/gfx/state.h +++ b/include/blt/gfx/state.h @@ -85,7 +85,7 @@ namespace blt::gfx } void update_perspectives(std::int32_t width, std::int32_t height, float fov = 90, float near = 0.1f, float far = 500.0f, - float ortho_near = -1, float ortho_far = 1); + float ortho_near = 0, float ortho_far = 1.1); void update(); }; diff --git a/libraries/BLT b/libraries/BLT index 9db3f12..325508e 160000 --- a/libraries/BLT +++ b/libraries/BLT @@ -1 +1 @@ -Subproject commit 9db3f120489ff27aa560e488d82b5ae0d64019df +Subproject commit 325508e807f376fb7d287dbb9d80899eddb4e8ff diff --git a/libraries/imgui b/libraries/imgui index 231cbee..a1b0682 160000 --- a/libraries/imgui +++ b/libraries/imgui @@ -1 +1 @@ -Subproject commit 231cbee0fc4f59dbe5b8b853a11b08dc84e57c65 +Subproject commit a1b06823fe2d964a62fda99385499b218cf5cea5 diff --git a/libraries/openal-soft b/libraries/openal-soft index 111397c..6675317 160000 --- a/libraries/openal-soft +++ b/libraries/openal-soft @@ -1 +1 @@ -Subproject commit 111397c71a5f1c2c88e05da9c84edfdba2e472a4 +Subproject commit 6675317107257c2cc16c947b359d557821d85bf2 diff --git a/src/blt/gfx/renderer/batch_2d_renderer.cpp b/src/blt/gfx/renderer/batch_2d_renderer.cpp index 94d8f6a..320891c 100644 --- a/src/blt/gfx/renderer/batch_2d_renderer.cpp +++ b/src/blt/gfx/renderer/batch_2d_renderer.cpp @@ -100,6 +100,25 @@ namespace blt::gfx delete point_shader; } + template + void find_min_and_max(T& container, blt::f32& min, blt::f32& max) + { + for (auto& textures : container) + { + for (auto& colors : textures.second) + { + for (auto& blend_factors : colors.second) + { + for (auto& obj : blend_factors.second) + { + min = std::min(min, obj.z_index); + max = std::max(max, obj.z_index); + } + } + } + } + } + void batch_renderer_2d::render(bool transparency) { if (transparency) @@ -107,10 +126,22 @@ namespace blt::gfx glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + glEnable(GL_DEPTH_TEST); draw_count_ = 0; square_shader->bind(); square_vao->bind(); glActiveTexture(GL_TEXTURE0); + + // annoying + blt::f32 min = std::numeric_limits::max(); + blt::f32 max = std::numeric_limits::min(); + + find_min_and_max(complex_rectangles, min, max); + find_min_and_max(complex_points, min, max); + find_min_and_max(complex_lines, min, max); + + blt::f32 denominator = 1.0f / (max - min); + for (auto& textures : complex_rectangles) { // resource manager handles the check for empty string @@ -122,14 +153,16 @@ namespace blt::gfx for (auto& blend_factors : colors.second) { square_shader->setVec4("use_texture", blend_factors.first); - for (auto& rect : blend_factors.second) + for (auto& rect_obj : blend_factors.second) { + auto& rect = rect_obj.obj; blt::mat4x4 model; model.translate(rect.pos.x(), rect.pos.y(), 0.0f); model.scale(rect.size.x(), rect.size.y(), 1); if (rect.rotation != 0) model.rotateZ(blt::toRadians(rect.rotation)); square_shader->setMatrix("model", model); + square_shader->setFloat("z_index", (rect_obj.z_index - min) * denominator); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); draw_count_++; } @@ -152,12 +185,14 @@ namespace blt::gfx for (auto& blend_factors : colors.second) { point_shader->setVec4("use_texture", blend_factors.first); - for (auto& point : blend_factors.second) + for (auto& point_obj : blend_factors.second) { + auto& point = point_obj.obj; blt::mat4x4 model; model.translate(point.pos.x(), point.pos.y(), 0.0f); model.scale(point.scale, point.scale, 1); point_shader->setMatrix("model", model); + point_shader->setFloat("z_index", (point_obj.z_index - min) * denominator); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); draw_count_++; } @@ -185,8 +220,9 @@ namespace blt::gfx for (auto& blend_factors : colors.second) { square_shader->setVec4("use_texture", blend_factors.first); - for (auto& line : blend_factors.second) + for (auto& line_obj : blend_factors.second) { + auto& line = line_obj.obj; // 0, 1 (top right) // 5, 6 (bottom right) // 10, 11 (bottom left) @@ -215,6 +251,7 @@ namespace blt::gfx buf.update(sizeof(line_vertices), line_vertices); + square_shader->setFloat("z_index", (line_obj.z_index - min) * denominator); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); draw_count_++; } @@ -224,6 +261,7 @@ namespace blt::gfx } textures.second.clear(); } + glDisable(GL_DEPTH_TEST); if (transparency) glDisable(GL_BLEND); }