From f4996046a2436886a5f1fc17a72a8cec21ad423d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 10 Feb 2014 15:14:52 +0100 Subject: [PATCH 1/3] common buffer implementation --- include/llmr/geometry/debug_font_buffer.hpp | 19 ++---- include/llmr/geometry/fill_buffer.hpp | 33 +++++----- include/llmr/geometry/line_buffer.hpp | 27 ++------ include/llmr/geometry/vertex_buffer.hpp | 2 +- include/llmr/map/tile.hpp | 6 +- include/llmr/renderer/fill_bucket.hpp | 10 ++- src/geometry/debug_font_buffer.cpp | 51 +++------------ src/geometry/fill_buffer.cpp | 70 ++++----------------- src/geometry/line_buffer.cpp | 43 +++---------- src/geometry/vertex_buffer.cpp | 2 +- src/map/tile.cpp | 5 +- src/renderer/fill_bucket.cpp | 30 +++++---- src/renderer/line_bucket.cpp | 4 +- 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 28a50d372..15f6daf07 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 -#include +#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 array; - uint32_t buffer; - bool dirty; }; } diff --git a/include/llmr/geometry/fill_buffer.hpp b/include/llmr/geometry/fill_buffer.hpp index b141825fc..f41371504 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 #include 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(); -private: - std::vector vertices; - std::vector elements; - uint32_t vertex_buffer; - uint32_t element_buffer; - bool dirty; +class FillElementsBuffer : public Buffer< + 6, // bytes per triangle (3 * unsigned short == 6 bytes) + GL_ELEMENT_ARRAY_BUFFER +> { +public: + typedef uint16_t element_type; + + 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 412ba860c..ccbdce119 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 -#include -#include +#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 array; - uint32_t buffer = 0; }; } diff --git a/include/llmr/geometry/vertex_buffer.hpp b/include/llmr/geometry/vertex_buffer.hpp index 5dd5ec719..9d053693c 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 7896d91eb..d0d660a4e 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 debugFontArray; - std::shared_ptr fillBuffer; + std::shared_ptr fillVertexBuffer; + std::shared_ptr fillElementsBuffer; std::shared_ptr lineBuffer; // Holds the buckets of this tile. diff --git a/include/llmr/renderer/fill_bucket.hpp b/include/llmr/renderer/fill_bucket.hpp index 209e164e8..2992d7710 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& buffer, const BucketDescription& bucket_desc); + FillBucket(const std::shared_ptr& vertexBuffer, + const std::shared_ptr& 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 buffer; + std::shared_ptr vertexBuffer; + std::shared_ptr elementsBuffer; struct group { VertexArrayObject array; diff --git a/src/geometry/debug_font_buffer.cpp b/src/geometry/debug_font_buffer.cpp index 7316ca21c..4db1aa285 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(addElement()); + coords[0] = prev_x; + coords[1] = prev_y; + + coords = static_cast(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 a90664238..3de008a7a 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) { - +void FillVertexBuffer::addDegenerate() { + vertex_type *vertices = static_cast(addElement()); + vertices[0] = 32767; + vertices[1] = 0; } -FillBuffer::~FillBuffer() { - if (vertex_buffer != 0) { - glDeleteBuffers(1, &vertex_buffer); - vertex_buffer = 0; - } - if (element_buffer != 0) { - glDeleteBuffers(1, &element_buffer); - element_buffer = 0; - } +void FillVertexBuffer::add(vertex_type x, vertex_type y) { + vertex_type *vertices = static_cast(addElement()); + vertices[0] = x; + vertices[1] = y; } -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 FillBuffer::addDegenerate() { - vertices.push_back(32767); - vertices.push_back(0); -} - -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(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 4e1200d2f..b9c770c04 100644 --- a/src/geometry/line_buffer.cpp +++ b/src/geometry/line_buffer.cpp @@ -1,46 +1,23 @@ #include #include +#include + using namespace llmr; -LineBuffer::~LineBuffer() { - if (buffer != 0) { - glDeleteBuffers(1, &buffer); - buffer = 0; - } -} - -uint32_t LineBuffer::length() const { - // We store 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes) - return array.size() / 4; -} - 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(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(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 2d209f6be..47fe73a2a 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 da0ad0006..016811af0 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -42,7 +42,8 @@ std::forward_list Tile::children(const ID& id, int32_t z) { Tile::Tile(ID id, const Style& style) : id(id), state(initial), - fillBuffer(std::make_shared()), + fillVertexBuffer(std::make_shared()), + fillElementsBuffer(std::make_shared()), lineBuffer(std::make_shared()), style(style) { @@ -166,7 +167,7 @@ std::shared_ptr Tile::createBucket(const VectorTile& tile, const BucketD } std::shared_ptr Tile::createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) { - std::shared_ptr bucket = std::make_shared(fillBuffer, bucket_desc); + std::shared_ptr bucket = std::make_shared(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 bfa50b007..8446c04f2 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& buffer, const BucketDescription& bucket_desc) +FillBucket::FillBucket(const std::shared_ptr& vertexBuffer, + const std::shared_ptr& 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& 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& 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 5cad0ddd4..213d8a285 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& 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& 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 31f8a8333..a00ead94f 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()); } From 4c6dc54352db2c5ef616eb88984845bb11ee2dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 10 Feb 2014 15:18:24 +0100 Subject: [PATCH 2/3] add missing buffer.hpp --- include/llmr/geometry/buffer.hpp | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 include/llmr/geometry/buffer.hpp diff --git a/include/llmr/geometry/buffer.hpp b/include/llmr/geometry/buffer.hpp new file mode 100644 index 000000000..02f03d010 --- /dev/null +++ b/include/llmr/geometry/buffer.hpp @@ -0,0 +1,73 @@ +#ifndef LLMR_GEOMETRY_BUFFER +#define LLMR_GEOMETRY_BUFFER + +#include +#include +#include + +namespace llmr { + +template < + size_t itemSize, + int bufferType = GL_ARRAY_BUFFER, + size_t defaultLength = 8192 +> +class Buffer { +public: + ~Buffer() { + if (array) { + free(array); + array = nullptr; + } + if (buffer != 0) { + glDeleteBuffers(1, &buffer); + buffer = 0; + } + } + + inline size_t index() const { + return pos / itemSize; + } + + void bind() { + if (buffer == 0) { + glGenBuffers(1, &buffer); + glBindBuffer(bufferType, buffer); + glBufferData(bufferType, pos, array, GL_STATIC_DRAW); + free(array); + array = nullptr; + } else { + glBindBuffer(bufferType, buffer); + } + } + +protected: + // increase the buffer size by at least /required/ bytes. + void *addElement() { + assert("Buffer is already bound to GPU" && buffer == 0); + if (length < pos + itemSize) { + while (length < pos + itemSize) length += defaultLength; + array = realloc(array, length); + assert("Buffer reallocation failed" && array != nullptr); + } + pos += itemSize; + return static_cast(array) + (pos - itemSize); + } + +private: + // CPU buffer + void *array = nullptr; + + // Byte position where we are writing. + size_t pos = 0; + + // Number of bytes that are valid in this buffer. + size_t length = 0; + + // GL buffer ID + uint32_t buffer = 0; +}; + +} + +#endif From eb9a6b7068b9910301bfc7a3b83e114c7545c893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Mon, 10 Feb 2014 15:20:46 +0100 Subject: [PATCH 3/3] add more docs --- include/llmr/geometry/buffer.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/llmr/geometry/buffer.hpp b/include/llmr/geometry/buffer.hpp index 02f03d010..1177bb196 100644 --- a/include/llmr/geometry/buffer.hpp +++ b/include/llmr/geometry/buffer.hpp @@ -25,10 +25,13 @@ 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. inline size_t index() const { return pos / itemSize; } + // Transfers this buffer to the GPU and binds the buffer to the GL context. void bind() { if (buffer == 0) { glGenBuffers(1, &buffer);