diff --git a/bin/style.js b/bin/style.js index 4099b420d..ae2c353d2 100644 --- a/bin/style.js +++ b/bin/style.js @@ -83,7 +83,7 @@ module.exports = { "type": "fill", "color": "#c8df9f", "antialias": true, - "image": "park" + // "image": "park" }, "wood": { "type": "fill", @@ -96,7 +96,7 @@ module.exports = { "color": "#bae0e9", "stroke": "#73b6e6", "antialias": true, - "image": "water_etsy" + // "image": "water_etsy" }, "building": { "type": "fill", diff --git a/include/llmr/geometry/vao.hpp b/include/llmr/geometry/vao.hpp new file mode 100644 index 000000000..5e0b54ba6 --- /dev/null +++ b/include/llmr/geometry/vao.hpp @@ -0,0 +1,42 @@ +#ifndef LLMR_GEOMETRY_VAO +#define LLMR_GEOMETRY_VAO + +#include + +#include + +namespace llmr { + +class VertexArrayObject { +public: + template + inline void setup(Shader& shader, VertexBuffer& vertex_buffer, char *vertex_offset) { + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + vertex_buffer.bind(); + shader.bind_vertex(vertex_offset); + } + + inline ~VertexArrayObject() { + if (vao) { + glDeleteVertexArrays(1, &vao); + } + } + + inline operator bool() const { + return vao != 0; + } + + inline void bind() { + assert(vao); + glBindVertexArray(vao); + } + +private: + GLuint vao = 0; +}; + +} + +#endif diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp index 2184af9bd..a6457a58a 100644 --- a/include/llmr/map/tile.hpp +++ b/include/llmr/map/tile.hpp @@ -2,6 +2,8 @@ #define LLMR_MAP_TILE #include +#include +#include #include #include @@ -18,7 +20,6 @@ class LayerDescription; class BucketDescription; class VectorTile; class VectorTileLayer; -class DebugFontBuffer; class FillBuffer; class LineBuffer; @@ -71,7 +72,9 @@ public: state state; // Holds the actual geometries in this tile. - std::shared_ptr debugFontBuffer; + DebugFontBuffer debugFontBuffer; + VertexArrayObject debugFontArray; + std::shared_ptr fillBuffer; std::shared_ptr lineBuffer; diff --git a/include/llmr/platform/gl.hpp b/include/llmr/platform/gl.hpp index 529a6d307..4074fa081 100644 --- a/include/llmr/platform/gl.hpp +++ b/include/llmr/platform/gl.hpp @@ -8,6 +8,9 @@ #if TARGET_OS_IPHONE #include #include + #define glGenVertexArrays glGenVertexArraysOES + #define glBindVertexArray glBindVertexArrayOES + #define glDeleteVertexArrays glDeleteVertexArraysOES #elif TARGET_IPHONE_SIMULATOR #include #include diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index b31a112b8..4957f7042 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -5,8 +5,8 @@ #include #include -#define kTileURL "http://mapbox:magic@kkaefer.net/gl/tiles/plain/%d-%d-%d.vector.pbf" -#define kSpriteURL "http://mapbox:magic@kkaefer.net/gl/debug/img/sprite" +#define kTileURL "http://pepper.local:3333/gl/tiles/plain/%d-%d-%d.vector.pbf" +#define kSpriteURL "http://pepper.local:3333/gl/debug/img/sprite" namespace llmr { diff --git a/include/llmr/renderer/fill_bucket.hpp b/include/llmr/renderer/fill_bucket.hpp index 4ab950731..774b00811 100644 --- a/include/llmr/renderer/fill_bucket.hpp +++ b/include/llmr/renderer/fill_bucket.hpp @@ -3,10 +3,16 @@ #include "bucket.hpp" #include +#include +#include #include #include +#ifndef BUFFER_OFFSET +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) +#endif + namespace llmr { class Style; @@ -24,8 +30,9 @@ public: void addGeometry(pbf& data); void addGeometry(const std::vector& line); uint32_t size() const; - void drawElements(int32_t attrib); - void drawVertices(int32_t attrib); + + template void drawElements(Shader& shader); + template void drawVertices(Shader& shader); public: const BucketGeometryDescription geom_desc; @@ -34,6 +41,7 @@ private: std::shared_ptr buffer; struct group { + VertexArrayObject array; uint32_t vertex_length; uint32_t elements_length; @@ -48,9 +56,40 @@ private: uint32_t vertex_start; uint32_t elements_start; uint32_t length; + VertexArrayObject array; std::vector groups; }; + +template +void FillBucket::drawElements(Shader& 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) { + if (!group.array) { + group.array.setup(shader, *buffer, vertex_index); + } else { + group.array.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); + } +} + +template +void FillBucket::drawVertices(Shader& shader) { + // Draw the entire line + if (!array) { + char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t)); + array.setup(shader, *buffer, vertex_index); + } else { + array.bind(); + } + glDrawArrays(GL_LINE_STRIP, 0, length); +} + + } #endif diff --git a/include/llmr/renderer/line_bucket.hpp b/include/llmr/renderer/line_bucket.hpp index f6caededa..677adbdd4 100644 --- a/include/llmr/renderer/line_bucket.hpp +++ b/include/llmr/renderer/line_bucket.hpp @@ -3,6 +3,7 @@ #include "bucket.hpp" #include +#include #include #include @@ -10,6 +11,7 @@ namespace llmr { class Style; class LineBuffer; +class LineShader; struct Coordinate; struct pbf; @@ -21,10 +23,12 @@ public: void addGeometry(pbf& data); void addGeometry(const std::vector& line); - uint32_t size() const; - void bind(); - char *vertexOffset() const; + size_t size() const; + + void bind(LineShader& shader); + void drawLines(); + void drawPoints(); public: const BucketGeometryDescription geometry; @@ -33,6 +37,7 @@ private: std::shared_ptr buffer; uint32_t start; uint32_t length; + VertexArrayObject array; }; } diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 108eb2f38..7688763ac 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -2,6 +2,7 @@ #define LLMR_RENDERER_PAINTER #include +#include #include #include @@ -86,6 +87,8 @@ private: 4096, 4096 }; + VertexArrayObject tileStencilArray; + // Set up the tile boundary lines we're using to draw the tile outlines. VertexBuffer tileBorderBuffer = { 0, 0, @@ -95,6 +98,8 @@ private: 0, 0 }; + VertexArrayObject tileBorderArray; + // Set up the matte buffer we're using to draw the filling background. VertexBuffer matteBuffer = { // top left triangle @@ -108,6 +113,7 @@ private: 16384, 16384 }; + VertexArrayObject matteArray; }; } diff --git a/include/llmr/renderer/shader-fill.hpp b/include/llmr/renderer/shader-fill.hpp index 440f3011c..beff61592 100644 --- a/include/llmr/renderer/shader-fill.hpp +++ b/include/llmr/renderer/shader-fill.hpp @@ -9,6 +9,8 @@ class FillShader : public Shader { public: FillShader(); + void bind_vertex(char *offset); + int32_t a_pos; int32_t u_matrix; int32_t u_color; diff --git a/include/llmr/renderer/shader-line.hpp b/include/llmr/renderer/shader-line.hpp index 1045a97f3..f33e26e51 100644 --- a/include/llmr/renderer/shader-line.hpp +++ b/include/llmr/renderer/shader-line.hpp @@ -9,6 +9,8 @@ class LineShader : public Shader { public: LineShader(); + void bind_vertex(char *offset); + int32_t a_pos; int32_t a_extrude; int32_t a_linesofar; diff --git a/include/llmr/renderer/shader-outline.hpp b/include/llmr/renderer/shader-outline.hpp index f37c54d5b..eda1bb88b 100644 --- a/include/llmr/renderer/shader-outline.hpp +++ b/include/llmr/renderer/shader-outline.hpp @@ -9,6 +9,8 @@ class OutlineShader : public Shader { public: OutlineShader(); + void bind_vertex(char *offset); + int32_t a_pos; int32_t u_matrix; int32_t u_color; diff --git a/include/llmr/renderer/shader-plain.hpp b/include/llmr/renderer/shader-plain.hpp index d1ccdeff0..dd3a57102 100644 --- a/include/llmr/renderer/shader-plain.hpp +++ b/include/llmr/renderer/shader-plain.hpp @@ -9,6 +9,8 @@ class PlainShader : public Shader { public: PlainShader(); + void bind_vertex(char *offset); + int32_t a_pos; int32_t u_matrix; int32_t u_color; diff --git a/include/llmr/util/std.hpp b/include/llmr/util/std.hpp new file mode 100644 index 000000000..4ef28d5f8 --- /dev/null +++ b/include/llmr/util/std.hpp @@ -0,0 +1,16 @@ +#ifndef LLMR_UTIL_STD +#define LLMR_UTIL_STD + +#include + +namespace std { + +// C++14 backfill from http://herbsutter.com/gotw/_102/ +template +::std::unique_ptr make_unique(Args&& ...args) { + return ::std::unique_ptr(new T(::std::forward(args)...)); +} + +} + +#endif diff --git a/resources/style.pbf b/resources/style.pbf index d87f896d1..69475487d 100644 Binary files a/resources/style.pbf and b/resources/style.pbf differ diff --git a/src/geometry/vertex_buffer.cpp b/src/geometry/vertex_buffer.cpp index b190e31d8..591b0c13d 100644 --- a/src/geometry/vertex_buffer.cpp +++ b/src/geometry/vertex_buffer.cpp @@ -9,7 +9,6 @@ VertexBuffer::VertexBuffer(std::initializer_list init) : array(init) {} VertexBuffer::~VertexBuffer() { if (buffer != 0) { glDeleteBuffers(1, &buffer); - buffer = 0; } } @@ -26,5 +25,4 @@ void VertexBuffer::bind() { } else { glBindBuffer(GL_ARRAY_BUFFER, buffer); } - } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index dccde9383..b7cf468d0 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -43,7 +42,6 @@ std::forward_list Tile::children(const ID& id, int32_t z) { Tile::Tile(ID id, const Style& style) : id(id), state(initial), - debugFontBuffer(std::make_shared()), fillBuffer(std::make_shared()), lineBuffer(std::make_shared()), style(style) { @@ -51,7 +49,7 @@ Tile::Tile(ID id, const Style& style) // Initialize tile debug coordinates char coord[32]; snprintf(coord, sizeof(coord), "%d/%d/%d", id.z, id.x, id.y); - debugFontBuffer->addText(coord, 50, 200, 5); + debugFontBuffer.addText(coord, 50, 200, 5); } Tile::~Tile() { diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index 69208ae20..f0226f134 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -8,8 +8,6 @@ #include -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - #include struct geometry_too_long_exception : std::exception {}; @@ -97,26 +95,6 @@ void FillBucket::addGeometry(const std::vector& line) { } -void FillBucket::drawElements(int32_t attrib) { - char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t)); - char *elements_index = BUFFER_OFFSET(elements_start * 3 * sizeof(int16_t)); - buffer->bind(); - for (const auto& group : groups) { - glVertexAttribPointer(attrib, 2, GL_SHORT, GL_FALSE, 0, vertex_index); - glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index); - vertex_index += group.vertex_length * 2 * sizeof(uint16_t); - elements_index += group.elements_length * 3 * sizeof(uint16_t); - } -} - -void FillBucket::drawVertices(int32_t attrib) { - // Draw the entire line - char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t)); - buffer->bind(); - glVertexAttribPointer(attrib, 2, GL_SHORT, GL_FALSE, 0, vertex_index); - glDrawArrays(GL_LINE_STRIP, 0, length); -} - void FillBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { painter.renderFill(*this, layer_name, id); } diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index 70f766d9d..5dc0710b8 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -264,14 +265,23 @@ void LineBucket::render(Painter& painter, const std::string& layer_name, const T painter.renderLine(*this, layer_name, id); } -uint32_t LineBucket::size() const { +size_t LineBucket::size() const { return length; } -void LineBucket::bind() { - buffer->bind(); +void LineBucket::bind(LineShader& shader) { + if (!array) { + char *vertex_index = BUFFER_OFFSET(start * 4 * sizeof(int16_t)); + array.setup(shader, *buffer, vertex_index); + } else { + array.bind(); + } } -char *LineBucket::vertexOffset() const { - return BUFFER_OFFSET(start * 4 * sizeof(int16_t)); +void LineBucket::drawLines() { + glDrawArrays(GL_TRIANGLE_STRIP, 0, length); +} + +void LineBucket::drawPoints() { + glDrawArrays(GL_POINTS, 0, length); } diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 3b5c83caf..3ef7fbe22 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -76,7 +77,7 @@ void Painter::changeMatrix(const Tile::ID& id) { } void Painter::drawClippingMask() { - switchShader(plainShader); + glUseProgram(plainShader->program); glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data()); glColorMask(false, false, false, false); @@ -96,9 +97,13 @@ void Painter::drawClippingMask() { glStencilMask(0xC0); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); + if (!tileStencilArray) { + tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); + } else { + tileStencilArray.bind(); + } + // Draw the clipping mask - 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, tileStencilBuffer.length()); @@ -197,11 +202,11 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glColorMask(false, false, false, false); // Draw the actual triangle fan into the stencil buffer. - switchShader(fillShader); + glUseProgram(fillShader->program); glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data()); // Draw all groups - bucket.drawElements(fillShader->a_pos); + bucket.drawElements(*fillShader); // Now that we have the stencil mask in the stencil buffer, we can start // writing to the color buffer. @@ -215,7 +220,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) if (properties.antialias) { - switchShader(outlineShader); + glUseProgram(outlineShader->program); glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix.data()); glLineWidth(2); @@ -238,49 +243,53 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Draw the entire line glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height); glLineWidth(2.0f); - bucket.drawVertices(outlineShader->a_pos); + bucket.drawVertices(*outlineShader); } // Only draw regions that we marked glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F); if (properties.image.size() && style.sprite) { - // Draw texture fill - ImagePosition imagePos = style.sprite->getPosition(properties.image, true); + // TODO: + // // Draw texture fill + // ImagePosition imagePos = style.sprite->getPosition(properties.image, true); - double factor = 8.0 / pow(2, transform.getIntegerZoom() - id.z); - double mix = fmod(transform.getZoom(), 1.0); - vec2 imageSize { imagePos.size.x * factor, imagePos.size.y * factor }; + // double factor = 8.0 / pow(2, transform.getIntegerZoom() - id.z); + // double mix = fmod(transform.getZoom(), 1.0); + // vec2 imageSize { imagePos.size.x * factor, imagePos.size.y * factor }; - vec2 offset { - fmod(id.x * 4096, imageSize.x), - fmod(id.y * 4096, imageSize.y) - }; + // vec2 offset { + // fmod(id.x * 4096, imageSize.x), + // fmod(id.y * 4096, imageSize.y) + // }; - switchShader(patternShader); - glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data()); - glUniform2f(patternShader->u_pattern_size, imageSize.x, imageSize.y); - glUniform2f(patternShader->u_offset, offset.x, offset.y); - glUniform2f(patternShader->u_pattern_tl, imagePos.tl.x, imagePos.tl.y); - glUniform2f(patternShader->u_pattern_br, imagePos.br.x, imagePos.br.y); - glUniform4fv(patternShader->u_color, 1, fill_color.data()); - glUniform1f(patternShader->u_mix, mix); - style.sprite->bind(true); + // switchShader(patternShader); + // glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data()); + // glUniform2f(patternShader->u_pattern_size, imageSize.x, imageSize.y); + // glUniform2f(patternShader->u_offset, offset.x, offset.y); + // glUniform2f(patternShader->u_pattern_tl, imagePos.tl.x, imagePos.tl.y); + // glUniform2f(patternShader->u_pattern_br, imagePos.br.x, imagePos.br.y); + // glUniform4fv(patternShader->u_color, 1, fill_color.data()); + // glUniform1f(patternShader->u_mix, mix); + // style.sprite->bind(true); - // Draw a rectangle that covers the entire viewport. - tileStencilBuffer.bind(); - glVertexAttribPointer(patternShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); + // // Draw a rectangle that covers the entire viewport. + // tileStencilBuffer.bind(); + // glVertexAttribPointer(patternShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); + // glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); } else { // Draw filling rectangle. - switchShader(fillShader); + glUseProgram(fillShader->program); glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data()); glUniform4fv(fillShader->u_color, 1, fill_color.data()); // Draw a rectangle that covers the entire viewport. - tileStencilBuffer.bind(); - glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); + if (!tileStencilArray) { + tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); + } else { + tileStencilArray.bind(); + } glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); } @@ -324,42 +333,37 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons // glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0); } else { - switchShader(lineShader); + glUseProgram(lineShader->program); glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix.data()); glUniformMatrix4fv(lineShader->u_exmatrix, 1, GL_FALSE, exMatrix.data()); // glUniform2fv(painter.lineShader.u_dasharray, properties.dasharray || [1, -1]); glUniform2f(lineShader->u_dasharray, 1, -1); - } - // TODO: Move this to transform? - const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8; + // TODO: Move this to transform? + const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8; - glUniform2f(lineShader->u_linewidth, outset, inset); - glUniform1f(lineShader->u_ratio, tilePixelRatio); - glUniform1f(lineShader->u_gamma, transform.pixelRatio); + glUniform2f(lineShader->u_linewidth, outset, inset); + glUniform1f(lineShader->u_ratio, tilePixelRatio); + glUniform1f(lineShader->u_gamma, transform.pixelRatio); - // const Color& color = properties.color; - // if (!params.antialiasing) { - // color[3] = Infinity; - // glUniform4fv(lineShader->u_color, color); - // } else { - glUniform4fv(lineShader->u_color, 1, color.data()); - // } + // const Color& color = properties.color; + // if (!params.antialiasing) { + // color[3] = Infinity; + // glUniform4fv(lineShader->u_color, color); + // } else { + glUniform4fv(lineShader->u_color, 1, color.data()); + // } - glUniform1f(lineShader->u_point, 0); + glUniform1f(lineShader->u_point, 0); + bucket.bind(*lineShader); + bucket.drawLines(); - bucket.bind(); - char *vertex_index = bucket.vertexOffset(); - glVertexAttribPointer(lineShader->a_pos, 2, GL_SHORT, false, 8, vertex_index); - glVertexAttribPointer(lineShader->a_extrude, 2, GL_BYTE, false, 8, vertex_index + 6); - glVertexAttribPointer(lineShader->a_linesofar, 1, GL_SHORT, false, 8, vertex_index + 4); - glDrawArrays(GL_TRIANGLE_STRIP, 0, bucket.size()); - - if (bucket.geometry.join == JoinType::Round) { - glUniform1f(lineShader->u_point, 1); - glDrawArrays(GL_POINTS, 0, bucket.size()); + if (bucket.geometry.join == JoinType::Round) { + glUniform1f(lineShader->u_point, 1); + bucket.drawPoints(); + } } // statistics @@ -369,27 +373,31 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons void Painter::renderDebug(const Tile::Ptr& tile) { // Blend to the front, not the back. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(plainShader->program); + glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data()); // draw tile outline - switchShader(plainShader); - glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data()); - 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); + if (!tileBorderArray) { + tileBorderArray.setup(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0)); + } else { + tileBorderArray.bind(); + } + glUniform4f(plainShader->u_color, 1.0f, 0.0f, 0.0f, 1.0f); glLineWidth(4.0f); glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.length()); // draw debug info - switchShader(plainShader); - glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data()); - tile->debugFontBuffer->bind(); - glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, BUFFER_OFFSET(0)); + if (!tile->debugFontArray) { + tile->debugFontArray.setup(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0)); + } else { + tile->debugFontArray.bind(); + } 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.length()); 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.length()); // Revert blending mode to blend to the back. glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); @@ -398,30 +406,37 @@ void Painter::renderDebug(const Tile::Ptr& tile) { void Painter::renderMatte() { glDisable(GL_STENCIL_TEST); - switchShader(fillShader); - glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, nativeMatrix.data()); + Color white = {{ 0.9, 0.9, 0.9, 1 }}; - Color white = {{ 1, 1, 1, 1 }}; + glUseProgram(plainShader->program); + glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, nativeMatrix.data()); + + if (!matteArray) { + matteArray.setup(*plainShader, matteBuffer, BUFFER_OFFSET(0)); + } else { + matteArray.bind(); + } // Draw the clipping mask - matteBuffer.bind(); - glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); - glUniform4fv(fillShader->u_color, 1, white.data()); + glUniform4fv(plainShader->u_color, 1, white.data()); glDrawArrays(GL_TRIANGLES, 0, matteBuffer.length()); glEnable(GL_STENCIL_TEST); } void Painter::renderBackground() { - switchShader(fillShader); - glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data()); - Color white = {{ 1, 1, 1, 1 }}; + glUseProgram(plainShader->program); + glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data()); + // Draw the clipping mask - tileStencilBuffer.bind(); - glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); - glUniform4fv(fillShader->u_color, 1, white.data()); + if (!tileStencilArray) { + tileStencilArray.setup(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); + } else { + tileStencilArray.bind(); + } + glUniform4fv(plainShader->u_color, 1, white.data()); glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length()); } @@ -431,6 +446,7 @@ void Painter::renderBackground() { * @return boolean whether the shader was actually switched */ bool Painter::switchShader(std::shared_ptr shader) { + assert(false); if (currentShader != shader) { glUseProgram(shader->program); diff --git a/src/renderer/shader-fill.cpp b/src/renderer/shader-fill.cpp index 623d06118..a5536bf83 100644 --- a/src/renderer/shader-fill.cpp +++ b/src/renderer/shader-fill.cpp @@ -20,3 +20,8 @@ FillShader::FillShader() u_matrix = glGetUniformLocation(program, "u_matrix"); u_color = glGetUniformLocation(program, "u_color"); } + +void FillShader::bind_vertex(char *offset) { + glEnableVertexAttribArray(a_pos); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); +} diff --git a/src/renderer/shader-line.cpp b/src/renderer/shader-line.cpp index ae73dbb4f..7a1c0b5a3 100644 --- a/src/renderer/shader-line.cpp +++ b/src/renderer/shader-line.cpp @@ -31,3 +31,14 @@ LineShader::LineShader() u_point = glGetUniformLocation(program, "u_point"); u_gamma = glGetUniformLocation(program, "u_gamma"); } + +void LineShader::bind_vertex(char *offset) { + glEnableVertexAttribArray(a_pos); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset); + + glEnableVertexAttribArray(a_extrude); + glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 6); + + glEnableVertexAttribArray(a_linesofar); + glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 4); +} \ No newline at end of file diff --git a/src/renderer/shader-outline.cpp b/src/renderer/shader-outline.cpp index ea27b2698..82f31e1dc 100644 --- a/src/renderer/shader-outline.cpp +++ b/src/renderer/shader-outline.cpp @@ -21,3 +21,8 @@ OutlineShader::OutlineShader() u_color = glGetUniformLocation(program, "u_color"); u_world = glGetUniformLocation(program, "u_world"); } + +void OutlineShader::bind_vertex(char *offset) { + glEnableVertexAttribArray(a_pos); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); +} diff --git a/src/renderer/shader-plain.cpp b/src/renderer/shader-plain.cpp index 8e767b6dc..42c5ea564 100644 --- a/src/renderer/shader-plain.cpp +++ b/src/renderer/shader-plain.cpp @@ -20,3 +20,8 @@ PlainShader::PlainShader() u_matrix = glGetUniformLocation(program, "u_matrix"); u_color = glGetUniformLocation(program, "u_color"); } + +void PlainShader::bind_vertex(char *offset) { + glEnableVertexAttribArray(a_pos); + glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); +} diff --git a/src/renderer/shader.cpp b/src/renderer/shader.cpp index f2326efd7..fd74281bf 100644 --- a/src/renderer/shader.cpp +++ b/src/renderer/shader.cpp @@ -107,7 +107,7 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) { #if defined(EMSCRIPTEN) || defined(GL_ES_VERSION_2_0) // Add WebGL GLSL / OpenGL ES precision premable - const GLchar *preamble = "precision mediump float;\n\n"; + const GLchar *preamble = "precision highp float;\n\n"; #else // Desktop GLSL const GLchar *preamble = "#version 120\n\n"; diff --git a/src/style/resources.cpp b/src/style/resources.cpp index def1933ff..9380bf025 100644 --- a/src/style/resources.cpp +++ b/src/style/resources.cpp @@ -47,28 +47,27 @@ const unsigned char resources::style[] = { 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 18, 24, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 18, 18, 10, 7, 97, 108, 99, 111, 104, - 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 220, 2, 10, 7, - 100, 101, 102, 97, 117, 108, 116, 18, 27, 10, 4, 112, 97, 114, 107, 34, - 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 159, 223, 200, 66, 4, - 112, 97, 114, 107, 18, 31, 10, 4, 119, 111, 111, 100, 34, 8, 8, 2, - 18, 4, 0, 0, 128, 63, 45, 255, 102, 170, 51, 58, 8, 8, 2, 18, - 4, 205, 204, 204, 61, 18, 39, 10, 5, 119, 97, 116, 101, 114, 34, 8, - 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 233, 224, 186, 53, 255, 230, - 182, 115, 66, 10, 119, 97, 116, 101, 114, 95, 101, 116, 115, 121, 18, 51, - 10, 8, 98, 117, 105, 108, 100, 105, 110, 103, 34, 8, 8, 2, 18, 4, - 0, 0, 128, 63, 45, 255, 0, 0, 0, 58, 24, 8, 4, 18, 20, 0, - 0, 80, 65, 0, 0, 0, 0, 205, 204, 204, 61, 0, 0, 0, 0, 205, - 204, 204, 61, 26, 41, 10, 12, 114, 111, 97, 100, 95, 108, 105, 109, 105, - 116, 101, 100, 29, 255, 187, 187, 187, 34, 20, 8, 3, 18, 16, 0, 0, - 0, 0, 0, 0, 128, 63, 0, 0, 240, 65, 0, 0, 128, 63, 26, 65, - 10, 12, 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 29, 255, - 153, 153, 153, 34, 44, 8, 3, 18, 40, 0, 0, 0, 0, 0, 0, 0, - 63, 0, 0, 80, 65, 0, 0, 0, 63, 0, 0, 128, 65, 0, 0, 0, - 64, 0, 0, 160, 65, 0, 0, 0, 66, 0, 0, 240, 65, 0, 0, 0, - 66, 26, 71, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 29, - 255, 102, 102, 102, 34, 52, 8, 3, 18, 48, 0, 0, 0, 0, 0, 0, - 0, 63, 0, 0, 48, 65, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, - 128, 63, 0, 0, 128, 65, 0, 0, 128, 64, 0, 0, 160, 65, 0, 0, - 128, 66, 0, 0, 240, 65, 0, 0, 128, 66 + 111, 108, 18, 7, 97, 108, 99, 111, 104, 111, 108, 26, 202, 2, 10, 7, + 100, 101, 102, 97, 117, 108, 116, 18, 21, 10, 4, 112, 97, 114, 107, 34, + 8, 8, 2, 18, 4, 0, 0, 128, 63, 45, 255, 159, 223, 200, 18, 31, + 10, 4, 119, 111, 111, 100, 34, 8, 8, 2, 18, 4, 0, 0, 128, 63, + 45, 255, 102, 170, 51, 58, 8, 8, 2, 18, 4, 205, 204, 204, 61, 18, + 27, 10, 5, 119, 97, 116, 101, 114, 34, 8, 8, 2, 18, 4, 0, 0, + 128, 63, 45, 255, 233, 224, 186, 53, 255, 230, 182, 115, 18, 51, 10, 8, + 98, 117, 105, 108, 100, 105, 110, 103, 34, 8, 8, 2, 18, 4, 0, 0, + 128, 63, 45, 255, 0, 0, 0, 58, 24, 8, 4, 18, 20, 0, 0, 80, + 65, 0, 0, 0, 0, 205, 204, 204, 61, 0, 0, 0, 0, 205, 204, 204, + 61, 26, 41, 10, 12, 114, 111, 97, 100, 95, 108, 105, 109, 105, 116, 101, + 100, 29, 255, 187, 187, 187, 34, 20, 8, 3, 18, 16, 0, 0, 0, 0, + 0, 0, 128, 63, 0, 0, 240, 65, 0, 0, 128, 63, 26, 65, 10, 12, + 114, 111, 97, 100, 95, 114, 101, 103, 117, 108, 97, 114, 29, 255, 153, 153, + 153, 34, 44, 8, 3, 18, 40, 0, 0, 0, 0, 0, 0, 0, 63, 0, + 0, 80, 65, 0, 0, 0, 63, 0, 0, 128, 65, 0, 0, 0, 64, 0, + 0, 160, 65, 0, 0, 0, 66, 0, 0, 240, 65, 0, 0, 0, 66, 26, + 71, 10, 10, 114, 111, 97, 100, 95, 108, 97, 114, 103, 101, 29, 255, 102, + 102, 102, 34, 52, 8, 3, 18, 48, 0, 0, 0, 0, 0, 0, 0, 63, + 0, 0, 48, 65, 0, 0, 0, 63, 0, 0, 80, 65, 0, 0, 128, 63, + 0, 0, 128, 65, 0, 0, 128, 64, 0, 0, 160, 65, 0, 0, 128, 66, + 0, 0, 240, 65, 0, 0, 128, 66 }; const unsigned long resources::style_size = sizeof(resources::style);