Last active
December 20, 2016 08:12
-
-
Save jacobmilligan/860ef9b41b43b6612732379ea60aebde to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RenderBatch.hpp | |
// Disco Rocket Library | |
// | |
// ---------------------------------------------------------------------------- | |
// | |
// Created by Jacob Milligan on 9/12/2016. | |
// Copyright (c) 2016 Jacob Milligan All rights reserved. | |
// | |
#ifndef DISCO_ROCKET_RENDERBATCH_HPP | |
#define DISCO_ROCKET_RENDERBATCH_HPP | |
#include <array> | |
#include "DiscoRocket/Core/Math/Matrix4.hpp" | |
#include "DiscoRocket/Platform/DiscoGL.hpp" | |
#include "DiscoRocket/Graphics/Shader.hpp" | |
#include "DiscoRocket/Graphics/RenderData.hpp" | |
namespace disco { | |
struct Rectangle; | |
struct Color; | |
class Camera; | |
class Window; | |
struct Vertex { | |
float x; | |
float y; | |
float z; | |
uint8_t r; | |
uint8_t g; | |
uint8_t b; | |
uint8_t a; | |
}; | |
class RenderBatch { | |
public: | |
static constexpr int batch_max = 4096; | |
RenderBatch(const Window& window); | |
RenderBatch(const Vector2& view_size); | |
RenderBatch(const int view_width, const int view_height); | |
~RenderBatch(); | |
void start(); | |
void finish(); | |
void fill_rectangle(const Rectangle& rect, const Color& color); | |
private: | |
int next_, draw_calls_; | |
static constexpr int num_vertices_ = batch_max * 4; | |
static constexpr int num_indices_ = batch_max * 6; | |
Matrix4 projection_; | |
Matrix4 view_; | |
// Debug uniforms | |
GLint projloc_; | |
// Primitive VAOs | |
GLuint quad_VAO_; | |
std::array<GLuint, 2> bufobjs_; | |
std::array<Vertex, num_vertices_> vertices_; | |
std::array<GLuint, num_indices_> indices_; | |
Shader debug_shader_; | |
}; | |
} | |
#endif //DISCO_ROCKET_RENDERBATCH_HPP | |
// | |
// RenderBatch.cpp | |
// Disco Rocket Library | |
// | |
// ---------------------------------------------------------------------------- | |
// | |
// Created by Jacob Milligan on 9/12/2016. | |
// Copyright (c) 2016 Jacob Milligan All rights reserved. | |
// | |
#include "DiscoRocket/Graphics/RenderBatch.hpp" | |
#include "DiscoRocket/Graphics/DebugShaders.hpp" | |
#include "DiscoRocket/Graphics/Rectangle.hpp" | |
#include "DiscoRocket/Graphics/Window.hpp" | |
namespace disco { | |
RenderBatch::RenderBatch(const int view_width, const int view_height) | |
: RenderBatch(Vector2(view_width, view_height)) {} | |
RenderBatch::RenderBatch(const Window& window) | |
: RenderBatch(window.size()) {} | |
RenderBatch::RenderBatch(const Vector2& view_size) | |
: next_(0) | |
{ | |
GLuint vert = 0, indices_per_vert = 6; | |
for(GLuint i = 0; i < indices_.size(); i += indices_per_vert) | |
{ | |
vert = i * 4; | |
indices_[i] = vert; | |
indices_[i + 1] = 1 + vert; | |
indices_[i + 2] = 2 + vert; | |
indices_[i + 3] = vert; | |
indices_[i + 4] = 2 + vert; | |
indices_[i + 5] = 3 + vert; | |
} | |
glGenVertexArrays(1, &quad_VAO_); | |
glGenBuffers(2, bufobjs_.data()); | |
glBindVertexArray(quad_VAO_); | |
glBindBuffer(GL_ARRAY_BUFFER, bufobjs_[0]); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_), vertices_.data(), | |
GL_DYNAMIC_DRAW); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufobjs_[1]); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices_), indices_.data(), | |
GL_DYNAMIC_DRAW); | |
glEnableVertexAttribArray(0); | |
glEnableVertexAttribArray(1); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); | |
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), | |
(GLvoid*)offsetof(Vertex, r)); | |
glBindVertexArray(0); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
// For debugging purposes | |
projection_ = projection_.ortho(0.0f, view_size.x, view_size.y, 0.0f); | |
debug_shader_.compile(debug_shader_vert, debug_shader_frag); | |
projloc_ = glGetUniformLocation(debug_shader_.id, "projection"); | |
viewloc_ = glGetUniformLocation(debug_shader_.id, "view"); | |
debug_shader_.use(); | |
glUniformMatrix4fv(projloc_, 1, GL_FALSE, &projection_[0][0]); | |
glUniformMatrix4fv(viewloc_, 1, GL_FALSE, &view_[0][0]); | |
} | |
RenderBatch::~RenderBatch() | |
{ | |
glDeleteBuffers(2, bufobjs_.data()); | |
glDeleteVertexArrays(1, &quad_VAO_); | |
} | |
void RenderBatch::start() | |
{ | |
next_ = 0; | |
draw_calls_ = 0; | |
glBindVertexArray(quad_VAO_); | |
glBindBuffer(GL_ARRAY_BUFFER, bufobjs_[0]); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufobjs_[1]); | |
} | |
void RenderBatch::finish() | |
{ | |
if ( draw_calls_ <= 0 ) | |
return; | |
glBufferSubData(GL_ARRAY_BUFFER, 0, | |
next_ * sizeof(Vertex), vertices_.data()); | |
glDrawElements(GL_TRIANGLES, draw_calls_ * 6, GL_UNSIGNED_INT, nullptr); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
glBindVertexArray(0); | |
disco_gl_get_error(); | |
} | |
void RenderBatch::fill_rectangle(const Rectangle& rect, const Color& color) | |
{ | |
auto scaled_alpha = static_cast<uint8_t>(color.a * 255.0f); // scale from normalized to 0-255 value | |
// Top left | |
auto v = &vertices_[next_++]; | |
v->r = color.r; | |
v->g = color.g; | |
v->b = color.b; | |
v->a = scaled_alpha; | |
v->x = rect.position.x; | |
v->y = rect.position.y; | |
v->z = 0.0f; | |
// Top right | |
v = &vertices_[next_++]; | |
v->r = color.r; | |
v->g = color.g; | |
v->b = color.b; | |
v->a = scaled_alpha; | |
v->x = rect.position.x + rect.width; | |
v->y = rect.position.y; | |
v->z = 0.0f; | |
// Bottom right | |
v = &vertices_[next_++]; | |
v->r = color.r; | |
v->g = color.g; | |
v->b = color.b; | |
v->a = scaled_alpha; | |
v->x = rect.position.x + rect.width; | |
v->y = rect.position.y + rect.height; | |
v->z = 0.0f; | |
// Bottom left | |
v = &vertices_[next_++]; | |
v->r = color.r; | |
v->g = color.g; | |
v->b = color.b; | |
v->a = scaled_alpha; | |
v->x = rect.position.x; | |
v->y = rect.position.y + rect.height; | |
v->z = 0.0f; | |
draw_calls_++; | |
if ( next_ >= vertices_.size() ) { | |
finish(); | |
start(); | |
} | |
} | |
} | |
// | |
// DebugShaders.hpp | |
// Disco Rocket Library | |
// | |
// ---------------------------------------------------------------------------- | |
// | |
// Created by Jacob Milligan on 9/12/2016. | |
// Copyright (c) 2016 Jacob Milligan All rights reserved. | |
// | |
#ifndef DISCO_ROCKET_DEBUGSHADERS_HPP | |
#define DISCO_ROCKET_DEBUGSHADERS_HPP | |
namespace disco { | |
static const char* debug_shader_vert = R"( | |
#version 330 core | |
layout (location = 0) in vec3 position; | |
layout (location = 1) in vec4 color; | |
out vec4 frag_color; | |
uniform mat4 projection; | |
void main() { | |
gl_Position = projection * vec4(position, 1.0f); | |
frag_color = color; | |
} | |
)"; | |
static const char* debug_shader_frag = R"( | |
#version 330 core | |
out vec4 color; | |
in vec4 frag_color; | |
void main() { | |
color = frag_color; | |
} | |
)"; | |
} | |
#endif //DISCO_ROCKET_DEBUGSHADERS_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment