move static global buffers to RAII

This commit is contained in:
Konstantin Käfer
2014-01-29 15:31:22 +01:00
parent 3f9337b74c
commit 2b59dfae63
5 changed files with 113 additions and 70 deletions

View File

@@ -0,0 +1,33 @@
#ifndef LLMR_GEOMETRY_VERTEX_BUFFER
#define LLMR_GEOMETRY_VERTEX_BUFFER
#include <vector>
#include <cmath>
namespace llmr {
class VertexBuffer {
public:
VertexBuffer(std::initializer_list<int16_t> init);
~VertexBuffer();
/*
* Returns the number of elements in this buffer. This is not the number of
* bytes, but rather the number of coordinates with associated information.
*/
uint32_t length() const;
/*
* Transfers this buffer to the GPU and binds the buffer to the GL context.
*/
void bind();
private:
const std::vector<int16_t> array;
uint32_t buffer = 0;
};
}
#endif

View File

@@ -7,6 +7,7 @@
#include "shader-line.hpp"
#include "../map/tile.hpp"
#include "../geometry/vertex_buffer.hpp"
#include "../util/mat4.hpp"
namespace llmr {
@@ -26,12 +27,11 @@ public:
// Make noncopyable
Painter(const Painter&) = delete;
Painter(const Painter&&) = delete;
Painter &operator=(const Painter&) = delete;
Painter &operator=(const Painter&&) = delete;
Painter& operator=(const Painter&) = delete;
Painter& operator=(const Painter && ) = delete;
void setup();
void teardown();
void clear();
void render(const std::shared_ptr<Tile>& tile);
@@ -68,9 +68,41 @@ private:
std::shared_ptr<OutlineShader> outlineShader;
std::shared_ptr<LineShader> lineShader;
uint32_t tile_stencil_buffer;
uint32_t tile_border_buffer;
uint32_t matte_buffer;
// Set up the stencil quad we're using to generate the stencil mask.
VertexBuffer tileStencilBuffer = {
// top left triangle
0, 0,
4096, 0,
0, 4096,
// bottom right triangle
4096, 0,
0, 4096,
4096, 4096
};
// Set up the tile boundary lines we're using to draw the tile outlines.
VertexBuffer tileBorderBuffer = {
0, 0,
4096, 0,
4096, 4096,
0, 4096,
0, 0
};
// Set up the matte buffer we're using to draw the filling background.
VertexBuffer matteBuffer = {
// top left triangle
0, 0,
16384, 0,
0, 16384,
// bottom right triangle
16384, 0,
0, 16384,
16384, 16384
};
};
}

View File

@@ -2,6 +2,7 @@ SET(llmr_SOURCES
geometry/debug_font_buffer.cpp
geometry/fill_buffer.cpp
geometry/line_buffer.cpp
geometry/vertex_buffer.cpp
map/map.cpp
map/tile.cpp
map/transform.cpp
@@ -29,6 +30,7 @@ SET(llmr_HEADERS
../include/llmr/geometry/debug_font_buffer.hpp
../include/llmr/geometry/fill_buffer.hpp
../include/llmr/geometry/line_buffer.hpp
../include/llmr/geometry/vertex_buffer.hpp
../include/llmr/llmr.hpp
../include/llmr/map/map.hpp
../include/llmr/map/tile.hpp

View File

@@ -0,0 +1,30 @@
#include <llmr/geometry/vertex_buffer.hpp>
#include <llmr/platform/gl.hpp>
using namespace llmr;
VertexBuffer::VertexBuffer(std::initializer_list<int16_t> init) : array(init) {}
VertexBuffer::~VertexBuffer() {
if (buffer != 0) {
glDeleteBuffers(1, &buffer);
buffer = 0;
}
}
uint32_t VertexBuffer::length() const {
// We store 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes)
return array.size() / 2;
}
void VertexBuffer::bind() {
if (buffer == 0) {
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(int16_t), array.data(), GL_STATIC_DRAW);
} else {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
}
}

View File

@@ -20,38 +20,6 @@ using namespace llmr;
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
GLshort tile_stencil_vertices[] = {
// top left triangle
0, 0,
4096, 0,
0, 4096,
// bottom right triangle
4096, 0,
0, 4096,
4096, 4096
};
GLshort tile_border_vertices[] = {
0, 0,
4096, 0,
4096, 4096,
0, 4096,
0, 0
};
GLshort matte_vertices[] = {
// top left triangle
0, 0,
16384, 0,
0, 16384,
// bottom right triangle
16384, 0,
0, 16384,
16384, 16384
};
Painter::Painter(Transform& transform, Settings& settings, Style& style)
: transform(transform),
settings(settings),
@@ -68,22 +36,6 @@ void Painter::setup() {
assert(outlineShader);
assert(lineShader);
// Set up the stencil quad we're using to generate the stencil mask.
glGenBuffers(1, &tile_stencil_buffer);
glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(tile_stencil_vertices), tile_stencil_vertices, GL_STATIC_DRAW);
// Set up the tile boundary lines we're using to draw the tile outlines.
glGenBuffers(1, &tile_border_buffer);
glBindBuffer(GL_ARRAY_BUFFER, tile_border_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(tile_border_vertices), tile_border_vertices, GL_STATIC_DRAW);
// Set up the tile boundary lines we're using to draw the tile outlines.
glGenBuffers(1, &matte_buffer);
glBindBuffer(GL_ARRAY_BUFFER, matte_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(matte_vertices), matte_vertices, GL_STATIC_DRAW);
glEnable(GL_STENCIL_TEST);
// We are blending the new pixels *behind* the existing pixels. That way we can
@@ -99,12 +51,6 @@ void Painter::setupShaders() {
lineShader = std::make_shared<LineShader>();
}
void Painter::teardown() {
glDeleteBuffers(1, &tile_stencil_buffer);
glDeleteBuffers(1, &tile_border_buffer);
glDeleteBuffers(1, &matte_buffer);
}
void Painter::changeMatrix(const Tile::Ptr& tile) {
// Initialize projection matrix
mat4 projMatrix;
@@ -148,10 +94,10 @@ void Painter::drawClippingMask() {
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
// Draw the clipping mask
glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer);
tileStencilBuffer.bind();
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, sizeof(tile_stencil_vertices));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
// glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 0x80, 0x80);
@@ -329,9 +275,9 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name) {
glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F);
// Draw a rectangle that covers the entire viewport.
glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer);
tileStencilBuffer.bind();
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, sizeof(tile_stencil_vertices));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
glStencilMask(0x00);
glStencilFunc(GL_EQUAL, 0x80, 0x80);
@@ -422,11 +368,11 @@ void Painter::renderDebug(const Tile::Ptr& tile) {
// draw tile outline
switchShader(plainShader);
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
glBindBuffer(GL_ARRAY_BUFFER, tile_border_buffer);
tileBorderBuffer.bind();
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
glLineWidth(4.0f);
glDrawArrays(GL_LINE_STRIP, 0, sizeof(tile_border_vertices));
glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.length());
// draw debug info
switchShader(plainShader);
@@ -453,10 +399,10 @@ void Painter::renderMatte() {
Color white = {{ 1, 1, 1, 1 }};
// Draw the clipping mask
glBindBuffer(GL_ARRAY_BUFFER, matte_buffer);
matteBuffer.bind();
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4fv(fillShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, sizeof(matte_vertices));
glDrawArrays(GL_TRIANGLES, 0, matteBuffer.length());
glEnable(GL_STENCIL_TEST);
}
@@ -468,10 +414,10 @@ void Painter::renderBackground() {
Color white = {{ 1, 1, 1, 1 }};
// Draw the clipping mask
glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer);
tileStencilBuffer.bind();
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
glUniform4fv(fillShader->u_color, 1, white.data());
glDrawArrays(GL_TRIANGLES, 0, sizeof(tile_stencil_vertices));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
}