allow switching the vao if we switch the style from plain color to pattern fill

This commit is contained in:
Konstantin Käfer
2014-02-18 15:56:23 +01:00
parent 004ff9ea10
commit ea80daa129
8 changed files with 47 additions and 29 deletions

View File

@@ -2,15 +2,12 @@
#define LLMR_GEOMETRY_TRIANGLE_ELEMENTS_BUFFER
#include <llmr/geometry/buffer.hpp>
#include <llmr/geometry/vao.hpp>
namespace llmr {
template <typename Shader>
class VertexArrayObject;
template <typename Shader>
struct ElementGroup {
VertexArrayObject<Shader> array;
VertexArrayObject array;
uint32_t vertex_length;
uint32_t elements_length;

View File

@@ -7,18 +7,26 @@
namespace llmr {
template <typename Shader>
class VertexArrayObject {
public:
template <typename VertexBuffer>
template <typename Shader, typename VertexBuffer>
void bind(Shader& shader, VertexBuffer& vertex_buffer, char *offset) {
if (!vao) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
} else {
// We have been given the correct information.
glBindVertexArray(vao);
}
if (shader_ptr != &shader) {
if (shader_ptr != nullptr) {
fprintf(stderr, "shader rebind!");
}
vertex_buffer.bind();
shader.bind(offset);
shader_ptr = &shader;
vertex_buffer_ptr = &vertex_buffer;
elements_buffer_ptr = nullptr;
offset_ptr = offset;
@@ -28,22 +36,25 @@ public:
throw std::runtime_error("trying to bind VAO to another elements buffer");
} else if (offset_ptr != offset) {
throw std::runtime_error("trying to bind VAO to another offset");
} else {
// We have been given the correct information.
glBindVertexArray(vao);
}
}
template <typename VertexBuffer, typename ElementsBuffer>
template <typename Shader, typename VertexBuffer, typename ElementsBuffer>
void bind(Shader& shader, VertexBuffer& vertex_buffer, ElementsBuffer& elements_buffer, char *offset) {
if (!vao) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
} else {
// We have been given the correct information.
glBindVertexArray(vao);
}
if (shader_ptr != &shader) {
vertex_buffer.bind();
elements_buffer.bind();
shader.bind(offset);
shader_ptr = &shader;
vertex_buffer_ptr = &vertex_buffer;
elements_buffer_ptr = &elements_buffer;
offset_ptr = offset;
@@ -53,9 +64,6 @@ public:
throw std::runtime_error("trying to bind VAO to another elements buffer");
} else if (offset_ptr != offset) {
throw std::runtime_error("trying to bind VAO to another offset");
} else {
// We have been given the correct information.
glBindVertexArray(vao);
}
}
@@ -70,6 +78,7 @@ private:
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
void *shader_ptr = nullptr;
void *vertex_buffer_ptr = nullptr;
void *elements_buffer_ptr = nullptr;
char *offset_ptr = 0;

View File

@@ -73,7 +73,7 @@ public:
// Holds the actual geometries in this tile.
DebugFontBuffer debugFontBuffer;
VertexArrayObject<PlainShader> debugFontArray;
VertexArrayObject debugFontArray;
std::shared_ptr<FillVertexBuffer> fillVertexBuffer;
std::shared_ptr<LineVertexBuffer> lineVertexBuffer;

View File

@@ -24,6 +24,7 @@ class LineElementsBuffer;
class BucketDescription;
class OutlineShader;
class PlainShader;
class PatternShader;
struct Coordinate;
struct pbf;
@@ -34,8 +35,8 @@ class FillBucket : public Bucket {
static void free(void *userData, void *ptr);
typedef ElementGroup<PlainShader> triangle_group_type;
typedef ElementGroup<OutlineShader> line_group_type;
typedef ElementGroup triangle_group_type;
typedef ElementGroup line_group_type;
public:
FillBucket(const std::shared_ptr<FillVertexBuffer>& vertexBuffer,
const std::shared_ptr<TriangleElementsBuffer>& triangleElementsBuffer,
@@ -52,6 +53,7 @@ public:
void tessellate();
void drawElements(PlainShader& shader);
void drawElements(PatternShader& shader);
void drawVertices(OutlineShader& shader);
public:
@@ -69,7 +71,7 @@ private:
const uint32_t vertex_start;
const uint32_t triangle_elements_start;
const uint32_t line_elements_start;
VertexArrayObject<OutlineShader> array;
VertexArrayObject array;
std::vector<triangle_group_type> triangleGroups;
std::vector<line_group_type> lineGroups;

View File

@@ -19,8 +19,8 @@ struct Coordinate;
struct pbf;
class LineBucket : public Bucket {
typedef ElementGroup<LineShader> triangle_group_type;
typedef ElementGroup<LinejoinShader> point_group_type;
typedef ElementGroup triangle_group_type;
typedef ElementGroup point_group_type;
public:
LineBucket(const std::shared_ptr<LineVertexBuffer>& vertexBuffer,
const std::shared_ptr<TriangleElementsBuffer>& triangleElementsBuffer,

View File

@@ -77,8 +77,8 @@ private:
4096, 4096
};
VertexArrayObject<PlainShader> coveringPlainArray;
VertexArrayObject<PatternShader> coveringPatternArray;
VertexArrayObject coveringPlainArray;
VertexArrayObject coveringPatternArray;
// Set up the tile boundary lines we're using to draw the tile outlines.
VertexBuffer tileBorderBuffer = {
@@ -89,7 +89,7 @@ private:
0, 0
};
VertexArrayObject<PlainShader> tileBorderArray;
VertexArrayObject tileBorderArray;
// Set up the matte buffer we're using to draw the filling background.
VertexBuffer matteBuffer = {
@@ -104,7 +104,7 @@ private:
16384, 16384
};
VertexArrayObject<PlainShader> matteArray;
VertexArrayObject matteArray;
};
}

View File

@@ -272,6 +272,17 @@ void FillBucket::drawElements(PlainShader& shader) {
}
}
void FillBucket::drawElements(PatternShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer->itemSize);
for (triangle_group_type& group : triangleGroups) {
group.array.bind(shader, *vertexBuffer, *triangleElementsBuffer, vertex_index);
glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index);
vertex_index += group.vertex_length * vertexBuffer->itemSize;
elements_index += group.elements_length * triangleElementsBuffer->itemSize;
}
}
void FillBucket::drawVertices(OutlineShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
char *elements_index = BUFFER_OFFSET(line_elements_start * lineElementsBuffer->itemSize);

View File

@@ -213,7 +213,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP);
}
if (false && properties.image.size() && *style.sprite) {
if (properties.image.size() && *style.sprite) {
// Draw texture fill
ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
@@ -242,16 +242,15 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
patternShader->setMix(mix);
style.sprite->bind(true);
// Draw a rectangle that covers the entire viewport.
coveringPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
// Draw the actual triangles into the color & stencil buffer.
bucket.drawElements(*patternShader);
} else {
// Draw filling rectangle.
useProgram(plainShader->program);
plainShader->setMatrix(matrix);
plainShader->setColor(fill_color);
// Draw the actual triangle fan into the stencil buffer.
// Draw the actual triangles into the color & stencil buffer.
bucket.drawElements(*plainShader);
}