diff options
-rw-r--r-- | include/llmr/geometry/debug_font_buffer.hpp | 19 | ||||
-rw-r--r-- | include/llmr/geometry/fill_buffer.hpp | 33 | ||||
-rw-r--r-- | include/llmr/geometry/line_buffer.hpp | 27 | ||||
-rw-r--r-- | include/llmr/geometry/vertex_buffer.hpp | 2 | ||||
-rw-r--r-- | include/llmr/map/tile.hpp | 6 | ||||
-rw-r--r-- | include/llmr/renderer/fill_bucket.hpp | 10 | ||||
-rw-r--r-- | src/geometry/debug_font_buffer.cpp | 51 | ||||
-rw-r--r-- | src/geometry/fill_buffer.cpp | 70 | ||||
-rw-r--r-- | src/geometry/line_buffer.cpp | 43 | ||||
-rw-r--r-- | src/geometry/vertex_buffer.cpp | 2 | ||||
-rw-r--r-- | src/map/tile.cpp | 5 | ||||
-rw-r--r-- | src/renderer/fill_bucket.cpp | 30 | ||||
-rw-r--r-- | src/renderer/line_bucket.cpp | 4 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 16 |
14 files changed, 99 insertions, 219 deletions
diff --git a/include/llmr/geometry/debug_font_buffer.hpp b/include/llmr/geometry/debug_font_buffer.hpp index 28a50d372e..15f6daf07f 100644 --- a/include/llmr/geometry/debug_font_buffer.hpp +++ b/include/llmr/geometry/debug_font_buffer.hpp @@ -1,26 +1,15 @@ #ifndef LLMR_GEOMETRY_DEBUG_FONT_BUFFER #define LLMR_GEOMETRY_DEBUG_FONT_BUFFER -#include <vector> -#include <cstdint> +#include "buffer.hpp" namespace llmr { -class DebugFontBuffer { +class DebugFontBuffer : public Buffer< + 4 // 2 bytes per coordinate, 2 coordinates +> { public: - DebugFontBuffer(); - ~DebugFontBuffer(); - void addText(const char *text, double left, double baseline, double scale = 1); - void clear(); - - uint32_t length(); - void bind(); - -private: - std::vector<uint16_t> array; - uint32_t buffer; - bool dirty; }; } diff --git a/include/llmr/geometry/fill_buffer.hpp b/include/llmr/geometry/fill_buffer.hpp index b141825fcb..f413715042 100644 --- a/include/llmr/geometry/fill_buffer.hpp +++ b/include/llmr/geometry/fill_buffer.hpp @@ -1,35 +1,32 @@ #ifndef LLMR_GEOMETRY_FILL_BUFFER #define LLMR_GEOMETRY_FILL_BUFFER +#include "buffer.hpp" #include <vector> #include <cstdint> namespace llmr { -class FillBuffer { + +class FillVertexBuffer : public Buffer< + 4 // bytes per coordinates (2 * unsigned short == 4 bytes) +> { public: typedef int16_t vertex_type; - typedef uint16_t element_type; - const uint8_t components = 2; - - FillBuffer(); - ~FillBuffer(); - - uint32_t vertex_length() const; - uint32_t elements_length() const; void addDegenerate(); - void addCoordinate(vertex_type x, vertex_type y); - void addElements(element_type a, element_type b, element_type c); + void add(vertex_type x, vertex_type y); +}; + - void bind(); +class FillElementsBuffer : public Buffer< + 6, // bytes per triangle (3 * unsigned short == 6 bytes) + GL_ELEMENT_ARRAY_BUFFER +> { +public: + typedef uint16_t element_type; -private: - std::vector<vertex_type> vertices; - std::vector<element_type> elements; - uint32_t vertex_buffer; - uint32_t element_buffer; - bool dirty; + void add(element_type a, element_type b, element_type c); }; } diff --git a/include/llmr/geometry/line_buffer.hpp b/include/llmr/geometry/line_buffer.hpp index 412ba860c8..ccbdce1191 100644 --- a/include/llmr/geometry/line_buffer.hpp +++ b/include/llmr/geometry/line_buffer.hpp @@ -1,17 +1,16 @@ #ifndef LLMR_GEOMETRY_LINE_BUFFER #define LLMR_GEOMETRY_LINE_BUFFER -#include <vector> -#include <cstdint> -#include <cmath> +#include "buffer.hpp" namespace llmr { -class LineBuffer { + +class LineBuffer : public Buffer< + 8 // 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes) +> { public: typedef int16_t vertex_type; - - ~LineBuffer(); /* * Scale the extrusion vector so that the normal length is this value. @@ -44,22 +43,6 @@ public: * coordinate of the next triangle strip. */ void addDegenerate(); - - /* - * 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: - bool dirty = true; - std::vector<vertex_type> array; - uint32_t buffer = 0; }; } diff --git a/include/llmr/geometry/vertex_buffer.hpp b/include/llmr/geometry/vertex_buffer.hpp index 5dd5ec7195..9d053693c9 100644 --- a/include/llmr/geometry/vertex_buffer.hpp +++ b/include/llmr/geometry/vertex_buffer.hpp @@ -17,7 +17,7 @@ public: * 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; + uint32_t index() const; /* * Transfers this buffer to the GPU and binds the buffer to the GL context. diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp index 7896d91ebd..d0d660a4e6 100644 --- a/include/llmr/map/tile.hpp +++ b/include/llmr/map/tile.hpp @@ -21,7 +21,8 @@ class LayerDescription; class BucketDescription; class VectorTile; class VectorTileLayer; -class FillBuffer; +class FillVertexBuffer; +class FillElementsBuffer; class LineBuffer; class PlainShader; @@ -72,7 +73,8 @@ public: DebugFontBuffer debugFontBuffer; VertexArrayObject<PlainShader> debugFontArray; - std::shared_ptr<FillBuffer> fillBuffer; + std::shared_ptr<FillVertexBuffer> fillVertexBuffer; + std::shared_ptr<FillElementsBuffer> fillElementsBuffer; std::shared_ptr<LineBuffer> lineBuffer; // Holds the buckets of this tile. diff --git a/include/llmr/renderer/fill_bucket.hpp b/include/llmr/renderer/fill_bucket.hpp index 209e164e8b..2992d77109 100644 --- a/include/llmr/renderer/fill_bucket.hpp +++ b/include/llmr/renderer/fill_bucket.hpp @@ -16,7 +16,8 @@ namespace llmr { class Style; -class FillBuffer; +class FillVertexBuffer; +class FillElementsBuffer; class BucketDescription; class OutlineShader; class PlainShader; @@ -25,7 +26,9 @@ struct pbf; class FillBucket : public Bucket { public: - FillBucket(const std::shared_ptr<FillBuffer>& buffer, const BucketDescription& bucket_desc); + FillBucket(const std::shared_ptr<FillVertexBuffer>& vertexBuffer, + const std::shared_ptr<FillElementsBuffer>& elementsBuffer, + const BucketDescription& bucket_desc); virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id); @@ -40,7 +43,8 @@ public: const BucketGeometryDescription geom_desc; private: - std::shared_ptr<FillBuffer> buffer; + std::shared_ptr<FillVertexBuffer> vertexBuffer; + std::shared_ptr<FillElementsBuffer> elementsBuffer; struct group { VertexArrayObject<PlainShader> array; diff --git a/src/geometry/debug_font_buffer.cpp b/src/geometry/debug_font_buffer.cpp index 7316ca21cd..4db1aa285a 100644 --- a/src/geometry/debug_font_buffer.cpp +++ b/src/geometry/debug_font_buffer.cpp @@ -7,20 +7,9 @@ using namespace llmr; -DebugFontBuffer::DebugFontBuffer() - : buffer(0), - dirty(true) { - -} - -DebugFontBuffer::~DebugFontBuffer() { - if (buffer != 0) { - glDeleteBuffers(1, &buffer); - buffer = 0; - } -} - void DebugFontBuffer::addText(const char *text, double left, double baseline, double scale) { + uint16_t *coords = nullptr; + int32_t length = strlen(text); for (int32_t i = 0; i < length; ++i) { if (text[i] < 32 || text[i] > 127) { @@ -45,39 +34,17 @@ void DebugFontBuffer::addText(const char *text, double left, double baseline, do int16_t x = round(left + glyph.data[j] * scale); int16_t y = round(baseline - glyph.data[j + 1] * scale); if (prev) { - array.push_back(prev_x); - array.push_back(prev_y); - array.push_back(x); - array.push_back(y); + coords = static_cast<uint16_t *>(addElement()); + coords[0] = prev_x; + coords[1] = prev_y; + + coords = static_cast<uint16_t *>(addElement()); + coords[0] = x; + coords[1] = y; } prev_x = x; prev_y = y; prev = true; } } left += glyph.width * scale; } - - dirty = true; -} - -void DebugFontBuffer::clear() { - array.clear(); - dirty = true; -} - -uint32_t DebugFontBuffer::length() { - // We store 2 coordinates per vertex - return array.size() / 2; -} - -void DebugFontBuffer::bind() { - if (buffer == 0) { - glGenBuffers(1, &buffer); - } - - glBindBuffer(GL_ARRAY_BUFFER, buffer); - - if (dirty) { - glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(uint16_t), array.data(), GL_STATIC_DRAW); - dirty = false; - } } diff --git a/src/geometry/fill_buffer.cpp b/src/geometry/fill_buffer.cpp index a90664238d..3de008a7a7 100644 --- a/src/geometry/fill_buffer.cpp +++ b/src/geometry/fill_buffer.cpp @@ -5,65 +5,21 @@ using namespace llmr; -FillBuffer::FillBuffer() - : vertex_buffer(0), - element_buffer(0), - dirty(true) { - -} - -FillBuffer::~FillBuffer() { - if (vertex_buffer != 0) { - glDeleteBuffers(1, &vertex_buffer); - vertex_buffer = 0; - } - if (element_buffer != 0) { - glDeleteBuffers(1, &element_buffer); - element_buffer = 0; - } -} - -uint32_t FillBuffer::vertex_length() const { - // We store 2 coordinates per vertex - return vertices.size() / 2; -} - -uint32_t FillBuffer::elements_length() const { - // A triangle has 3 indices - return elements.size() / 3; +void FillVertexBuffer::addDegenerate() { + vertex_type *vertices = static_cast<vertex_type *>(addElement()); + vertices[0] = 32767; + vertices[1] = 0; } -void FillBuffer::addDegenerate() { - vertices.push_back(32767); - vertices.push_back(0); +void FillVertexBuffer::add(vertex_type x, vertex_type y) { + vertex_type *vertices = static_cast<vertex_type *>(addElement()); + vertices[0] = x; + vertices[1] = y; } -void FillBuffer::addCoordinate(vertex_type x, vertex_type y) { - vertices.push_back(x); - vertices.push_back(y); -} - -void FillBuffer::addElements(element_type a, element_type b, element_type c) { - elements.push_back(a); - elements.push_back(b); - elements.push_back(c); -} - -void FillBuffer::bind() { - if (vertex_buffer == 0) { - glGenBuffers(1, &vertex_buffer); - } - - if (element_buffer == 0) { - glGenBuffers(1, &element_buffer); - } - - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer); - - if (dirty) { - glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertex_type), vertices.data(), GL_STATIC_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(element_type), elements.data(), GL_STATIC_DRAW); - dirty = false; - } +void FillElementsBuffer::add(element_type a, element_type b, element_type c) { + element_type *elements = static_cast<element_type *>(addElement()); + elements[0] = a; + elements[1] = b; + elements[2] = c; } diff --git a/src/geometry/line_buffer.cpp b/src/geometry/line_buffer.cpp index 4e1200d2f6..b9c770c04a 100644 --- a/src/geometry/line_buffer.cpp +++ b/src/geometry/line_buffer.cpp @@ -1,46 +1,23 @@ #include <llmr/geometry/line_buffer.hpp> #include <llmr/platform/gl.hpp> -using namespace llmr; - -LineBuffer::~LineBuffer() { - if (buffer != 0) { - glDeleteBuffers(1, &buffer); - buffer = 0; - } -} +#include <cmath> -uint32_t LineBuffer::length() const { - // We store 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes) - return array.size() / 4; -} +using namespace llmr; void LineBuffer::add(vertex_type x, vertex_type y, float ex, float ey, int8_t tx, int8_t ty, int32_t linesofar) { - array.push_back((x * 2) | tx); - array.push_back((y * 2) | ty); - array.push_back(linesofar); + void *data = addElement(); - int16_t extrude = 0; - *(((int8_t *)&extrude) + 0) = round(extrudeScale * ex); - *(((int8_t *)&extrude) + 1) = round(extrudeScale * ey); + int16_t *coords = static_cast<int16_t *>(data); + coords[0] = (x * 2) | tx; + coords[1] = (y * 2) | ty; + coords[2] = linesofar; - array.push_back(extrude); - if (!dirty) dirty = true; + int8_t *extrude = static_cast<int8_t *>(data); + extrude[6] = round(extrudeScale * ex); + extrude[7] = round(extrudeScale * ey); }; void LineBuffer::addDegenerate() { add(16383, 16383, 0, 0, 1, 1, 0); } - -void LineBuffer::bind() { - if (buffer == 0) { - glGenBuffers(1, &buffer); - } - - glBindBuffer(GL_ARRAY_BUFFER, buffer); - - if (dirty) { - glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(vertex_type), array.data(), GL_STATIC_DRAW); - dirty = false; - } -} diff --git a/src/geometry/vertex_buffer.cpp b/src/geometry/vertex_buffer.cpp index 2d209f6be1..47fe73a2aa 100644 --- a/src/geometry/vertex_buffer.cpp +++ b/src/geometry/vertex_buffer.cpp @@ -12,7 +12,7 @@ VertexBuffer::~VertexBuffer() { } } -uint32_t VertexBuffer::length() const { +uint32_t VertexBuffer::index() const { // We store 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes) return array.size() / 2; } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index da0ad00066..016811af00 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -42,7 +42,8 @@ std::forward_list<Tile::ID> Tile::children(const ID& id, int32_t z) { Tile::Tile(ID id, const Style& style) : id(id), state(initial), - fillBuffer(std::make_shared<FillBuffer>()), + fillVertexBuffer(std::make_shared<FillVertexBuffer>()), + fillElementsBuffer(std::make_shared<FillElementsBuffer>()), lineBuffer(std::make_shared<LineBuffer>()), style(style) { @@ -166,7 +167,7 @@ std::shared_ptr<Bucket> Tile::createBucket(const VectorTile& tile, const BucketD } std::shared_ptr<Bucket> Tile::createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { - std::shared_ptr<FillBucket> bucket = std::make_shared<FillBucket>(fillBuffer, bucket_desc); + std::shared_ptr<FillBucket> bucket = std::make_shared<FillBucket>(fillVertexBuffer, fillElementsBuffer, bucket_desc); FilteredVectorTileLayer filtered_layer(layer, bucket_desc); for (pbf feature : filtered_layer) { diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index bfa50b0079..8446c04f2b 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -14,11 +14,14 @@ struct geometry_too_long_exception : std::exception {}; using namespace llmr; -FillBucket::FillBucket(const std::shared_ptr<FillBuffer>& buffer, const BucketDescription& bucket_desc) +FillBucket::FillBucket(const std::shared_ptr<FillVertexBuffer>& vertexBuffer, + const std::shared_ptr<FillElementsBuffer>& elementsBuffer, + const BucketDescription& bucket_desc) : geom_desc(bucket_desc.geometry), - buffer(buffer), - vertex_start(buffer->vertex_length()), - elements_start(buffer->elements_length()), + vertexBuffer(vertexBuffer), + elementsBuffer(elementsBuffer), + vertex_start(vertexBuffer->index()), + elements_start(elementsBuffer->index()), length(0) { } @@ -44,13 +47,13 @@ void FillBucket::addGeometry(pbf& geom) { } void FillBucket::addGeometry(const std::vector<Coordinate>& line) { - uint32_t vertex_start = buffer->vertex_length(); - buffer->addDegenerate(); + uint32_t vertex_start = vertexBuffer->index(); + vertexBuffer->addDegenerate(); for (const Coordinate& coord : line) { - buffer->addCoordinate(coord.x, coord.y); + vertexBuffer->add(coord.x, coord.y); } - uint32_t vertex_end = buffer->vertex_length(); + uint32_t vertex_end = vertexBuffer->index(); if (vertex_end - vertex_start > 65535) { throw geometry_too_long_exception(); @@ -78,13 +81,13 @@ void FillBucket::addGeometry(const std::vector<Coordinate>& line) { assert(firstIndex + vertex_count - 1 < 65536); - uint32_t elements_start = buffer->elements_length(); + uint32_t elements_start = elementsBuffer->index(); for (uint32_t i = 2; i < vertex_count; ++i) { - buffer->addElements(firstIndex, firstIndex + i - 1, firstIndex + i); + elementsBuffer->add(firstIndex, firstIndex + i - 1, firstIndex + i); } - uint32_t elements_end = buffer->elements_length(); + uint32_t elements_end = elementsBuffer->index(); uint32_t elements_count = elements_end - elements_start; group.vertex_length += vertex_count; group.elements_length += elements_count; @@ -105,7 +108,8 @@ void FillBucket::drawElements(PlainShader& 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) { - group.array.bind(shader, *buffer, vertex_index); + group.array.bind(shader, *vertexBuffer, vertex_index); + elementsBuffer->bind(); 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); @@ -115,6 +119,6 @@ void FillBucket::drawElements(PlainShader& shader) { void FillBucket::drawVertices(OutlineShader& shader) { // Draw the entire line char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t)); - array.bind(shader, *buffer, vertex_index); + array.bind(shader, *vertexBuffer, vertex_index); glDrawArrays(GL_LINE_STRIP, 0, length); } diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index 5cad0ddd4e..213d8a2856 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -21,7 +21,7 @@ using namespace llmr; LineBucket::LineBucket(const std::shared_ptr<LineBuffer>& buffer, const BucketDescription& bucket_desc) : geometry(bucket_desc.geometry), buffer(buffer), - start(buffer->length()), + start(buffer->index()), length(0) { } @@ -258,7 +258,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) { } // Update the length. - length = buffer->length() - start; + length = buffer->index() - start; } void LineBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 31f8a83331..a00ead94fd 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -96,7 +96,7 @@ void Painter::drawClippingMask() { // Draw the clipping mask glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); // glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 0x80, 0x80); @@ -265,7 +265,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Draw a rectangle that covers the entire viewport. coveringPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); } else { // Draw filling rectangle. @@ -275,7 +275,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Draw a rectangle that covers the entire viewport. coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); } glStencilMask(0x00); @@ -365,16 +365,16 @@ void Painter::renderDebug(const Tile::Ptr& tile) { 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()); + glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.index()); // draw debug info 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()); + glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index()); glUniform4f(plainShader->u_color, 0.0f, 0.0f, 0.0f, 1.0f); glLineWidth(2.0f); - glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.length()); + glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index()); // Revert blending mode to blend to the back. glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); @@ -391,7 +391,7 @@ void Painter::renderMatte() { // Draw the clipping mask matteArray.bind(*plainShader, matteBuffer, BUFFER_OFFSET(0)); glUniform4fv(plainShader->u_color, 1, white.data()); - glDrawArrays(GL_TRIANGLES, 0, matteBuffer.length()); + glDrawArrays(GL_TRIANGLES, 0, matteBuffer.index()); glEnable(GL_STENCIL_TEST); } @@ -405,5 +405,5 @@ void Painter::renderBackground() { // Draw the clipping mask coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); glUniform4fv(plainShader->u_color, 1, white.data()); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index()); } |