/* * * Copyright (C) 2023 Brett Terpstra * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H #define BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H #include "blt/gfx/model.h" #include "blt/gfx/shader.h" #include "blt/gfx/renderer/resource_manager.h" #include #include #include #include #include #include namespace blt::gfx { struct rectangle2d_t { float x, y, width, height, 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): x(x), y(y), width(width), height(height) {} }; struct draw_state { // texture to use std::string texture_name; // color to use blt::vec4 color; // how much to blend the texture into the color? note blending is always additive! blt::vec4 blend; }; class batch_renderer_2d { private: struct vec_hash { 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()); } }; private: vertex_array* square_vao = nullptr; shader_t* shader = nullptr; resource_manager& resources; blt::hashmap_t, vec_hash>, vec_hash>> complex_rectangles; size_t draw_count_ = 0; public: explicit batch_renderer_2d(resource_manager& resources): resources(resources) {} void create(); inline void drawRectangle(std::string_view texture, const rectangle2d_t& rectangle) { const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 full{1, 1, 1, 1}; complex_rectangles[texture][empty][full].push_back(rectangle); } inline void drawRectangle(const blt::vec4& color, const rectangle2d_t& rectangle) { const static blt::vec4 empty{0, 0, 0, 0}; complex_rectangles[""][color][empty].push_back(rectangle); } inline void drawRectangle(const draw_state& draw_info, const rectangle2d_t& rectangle) { complex_rectangles[draw_info.texture_name][draw_info.color][draw_info.blend].push_back(rectangle); } template inline void drawRectangle(const T& render_info, P... p) { drawRectangle(render_info, {p...}); } void render(bool transparency = true); void cleanup(); [[nodiscard]] inline size_t draw_count() { return draw_count_; } }; } #endif //BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H