#include #include "shape_renderer.h" #include "debug/debug_stats.h" #include "math/math.h" ShapeRenderer::ShapeRenderer(unsigned int screen_width, unsigned int screen_height) { math::ortho_proj(_projection, 0.0f, (float)screen_width, 0.0f, (float)screen_height, -1.0f, 1.0f); /* Load shader. */ _shape_shader = new Shader("assets/shaders/shape.vert", "assets/shaders/shape.frag"); _shape_shader->use(); _shape_shader->set_mat4("projection", _projection); /* Configure VAO/VBO for batch rendering. */ glGenVertexArrays(1, &_vao); glGenBuffers(1, &_vbo); glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(ShapeVertex) * MAX_SHAPE_VERTICES, nullptr, GL_DYNAMIC_DRAW); /* Position attribute. */ glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(ShapeVertex), (void*)0); /* Colour attribute. */ glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ShapeVertex), (void*)offsetof(ShapeVertex, r)); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); _vertices.reserve(MAX_SHAPE_VERTICES); } ShapeRenderer::~ShapeRenderer(void) { delete _shape_shader; } void ShapeRenderer::begin(void) { _vertices.clear(); } void ShapeRenderer::flush(void) { if(_vertices.empty()) return; _shape_shader->use(); glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, _vertices.size() * sizeof(ShapeVertex), _vertices.data()); DebugStats::draw_calls++; DebugStats::shape_vertices += _vertices.size(); glDrawArrays(GL_TRIANGLES, 0, _vertices.size()); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } void ShapeRenderer::draw_rect(int x, int y, int width, int height, const Color& color) { float x_f = (float)x; float y_f = (float)y; float w_f = (float)width; float h_f = (float)height; _vertices.push_back({x_f, y_f+h_f, color.r, color.g, color.b}); _vertices.push_back({x_f, y_f, color.r, color.g, color.b}); _vertices.push_back({x_f+w_f, y_f, color.r, color.g, color.b}); _vertices.push_back({x_f, y_f+h_f, color.r, color.g, color.b}); _vertices.push_back({x_f+w_f, y_f, color.r, color.g, color.b}); _vertices.push_back({x_f+w_f, y_f+h_f, color.r, color.g, color.b}); } void ShapeRenderer::draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, const Color& color) { _vertices.push_back({(float)x1, (float)y1, color.r, color.g, color.b}); _vertices.push_back({(float)x2, (float)y2, color.r, color.g, color.b}); _vertices.push_back({(float)x3, (float)y3, color.r, color.g, color.b}); }