diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d39e6b..6a9dc5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.25) -set(BLT_GRAPHICS_VERSION 0.9.5) +set(BLT_GRAPHICS_VERSION 0.9.6) set(BLT_GRAPHICS_TEST_VERSION 0.0.1) project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION}) diff --git a/include/blt/gfx/model.h b/include/blt/gfx/model.h index 17b7293..53db22a 100644 --- a/include/blt/gfx/model.h +++ b/include/blt/gfx/model.h @@ -208,6 +208,11 @@ namespace blt::gfx * The VBO is considered invalid if its ID is 0 */ inline vbo_t& operator[](size_t index) + { + return getBuffer(index); + } + + inline vbo_t& getBuffer(size_t index) { return VBOs[index]->vbo; } diff --git a/include/blt/gfx/renderer/2d_line.frag b/include/blt/gfx/renderer/2d_line.frag index 7988219..1baea84 100644 --- a/include/blt/gfx/renderer/2d_line.frag +++ b/include/blt/gfx/renderer/2d_line.frag @@ -17,7 +17,7 @@ vec4 linear_iter(vec4 i, vec4 p, float factor){ } void main() { - FragColor = (texture(tex, uv) * use_texture) + color; + FragColor = color; } ")"; diff --git a/include/blt/gfx/renderer/2d_line.vert b/include/blt/gfx/renderer/2d_line.vert index 5b7fef8..aebc22c 100644 --- a/include/blt/gfx/renderer/2d_line.vert +++ b/include/blt/gfx/renderer/2d_line.vert @@ -1,14 +1,12 @@ #ifdef __cplusplus #include const std::string shader_2d_line_vert = R"(" -#version 300 es -precision mediump float; +#version 460 -layout (location = 0) in vec3 vertex; -layout (location = 1) in vec2 uv_in; - -out vec2 pos; -out vec2 uv; +layout(std430, binding = 0) buffer TVertex +{ + vec4 vertex[]; +}; layout (std140) uniform GlobalMatrices { @@ -18,14 +16,46 @@ layout (std140) uniform GlobalMatrices mat4 pvm; mat4 ovm; }; +uniform vec2 u_resolution; +uniform float u_thickness; -uniform mat4 model; +void main() +{ + int line_i = gl_VertexID / 6; + int tri_i = gl_VertexID % 6; -void main() { - gl_Position = ortho * model * vec4(vertex, 1.0); - pos = vertex.xy; - uv = uv_in; + vec4 va[4]; + for (int i=0; i<4; ++i) + { + va[i] = ovm * vertex[line_i+i]; + va[i].xyz /= va[i].w; + va[i].xy = (va[i].xy + 1.0) * 0.5 * u_resolution; + } + + vec2 v_line = normalize(va[2].xy - va[1].xy); + vec2 nv_line = vec2(-v_line.y, v_line.x); + + vec4 pos; + if (tri_i == 0 || tri_i == 1 || tri_i == 3) + { + vec2 v_pred = normalize(va[1].xy - va[0].xy); + vec2 v_miter = normalize(nv_line + vec2(-v_pred.y, v_pred.x)); + + pos = va[1]; + pos.xy += v_miter * u_thickness * (tri_i == 1 ? -0.5 : 0.5) / dot(v_miter, nv_line); + } + else + { + vec2 v_succ = normalize(va[3].xy - va[2].xy); + vec2 v_miter = normalize(nv_line + vec2(-v_succ.y, v_succ.x)); + + pos = va[2]; + pos.xy += v_miter * u_thickness * (tri_i == 5 ? 0.5 : -0.5) / dot(v_miter, nv_line); + } + + pos.xy = pos.xy / u_resolution * 2.0 - 1.0; + pos.xyz *= pos.w; + gl_Position = pos; } - ")"; #endif \ No newline at end of file diff --git a/include/blt/gfx/renderer/batch_2d_renderer.h b/include/blt/gfx/renderer/batch_2d_renderer.h index 7caaac7..678b8c4 100644 --- a/include/blt/gfx/renderer/batch_2d_renderer.h +++ b/include/blt/gfx/renderer/batch_2d_renderer.h @@ -53,12 +53,19 @@ namespace blt::gfx { blt::vec2f p1; blt::vec2f p2; + float thickness = 1; line2d_t(float px1, float py1, float px2, float 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::vec2f p1, blt::vec2f p2, float thickness): p1(p1), p2(p2), thickness(thickness) + {} }; struct point2d_t @@ -105,8 +112,7 @@ namespace blt::gfx // 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; - // color -> blend factor -> list of lines - blt::hashmap_t, vec_hash>, vec_hash> complex_lines; + blt::hashmap_t, vec_hash>, vec_hash>> complex_lines; size_t draw_count_ = 0; public: explicit batch_renderer_2d(resource_manager& resources): resources(resources) @@ -132,15 +138,22 @@ namespace blt::gfx complex_rectangles[draw_info.texture_name][draw_info.color][draw_info.blend].push_back(rectangle); } + inline void drawLine(std::string_view texture, const line2d_t& line) + { + const static blt::vec4 empty{0, 0, 0, 1}; + const static blt::vec4 full{1, 1, 1, 1}; + complex_lines[texture][empty][full].push_back(line); + } + inline void drawLine(const blt::vec4& color, const line2d_t& line) { const static blt::vec4 empty{0, 0, 0, 0}; - complex_lines[color][empty].push_back(line); + complex_lines[""][color][empty].push_back(line); } inline void drawLine(const draw_state& draw_info, const line2d_t& line) { - complex_lines[draw_info.color][draw_info.blend].push_back(line); + complex_lines[draw_info.texture_name][draw_info.color][draw_info.blend].push_back(line); } inline void drawPoint(std::string_view texture, const point2d_t& point) 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 c49f355..8d3c5f0 100644 --- a/src/blt/gfx/renderer/batch_2d_renderer.cpp +++ b/src/blt/gfx/renderer/batch_2d_renderer.cpp @@ -34,6 +34,19 @@ const unsigned int square_indices[6] = { 1, 2, 3 // second triangle }; +float line_vertices[20] = { + // positions // texture coords + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left + -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left +}; + +// 0, 1 (top right) +// 5, 6 (bottom right) +// 10, 11 (bottom left) +// 15, 16 (top left) + namespace blt::gfx { @@ -55,10 +68,19 @@ namespace blt::gfx square_vao->bindElement(indices_vbo); } { - ssbo_t vertex_data; + vbo_t vertices_vbo; + ebo_t indices_vbo; - vertex_data.create(); + vertices_vbo.create(); + indices_vbo.create(); + vertices_vbo.allocate(sizeof(line_vertices), line_vertices); + indices_vbo.allocate(sizeof(square_indices), square_indices); + + line_vao = new vertex_array(); + auto tb = line_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0); + line_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float)); + line_vao->bindElement(indices_vbo); } square_shader = new shader_t(shader_2d_textured_vert, shader_2d_textured_frag); @@ -113,6 +135,62 @@ namespace blt::gfx } textures.second.clear(); } + + blt::mat4x4 model; + square_shader->setMatrix("model", model); + line_vao->bind(); + auto& buf = line_vao->getBuffer(0); + buf.bind(); + for (auto& textures : complex_lines) + { + // resource manager handles the check for empty string + if (auto val = resources.get(textures.first)) + val.value()->bind(); + for (auto& colors : textures.second) + { + square_shader->setVec4("color", colors.first); + for (auto& blend_factors : colors.second) + { + square_shader->setVec4("use_texture", blend_factors.first); + for (auto& line : blend_factors.second) + { + // 0, 1 (top right) + // 5, 6 (bottom right) + // 10, 11 (bottom left) + // 15, 16 (top left) + blt::vec2 dir = (line.p1 - line.p2).normalize(); + blt::vec2 right = {dir.y(), -dir.x()}; + blt::vec2 left = {-dir.y(), dir.x()}; + + auto bottom_left = line.p1 + left * line.thickness; + auto bottom_right = line.p1 + right * line.thickness; + + auto top_left = line.p2 + left * line.thickness; + auto top_right = line.p2 + right * line.thickness; + + line_vertices[0] = top_right.x(); + line_vertices[1] = top_right.y(); + + line_vertices[5] = bottom_right.x(); + line_vertices[6] = bottom_right.y(); + + line_vertices[10] = bottom_left.x(); + line_vertices[11] = bottom_left.y(); + + line_vertices[15] = top_left.x(); + line_vertices[16] = top_left.y(); + + buf.update(sizeof(line_vertices), line_vertices); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + draw_count_++; + } + blend_factors.second.clear(); + } + colors.second.clear(); + } + textures.second.clear(); + } if (transparency) glDisable(GL_BLEND); }