This mirrors the previous refactor of the TextRenderer. All calls to draw_rect and draw_triangle now buffer vertex data (position and color). A begin()/flush() system is introduced to manage batching.
83 lines
2.7 KiB
C++
83 lines
2.7 KiB
C++
#include <GL/glew.h>
|
|
|
|
#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});
|
|
}
|