always pass the parameters and verify that they're correct

This commit is contained in:
Konstantin Käfer
2014-02-05 18:46:23 +01:00
parent e94cb1b00b
commit eabd99d8f6
4 changed files with 40 additions and 64 deletions

View File

@@ -3,38 +3,50 @@
#include <llmr/platform/gl.hpp>
#include <cassert>
#include <stdexcept>
namespace llmr {
class VertexArrayObject {
public:
template <typename Shader, typename VertexBuffer>
inline void setup(Shader& shader, VertexBuffer& vertex_buffer, char *vertex_offset) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
void bind(Shader& shader, VertexBuffer& vertex_buffer, char *vertex_offset) {
if (!vao) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
vertex_buffer.bind();
shader.bind_vertex(vertex_offset);
vertex_buffer.bind();
shader.bind_vertex(vertex_offset);
program = shader.program;
buffer = &vertex_buffer;
offset = vertex_offset;
} else if (program != shader.program) {
throw std::runtime_error("trying to bind VAO to different program");
} else if (buffer != &vertex_buffer) {
throw std::runtime_error("trying to bind VAO to another buffer");
} else if (offset != vertex_offset) {
throw std::runtime_error("trying to bind VAO to another offset");
} else {
// This is the correct program for this VAO.
glBindVertexArray(vao);
}
}
inline ~VertexArrayObject() {
~VertexArrayObject() {
if (vao) {
glDeleteVertexArrays(1, &vao);
}
}
inline operator bool() const {
return vao != 0;
}
inline void bind() {
assert(vao);
glBindVertexArray(vao);
}
private:
GLuint vao = 0;
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
GLuint program = 0;
void *buffer = NULL;
char *offset = 0;
};
}

View File

@@ -66,11 +66,7 @@ void FillBucket::drawElements(Shader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
char *elements_index = BUFFER_OFFSET(elements_start * 3 * sizeof(int16_t));
for (group& group : groups) {
if (!group.array) {
group.array.setup(shader, *buffer, vertex_index);
} else {
group.array.bind();
}
group.array.bind(shader, *buffer, vertex_index);
glDrawElements(GL_TRIANGLES, group.elements_length * 3 - 3, GL_UNSIGNED_SHORT, elements_index);
vertex_index += group.vertex_length * 2 * sizeof(uint16_t);
elements_index += group.elements_length * 3 * sizeof(uint16_t);
@@ -80,12 +76,8 @@ void FillBucket::drawElements(Shader& shader) {
template <typename Shader>
void FillBucket::drawVertices(Shader& shader) {
// Draw the entire line
if (!array) {
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
array.setup(shader, *buffer, vertex_index);
} else {
array.bind();
}
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
array.bind(shader, *buffer, vertex_index);
glDrawArrays(GL_LINE_STRIP, 0, length);
}

View File

@@ -270,12 +270,8 @@ size_t LineBucket::size() const {
}
void LineBucket::bind(LineShader& shader) {
if (!array) {
char *vertex_index = BUFFER_OFFSET(start * 4 * sizeof(int16_t));
array.setup(shader, *buffer, vertex_index);
} else {
array.bind();
}
char *vertex_index = BUFFER_OFFSET(start * 4 * sizeof(int16_t));
array.bind(shader, *buffer, vertex_index);
}
void LineBucket::drawLines() {

View File

@@ -93,11 +93,8 @@ void Painter::drawClippingMask() {
glStencilMask(0xC0);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
if (!tileStencilArray) {
tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
} else {
tileStencilArray.bind();
}
tileStencilArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
// Draw the clipping mask
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
@@ -281,11 +278,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
glUniform4fv(fillShader->u_color, 1, fill_color.data());
// Draw a rectangle that covers the entire viewport.
if (!tileStencilArray) {
tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
} else {
tileStencilArray.bind();
}
tileStencilArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}
@@ -373,21 +366,13 @@ void Painter::renderDebug(const Tile::Ptr& tile) {
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
// draw tile outline
if (!tileBorderArray) {
tileBorderArray.setup(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
} else {
tileBorderArray.bind();
}
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(4.0f);
glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.length());
// draw debug info
if (!tile->debugFontArray) {
tile->debugFontArray.setup(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0));
} else {
tile->debugFontArray.bind();
}
tile->debugFontArray.bind(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
glLineWidth(4.0f);
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.length());
@@ -407,13 +392,8 @@ void Painter::renderMatte() {
glUseProgram(plainShader->program);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, nativeMatrix.data());
if (!matteArray) {
matteArray.setup(*plainShader, matteBuffer, BUFFER_OFFSET(0));
} else {
matteArray.bind();
}
// Draw the clipping mask
matteArray.bind(*plainShader, matteBuffer, BUFFER_OFFSET(0));
glUniform4fv(plainShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, matteBuffer.length());
@@ -427,11 +407,7 @@ void Painter::renderBackground() {
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
// Draw the clipping mask
if (!tileStencilArray) {
tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
} else {
tileStencilArray.bind();
}
tileStencilArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
glUniform4fv(plainShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}