allow switching the vao if we switch the style from plain color to pattern fill
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user