diff --git a/CMakeLists.txt b/CMakeLists.txt index 87a3427..2d39e6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.25) -set(BLT_GRAPHICS_VERSION 0.9.4) +set(BLT_GRAPHICS_VERSION 0.9.5) 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 021db13..17b7293 100644 --- a/include/blt/gfx/model.h +++ b/include/blt/gfx/model.h @@ -28,33 +28,61 @@ namespace blt::gfx { + struct vbo_t_owner; + + class static_dynamic_array; + + class vertex_array; struct vbo_t { - GLuint bufferID_ = 0; - GLsizeiptr size_ = 0; - GLint buffer_type = 0; - GLint memory_type = 0; - - void create(GLint type = GL_ARRAY_BUFFER); - - void bind() const; - - void unbind() const; - - void allocate(GLsizeiptr size, GLint mem_type = GL_STATIC_DRAW, const void* data = nullptr); - - template - void allocate(GLsizeiptr size, const T* data, GLint mem_type = GL_STATIC_DRAW) - { - allocate(size, mem_type, static_cast(data)); - } - - void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data) const; - - void update(GLsizeiptr size, void* data); - - void destroy(); + friend vbo_t_owner; + friend vertex_array; + friend static_dynamic_array; + private: + GLuint bufferID_ = 0; + GLsizeiptr size_ = 0; + GLint buffer_type = 0; + GLint memory_type = 0; + public: + + void create(GLint type = GL_ARRAY_BUFFER); + + void bind() const; + + void unbind() const; + + void allocate(GLsizeiptr size, GLint mem_type = GL_STATIC_DRAW, const void* data = nullptr); + + template + void allocate(GLsizeiptr size, const T* data, GLint mem_type = GL_STATIC_DRAW) + { + allocate(size, mem_type, static_cast(data)); + } + + void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data) const; + + void update(GLsizeiptr size, void* data); + + void destroy(); + }; + + struct ssbo_t : public vbo_t + { + public: + inline void create() + { + vbo_t::create(GL_SHADER_STORAGE_BUFFER); + } + }; + + struct ebo_t : public vbo_t + { + public: + inline void create() + { + vbo_t::create(GL_ELEMENT_ARRAY_BUFFER); + } }; struct vbo_t_owner diff --git a/include/blt/gfx/renderer/2d_line.frag b/include/blt/gfx/renderer/2d_line.frag new file mode 100644 index 0000000..7988219 --- /dev/null +++ b/include/blt/gfx/renderer/2d_line.frag @@ -0,0 +1,24 @@ +#ifdef __cplusplus +#include +const std::string shader_2d_line_frag = R"(" +#version 300 es +precision mediump float; + +out vec4 FragColor; +in vec2 uv; +in vec2 pos; + +uniform sampler2D tex; +uniform vec4 color; +uniform vec4 use_texture; + +vec4 linear_iter(vec4 i, vec4 p, float factor){ + return (i + p) * factor; +} + +void main() { + FragColor = (texture(tex, uv) * use_texture) + color; +} + +")"; +#endif \ No newline at end of file diff --git a/include/blt/gfx/renderer/2d_line.vert b/include/blt/gfx/renderer/2d_line.vert new file mode 100644 index 0000000..5b7fef8 --- /dev/null +++ b/include/blt/gfx/renderer/2d_line.vert @@ -0,0 +1,31 @@ +#ifdef __cplusplus +#include +const std::string shader_2d_line_vert = R"(" +#version 300 es +precision mediump float; + +layout (location = 0) in vec3 vertex; +layout (location = 1) in vec2 uv_in; + +out vec2 pos; +out vec2 uv; + +layout (std140) uniform GlobalMatrices +{ + mat4 projection; + mat4 ortho; + mat4 view; + mat4 pvm; + mat4 ovm; +}; + +uniform mat4 model; + +void main() { + gl_Position = ortho * model * vec4(vertex, 1.0); + pos = vertex.xy; + uv = uv_in; +} + +")"; +#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 38337c3..7caaac7 100644 --- a/include/blt/gfx/renderer/batch_2d_renderer.h +++ b/include/blt/gfx/renderer/batch_2d_renderer.h @@ -33,12 +33,43 @@ namespace blt::gfx { struct rectangle2d_t { - float x, y, width, height, rotation = 0; + blt::vec2f pos, size; + float rotation = 0; - rectangle2d_t(float x, float y, float width, float height, float rotation): x(x), y(y), width(width), height(height), rotation(rotation) + rectangle2d_t(float x, float y, float width, float height, float rotation): pos(x, y), size(width, height), rotation(rotation) {} - rectangle2d_t(float x, float y, float width, float height): x(x), y(y), width(width), height(height) + rectangle2d_t(float x, float y, float width, float 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): pos(pos), size(size) + {} + }; + + struct line2d_t + { + blt::vec2f p1; + blt::vec2f p2; + + 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) + {} + }; + + struct point2d_t + { + blt::vec2f pos; + float scale = 1; + + point2d_t(float x, float y, float scale): pos(x, y), scale(scale) + {} + + point2d_t(float x, float y): pos(x, y) {} }; @@ -60,16 +91,22 @@ namespace blt::gfx std::size_t operator()(const blt::vec4& key) const { using namespace blt::mem; - return type_cast(key.x()) ^ type_cast(key.y()) ^ type_cast(key.y()) ^ - type_cast(key.z()); + return type_cast(key.x()) ^ type_cast(key.y()) ^ type_cast(key.y()) ^ type_cast(key.z()); } }; private: vertex_array* square_vao = nullptr; - shader_t* shader = nullptr; + vertex_array* line_vao = nullptr; + shader_t* square_shader = nullptr; + shader_t* line_shader = nullptr; + shader_t* point_shader = nullptr; resource_manager& resources; + // 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; size_t draw_count_ = 0; public: explicit batch_renderer_2d(resource_manager& resources): resources(resources) @@ -95,17 +132,58 @@ namespace blt::gfx complex_rectangles[draw_info.texture_name][draw_info.color][draw_info.blend].push_back(rectangle); } + 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); + } + + inline void drawLine(const draw_state& draw_info, const line2d_t& line) + { + complex_lines[draw_info.color][draw_info.blend].push_back(line); + } + + inline void drawPoint(std::string_view texture, const point2d_t& point) + { + const static blt::vec4 empty{0, 0, 0, 1}; + const static blt::vec4 full{1, 1, 1, 1}; + complex_points[texture][empty][full].push_back(point); + } + + inline void drawPoint(const blt::vec4& color, const point2d_t& point) + { + const static blt::vec4 empty{0, 0, 0, 0}; + complex_points[""][color][empty].push_back(point); + } + + inline void drawPoint(const draw_state& draw_info, const point2d_t& point) + { + complex_points[draw_info.texture_name][draw_info.color][draw_info.blend].push_back(point); + } + template inline void drawRectangle(const T& render_info, P... p) { drawRectangle(render_info, {p...}); } + template + inline void drawPoint(const T& render_info, P... p) + { + drawPoint(render_info, {p...}); + } + + template + inline void drawLine(const T& render_info, P... p) + { + drawLine(render_info, {p...}); + } + void render(bool transparency = true); void cleanup(); - [[nodiscard]] inline size_t draw_count() + [[nodiscard]] inline size_t draw_count() const { return draw_count_; } diff --git a/libraries/imgui b/libraries/imgui index a1b0682..231cbee 160000 --- a/libraries/imgui +++ b/libraries/imgui @@ -1 +1 @@ -Subproject commit a1b06823fe2d964a62fda99385499b218cf5cea5 +Subproject commit 231cbee0fc4f59dbe5b8b853a11b08dc84e57c65 diff --git a/libraries/openal-soft b/libraries/openal-soft index 6675317..111397c 160000 --- a/libraries/openal-soft +++ b/libraries/openal-soft @@ -1 +1 @@ -Subproject commit 6675317107257c2cc16c947b359d557821d85bf2 +Subproject commit 111397c71a5f1c2c88e05da9c84edfdba2e472a4 diff --git a/src/blt/gfx/renderer/batch_2d_renderer.cpp b/src/blt/gfx/renderer/batch_2d_renderer.cpp index e2791ba..c49f355 100644 --- a/src/blt/gfx/renderer/batch_2d_renderer.cpp +++ b/src/blt/gfx/renderer/batch_2d_renderer.cpp @@ -17,7 +17,10 @@ */ #include #include +#include #include +#include +// https://stackoverflow.com/questions/60440682/drawing-a-line-in-modern-opengl float square_vertices[20] = { // positions // texture coords @@ -36,29 +39,39 @@ namespace blt::gfx void batch_renderer_2d::create() { - vbo_t vertices_vbo; - vbo_t indices_vbo; + { + vbo_t vertices_vbo; + ebo_t indices_vbo; + + vertices_vbo.create(); + indices_vbo.create(); + + vertices_vbo.allocate(sizeof(square_vertices), square_vertices); + indices_vbo.allocate(sizeof(square_indices), square_indices); + + square_vao = new vertex_array(); + auto tb = square_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0); + square_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float)); + square_vao->bindElement(indices_vbo); + } + { + ssbo_t vertex_data; + + vertex_data.create(); + + } - vertices_vbo.create(); - indices_vbo.create(GL_ELEMENT_ARRAY_BUFFER); - - vertices_vbo.allocate(sizeof(square_vertices), square_vertices); - indices_vbo.allocate(sizeof(square_indices), square_indices); - - square_vao = new vertex_array(); - auto tb = square_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0); - square_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float)); - square_vao->bindElement(indices_vbo); - - shader = new shader_t(shader_2d_textured_vert, shader_2d_textured_frag); - shader->bindAttribute(0, "vertex"); - shader->bindAttribute(1, "uv_in"); + square_shader = new shader_t(shader_2d_textured_vert, shader_2d_textured_frag); + square_shader->bindAttribute(0, "vertex"); + square_shader->bindAttribute(1, "uv_in"); } void batch_renderer_2d::cleanup() { delete square_vao; - delete shader; + delete square_shader; + delete line_shader; + delete point_shader; } void batch_renderer_2d::render(bool transparency) @@ -69,7 +82,7 @@ namespace blt::gfx glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } draw_count_ = 0; - shader->bind(); + square_shader->bind(); square_vao->bind(); glActiveTexture(GL_TEXTURE0); for (auto& textures : complex_rectangles) @@ -79,18 +92,18 @@ namespace blt::gfx val.value()->bind(); for (auto& colors : textures.second) { - shader->setVec4("color", colors.first); + square_shader->setVec4("color", colors.first); for (auto& blend_factors : colors.second) { - shader->setVec4("use_texture", blend_factors.first); + square_shader->setVec4("use_texture", blend_factors.first); for (auto& rect : blend_factors.second) { blt::mat4x4 model; - model.translate(rect.x, rect.y, 0.0f); - model.scale(rect.width, rect.height, 1); + 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)); - shader->setMatrix("model", model); + square_shader->setMatrix("model", model); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); draw_count_++; }