diff options
88 files changed, 836 insertions, 890 deletions
diff --git a/.travis.yml b/.travis.yml index eb4e700b1e..b641c11589 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,9 @@ language: cpp os: - linux + - osx compiler: - - gcc - clang env: @@ -17,28 +17,25 @@ env: - secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I=" before_install: -- ./scripts/setup_travis.sh - source ./scripts/flags.sh +- ./scripts/travis_before_install.sh install: - make setup -- npm install git+https://github.com/mapbox/mapbox-gl-test-suite.git +- ./scripts/travis_install.sh before_script: - rm -rf mapnik-packaging/out/packages script: -- make linux -j4 BUILDTYPE=${BUILDTYPE} -- make test -j4 BUILDTYPE=${BUILDTYPE} -- ./scripts/run_tests.sh -- (cd ./node_modules/mapbox-gl-test-suite/ && (./bin/compare_images.js; ./bin/deploy_results.sh)) +- ./scripts/travis_script.sh notifications: hipchat: rooms: secure: "SgMjGDp8MP+UTAY/aWJwSQH2hv1Q0vhEc1BdIde59+lEL3u6gNMSexUTSJoVxRlIQTFXDJBU7v58ISdgJX8cPa+UvIC8hhLsayM+cbm+J3jgy7V9E9wllq3RpmXN33TxY7nwKgWdIms2t9YKZco3y4dKKAUyHXrtMvw8NNPQM+4=" template: - - 'Build <a href="%{build_url}">#%{build_number}</a>: %{author} tested <a href="%{compare_url}">%{commit}</a> in branch <a href="https://github.com/%{repository_slug}/tree/%{branch}">%{branch}</a> of <a href="https://github.com/%{repository_slug}">%{repository_name}</a>: <b>%{commit_message}</b><br>%{message} (%{duration}) - Compare: <a href="http://mapbox-gl-testing.s3.amazonaws.com/headless/%{build_number}.1/index.html">1</a> <a href="http://mapbox-gl-testing.s3.amazonaws.com/headless/%{build_number}.2/index.html">2</a> <a href="http://mapbox-gl-testing.s3.amazonaws.com/headless/%{build_number}.3/index.html">3</a> <a href="http://mapbox-gl-testing.s3.amazonaws.com/headless/%{build_number}.4/index.html">4</a>' + - 'Build <a href="%{build_url}">#%{build_number}</a>: %{author} tested <a href="%{compare_url}">%{commit}</a> in branch <a href="https://github.com/%{repository_slug}/tree/%{branch}">%{branch}</a> of <a href="https://github.com/%{repository_slug}">%{repository_name}</a>: <b>%{commit_message}</b><br>%{message} (%{duration})' format: html git: @@ -73,8 +73,10 @@ clear_xcode_cache: fi # build Mac OS X project for Xcode -xproj: config.gypi macosx/mapboxgl-app.gyp clear_xcode_cache node +xproj-cli: config.gypi macosx/mapboxgl-app.gyp clear_xcode_cache node deps/run_gyp macosx/mapboxgl-app.gyp --depth=. --generator-output=./build -f xcode + +xproj: xproj-cli open ./build/macosx/mapboxgl-app.xcodeproj # build iOS project for Xcode @@ -53,10 +53,13 @@ To create projects, you can run: and settings storage. This is what is also being built on Linux. - `make linux`: Builds the Linux GLFW application with `make`. +Target OS: 10.9+ + ## iOS -iOS makes use of a Cocoa-specific API called [mapbox-gl-cocoa](https://github.com/mapbox/mapbox-gl-cocoa), -which is included as a submodule and provides a `UIView` interface to the map view and some bundle resources. +iOS makes use of a Cocoa-specific API called [`mapbox-gl-cocoa`](https://github.com/mapbox/mapbox-gl-cocoa). If you are just interested in running Mapbox GL on iOS and not developing with it, head to that project and you can use this library as a pre-built static library instead. A `UIView` interface to the map view and bundle resources are provided there. + +If you intend to develop here, `mapbox-gl-cocoa` is included as a submodule of the overall build setup. First, pull down the submodule(s): @@ -73,6 +76,8 @@ Lastly, `make iproj` to create and open an Xcode project with an iOS-specific vi Target devices: iPhone 4 and above (4S, 5, 5c, 5s) and iPad 2 and above (3, 4, mini and/or retina). +Target OS: 7.0+ + ## Ubuntu Set the environment variable `MAPBOX_ACCESS_TOKEN` to your token. @@ -104,13 +109,7 @@ You can then proceed to build the library like: # Style -The default stylesheet at `bin/style.js` is JSON and is processed into a minified version by the following script: - -``` -node bin/build-style.js bin/style.js out/ -``` - -Note: This is automatically taken care of as a build phase so you are not expected to do this manually. +Some styles in JSON format are included at `./styles`. See the [style spec](https://github.com/mapbox/mapbox-gl-style-spec) for more details. # Usage @@ -118,7 +117,6 @@ Note: This is automatically taken care of as a build phase so you are not expect - Press `X` to reset the transform - Press `N` to reset north -- Press `R` to toggle styles - Press `Tab` to toggle debug information - Press `Esc` to quit @@ -129,7 +127,7 @@ Note: This is automatically taken care of as a build phase so you are not expect - Use two fingers to rotate - Double-tap to zoom in one level - Two-finger single-tap to zoom out one level -- Single-tap to toggle the command palette visibility for resetting north & the transform, toggling debug, toggling styles, and locating the user +- Single-tap to toggle the command palette visibility for resetting north & the transform, toggling debug, and locating the user - Double-tap, long-pressing the second, then pan up and down to "quick zoom" (iPhone only, meant for one-handed use) # Other notes diff --git a/common/headless_view.cpp b/common/headless_view.cpp index 6a7d75d754..3fb090f2b5 100644 --- a/common/headless_view.cpp +++ b/common/headless_view.cpp @@ -153,7 +153,7 @@ HeadlessView::~HeadlessView() { #endif } -void HeadlessView::notify_map_change(mbgl::MapChange change, mbgl::timestamp delay) { +void HeadlessView::notify_map_change(mbgl::MapChange /*change*/, mbgl::timestamp /*delay*/) { // no-op } diff --git a/include/mbgl/geometry/buffer.hpp b/include/mbgl/geometry/buffer.hpp index 20489cb33c..446177d443 100644 --- a/include/mbgl/geometry/buffer.hpp +++ b/include/mbgl/geometry/buffer.hpp @@ -62,6 +62,10 @@ public: } } + inline GLuint getID() const { + return buffer; + } + protected: // increase the buffer size by at least /required/ bytes. inline void *addElement() { @@ -72,7 +76,7 @@ protected: while (length < pos + itemSize) length += defaultLength; array = realloc(array, length); if (array == nullptr) { - throw std::runtime_error("Buffer reallocation failed¯"); + throw std::runtime_error("Buffer reallocation failed"); } } pos += itemSize; @@ -106,7 +110,7 @@ private: size_t length = 0; // GL buffer ID - uint32_t buffer = 0; + GLuint buffer = 0; }; } diff --git a/include/mbgl/geometry/elements_buffer.hpp b/include/mbgl/geometry/elements_buffer.hpp index ed60338e08..1282beb239 100644 --- a/include/mbgl/geometry/elements_buffer.hpp +++ b/include/mbgl/geometry/elements_buffer.hpp @@ -4,10 +4,13 @@ #include <mbgl/geometry/buffer.hpp> #include <mbgl/geometry/vao.hpp> +#include <array> + namespace mbgl { +template <int count> struct ElementGroup { - VertexArrayObject array; + std::array<VertexArrayObject, count> array; uint32_t vertex_length; uint32_t elements_length; diff --git a/include/mbgl/geometry/glyph_atlas.hpp b/include/mbgl/geometry/glyph_atlas.hpp index e05cbe3b90..07011d324e 100644 --- a/include/mbgl/geometry/glyph_atlas.hpp +++ b/include/mbgl/geometry/glyph_atlas.hpp @@ -32,6 +32,7 @@ public: const SDFGlyph& glyph); void removeGlyphs(uint64_t tile_id); void bind(); + void upload(); public: const uint16_t width = 0; diff --git a/include/mbgl/geometry/sprite_atlas.hpp b/include/mbgl/geometry/sprite_atlas.hpp index dc2378c2fb..c30499a53d 100644 --- a/include/mbgl/geometry/sprite_atlas.hpp +++ b/include/mbgl/geometry/sprite_atlas.hpp @@ -41,14 +41,17 @@ public: // NEVER CALL THIS FUNCTION FROM THE RENDER THREAD! it is blocking. Rect<dimension> waitForImage(const std::string &name, const Sprite &sprite); - // Binds the image buffer of this sprite atlas to the GPU, and uploads data if it is out - // of date. + // Binds the image buffer of this sprite atlas to the GPU. void bind(bool linear = false); + // Uploads the image buffer to the GPU if it is out of date. + void upload(); + inline float getWidth() const { return width; } inline float getHeight() const { return height; } inline float getTextureWidth() const { return width * pixelRatio; } inline float getTextureHeight() const { return height * pixelRatio; } + inline float getPixelRatio() const { return pixelRatio; } private: void allocate(); diff --git a/include/mbgl/geometry/static_vertex_buffer.hpp b/include/mbgl/geometry/static_vertex_buffer.hpp new file mode 100644 index 0000000000..ce932269f0 --- /dev/null +++ b/include/mbgl/geometry/static_vertex_buffer.hpp @@ -0,0 +1,26 @@ +#ifndef MBGL_GEOMETRY_STATIC_VERTEX_BUFFER +#define MBGL_GEOMETRY_STATIC_VERTEX_BUFFER + +#include <mbgl/geometry/buffer.hpp> + +#include <vector> +#include <cstddef> +#include <cstdint> +#include <cmath> + +namespace mbgl { + +class StaticVertexBuffer : public Buffer< + 4, // bytes per vertex (2 * signed short == 4 bytes) + GL_ARRAY_BUFFER, + 32 // default length +> { +public: + typedef int16_t vertex_type; + + StaticVertexBuffer(std::initializer_list<std::pair<int16_t, int16_t>> init); +}; + +} + +#endif diff --git a/include/mbgl/geometry/vao.hpp b/include/mbgl/geometry/vao.hpp index 71d7ff89fe..87408ddbad 100644 --- a/include/mbgl/geometry/vao.hpp +++ b/include/mbgl/geometry/vao.hpp @@ -1,101 +1,74 @@ #ifndef MBGL_GEOMETRY_VAO #define MBGL_GEOMETRY_VAO +#include <mbgl/shader/shader.hpp> #include <mbgl/platform/gl.hpp> #include <stdexcept> namespace mbgl { +#if GL_ARB_vertex_array_object class VertexArrayObject { public: template <typename Shader, typename VertexBuffer> - void bind(Shader& shader, VertexBuffer& vertex_buffer, char *offset) { -#ifdef GL_ARB_vertex_array_object - 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!"); - } -#endif - vertex_buffer.bind(); + inline void bind(Shader& shader, VertexBuffer &vertexBuffer, char *offset) { + bindVertexArrayObject(); + if (bound_shader == 0) { + vertexBuffer.bind(); shader.bind(offset); - -#ifdef GL_ARB_vertex_array_object - shader_ptr = &shader; - vertex_buffer_ptr = &vertex_buffer; - elements_buffer_ptr = nullptr; - offset_ptr = offset; - } else if (vertex_buffer_ptr != &vertex_buffer) { - throw std::runtime_error("trying to bind VAO to another vertex buffer"); - } else if (elements_buffer_ptr != nullptr) { - 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"); + storeBinding(shader, vertexBuffer.getID(), 0, offset); + } else { + verifyBinding(shader, vertexBuffer.getID(), 0, offset); } -#endif } template <typename Shader, typename VertexBuffer, typename ElementsBuffer> - void bind(Shader& shader, VertexBuffer& vertex_buffer, ElementsBuffer& elements_buffer, char *offset) { -#ifdef GL_ARB_vertex_array_object - if (!vao) { - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - } else { - // We have been given the correct information. - glBindVertexArray(vao); - } - - if (shader_ptr != &shader) { -#endif - vertex_buffer.bind(); - elements_buffer.bind(); + inline void bind(Shader& shader, VertexBuffer &vertexBuffer, ElementsBuffer &elementsBuffer, char *offset) { + bindVertexArrayObject(); + if (bound_shader == 0) { + vertexBuffer.bind(); + elementsBuffer.bind(); shader.bind(offset); - -#ifdef GL_ARB_vertex_array_object - shader_ptr = &shader; - vertex_buffer_ptr = &vertex_buffer; - elements_buffer_ptr = &elements_buffer; - offset_ptr = offset; - } else if (vertex_buffer_ptr != &vertex_buffer) { - throw std::runtime_error("trying to bind VAO to another vertex buffer"); - } else if (elements_buffer_ptr != &elements_buffer) { - 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"); + storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset); + } else { + verifyBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset); } -#endif } - ~VertexArrayObject() { -#ifdef GL_ARB_vertex_array_object - if (vao) { - glDeleteVertexArrays(1, &vao); - } -#endif - } + ~VertexArrayObject(); private: -#ifdef GL_ARB_vertex_array_object + void bindVertexArrayObject(); + void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, char *offset); + void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, char *offset); + GLuint vao = 0; // 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; -#endif + GLuint bound_shader = 0; + const char *bound_shader_name = ""; + GLuint bound_vertex_buffer = 0; + GLuint bound_elements_buffer = 0; + char *bound_offset = 0; +}; + +#else + +class VertexArrayObject { +public: + template <typename Shader, typename Buffers> + void bind(Shader& shader, Buffers& buffers, char *offset) { + for (auto &buffer : buffers) { + buffer.bind(); + } + shader.bind(offset); + } }; +#endif + } #endif diff --git a/include/mbgl/geometry/vertex_buffer.hpp b/include/mbgl/geometry/vertex_buffer.hpp deleted file mode 100644 index 58fd4a9d03..0000000000 --- a/include/mbgl/geometry/vertex_buffer.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef MBGL_GEOMETRY_VERTEX_BUFFER -#define MBGL_GEOMETRY_VERTEX_BUFFER - -#include <vector> -#include <cstddef> -#include <cstdint> -#include <cmath> - -namespace mbgl { - -class VertexBuffer { -public: - typedef int16_t vertex_type; - VertexBuffer(std::initializer_list<vertex_type> init); - ~VertexBuffer(); - - /* - * Returns the number of elements in this buffer. This is not the number of - * bytes, but rather the number of coordinates with associated information. - */ - size_t index() const; - - /* - * Transfers this buffer to the GPU and binds the buffer to the GL context. - */ - void bind(); - -private: - const std::vector<vertex_type> array; - uint32_t buffer = 0; -}; - -} - -#endif diff --git a/include/mbgl/map/tile_parser.hpp b/include/mbgl/map/tile_parser.hpp index f011d47a38..fa64dad6d5 100644 --- a/include/mbgl/map/tile_parser.hpp +++ b/include/mbgl/map/tile_parser.hpp @@ -4,7 +4,6 @@ #include <mbgl/map/vector_tile.hpp> #include <mbgl/style/filter_expression.hpp> #include <mbgl/text/glyph.hpp> -#include <mbgl/text/collision.hpp> #include <cstdint> #include <iosfwd> @@ -28,6 +27,7 @@ class StyleBucketLine; class StyleBucketSymbol; class StyleLayerGroup; class VectorTileData; +class Collision; class TileParser { public: @@ -37,6 +37,7 @@ public: const std::shared_ptr<GlyphStore> &glyphStore, const std::shared_ptr<SpriteAtlas> &spriteAtlas, const std::shared_ptr<Sprite> &sprite); + ~TileParser(); public: void parse(); @@ -65,7 +66,7 @@ private: std::shared_ptr<Sprite> sprite; std::shared_ptr<Texturepool> texturePool; - Collision collision; + std::unique_ptr<Collision> collision; }; } diff --git a/include/mbgl/platform/gl.hpp b/include/mbgl/platform/gl.hpp index a29b230dbf..cc2a681d42 100644 --- a/include/mbgl/platform/gl.hpp +++ b/include/mbgl/platform/gl.hpp @@ -26,9 +26,12 @@ #elif TARGET_OS_MAC #include <OpenGL/OpenGL.h> #include <OpenGL/gl.h> - #define glGenVertexArrays glGenVertexArraysAPPLE - #define glBindVertexArray glBindVertexArrayAPPLE - #define glDeleteVertexArrays glDeleteVertexArraysAPPLE + #if GL_APPLE_vertex_array_object + #define GL_ARB_vertex_array_object 1 + #define glGenVertexArrays glGenVertexArraysAPPLE + #define glBindVertexArray glBindVertexArrayAPPLE + #define glDeleteVertexArrays glDeleteVertexArraysAPPLE + #endif #else #error Unsupported Apple platform #endif diff --git a/include/mbgl/renderer/fill_bucket.hpp b/include/mbgl/renderer/fill_bucket.hpp index e9340cce68..e8d6bf99e1 100644 --- a/include/mbgl/renderer/fill_bucket.hpp +++ b/include/mbgl/renderer/fill_bucket.hpp @@ -34,9 +34,8 @@ class FillBucket : public Bucket { static void *realloc(void *data, void *ptr, unsigned int size); static void free(void *userData, void *ptr); - - typedef ElementGroup triangle_group_type; - typedef ElementGroup line_group_type; + typedef ElementGroup<2> triangle_group_type; + typedef ElementGroup<1> line_group_type; public: FillBucket(FillVertexBuffer& vertexBuffer, TriangleElementsBuffer& triangleElementsBuffer, diff --git a/include/mbgl/renderer/line_bucket.hpp b/include/mbgl/renderer/line_bucket.hpp index f65ca35605..a33dde34e0 100644 --- a/include/mbgl/renderer/line_bucket.hpp +++ b/include/mbgl/renderer/line_bucket.hpp @@ -20,8 +20,8 @@ class LinejoinShader; struct pbf; class LineBucket : public Bucket { - typedef ElementGroup triangle_group_type; - typedef ElementGroup point_group_type; + typedef ElementGroup<1> triangle_group_type; + typedef ElementGroup<1> point_group_type; public: LineBucket(LineVertexBuffer& vertexBuffer, TriangleElementsBuffer& triangleElementsBuffer, diff --git a/include/mbgl/renderer/painter.hpp b/include/mbgl/renderer/painter.hpp index 26e1bd3955..eb5f427898 100644 --- a/include/mbgl/renderer/painter.hpp +++ b/include/mbgl/renderer/painter.hpp @@ -3,7 +3,7 @@ #include <mbgl/map/tile_data.hpp> #include <mbgl/geometry/vao.hpp> -#include <mbgl/geometry/vertex_buffer.hpp> +#include <mbgl/geometry/static_vertex_buffer.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/renderer/frame_history.hpp> @@ -18,7 +18,6 @@ #include <mbgl/shader/raster_shader.hpp> #include <mbgl/shader/text_shader.hpp> #include <mbgl/shader/dot_shader.hpp> -#include <mbgl/shader/composite_shader.hpp> #include <mbgl/shader/gaussian_shader.hpp> #include <mbgl/map/transform_state.hpp> @@ -46,7 +45,6 @@ class PrerenderedTexture; struct FillProperties; struct RasterProperties; -struct CompositeProperties; class LayerDescription; class RasterTileData; @@ -111,13 +109,11 @@ public: void drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &sources); void drawClippingMask(const mat4& matrix, const ClipID& clip); - void clearFramebuffers(); void resetFramebuffer(); void bindFramebuffer(); void pushFramebuffer(); GLuint popFramebuffer(); void discardFramebuffers(); - void drawComposite(GLuint texture, const CompositeProperties &properties); bool needsAnimation() const; private: @@ -130,6 +126,7 @@ public: void useProgram(uint32_t program); void lineWidth(float lineWidth); void depthMask(bool value); + void depthRange(float near, float far); public: mat4 vtxMatrix; @@ -156,6 +153,7 @@ private: float gl_lineWidth = 0; bool gl_depthMask = true; std::array<uint16_t, 2> gl_viewport = {{ 0, 0 }}; + std::array<float, 2> gl_depthRange = {{ 0, 1 }}; float strata = 0; RenderPass pass = RenderPass::Opaque; const float strata_epsilon = 1.0f / (1 << 16); @@ -170,20 +168,19 @@ public: std::unique_ptr<RasterShader> rasterShader; std::unique_ptr<TextShader> textShader; std::unique_ptr<DotShader> dotShader; - std::unique_ptr<CompositeShader> compositeShader; std::unique_ptr<GaussianShader> gaussianShader; // Set up the stencil quad we're using to generate the stencil mask. - VertexBuffer tileStencilBuffer = { + StaticVertexBuffer tileStencilBuffer = { // top left triangle - 0, 0, - 4096, 0, - 0, 4096, + { 0, 0 }, + { 4096, 0 }, + { 0, 4096 }, // bottom right triangle - 4096, 0, - 0, 4096, - 4096, 4096 + { 4096, 0 }, + { 0, 4096 }, + { 4096, 4096 }, }; VertexArrayObject coveringPlainArray; @@ -191,16 +188,15 @@ public: VertexArrayObject coveringRasterArray; VertexArrayObject coveringGaussianArray; - VertexArrayObject compositeArray; VertexArrayObject matteArray; // Set up the tile boundary lines we're using to draw the tile outlines. - VertexBuffer tileBorderBuffer = { - 0, 0, - 4096, 0, - 4096, 4096, - 0, 4096, - 0, 0 + StaticVertexBuffer tileBorderBuffer = { + { 0, 0 }, + { 4096, 0 }, + { 4096, 4096 }, + { 0, 4096 }, + { 0, 0 }, }; VertexArrayObject tileBorderArray; diff --git a/include/mbgl/renderer/raster_bucket.hpp b/include/mbgl/renderer/raster_bucket.hpp index a68475565b..66cceac8e7 100644 --- a/include/mbgl/renderer/raster_bucket.hpp +++ b/include/mbgl/renderer/raster_bucket.hpp @@ -11,7 +11,7 @@ namespace mbgl { class RasterShader; -class VertexBuffer; +class StaticVertexBuffer; class VertexArrayObject; class RasterBucket : public Bucket { @@ -26,9 +26,9 @@ public: const StyleBucketRaster &properties; PrerenderedTexture texture; - void drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array); + void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array); - void drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array, GLuint texture); + void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, GLuint texture); Raster raster; diff --git a/include/mbgl/renderer/symbol_bucket.hpp b/include/mbgl/renderer/symbol_bucket.hpp index e890274238..fb1678fc8b 100644 --- a/include/mbgl/renderer/symbol_bucket.hpp +++ b/include/mbgl/renderer/symbol_bucket.hpp @@ -50,6 +50,9 @@ typedef std::vector<Symbol> Symbols; class SymbolBucket : public Bucket { + typedef ElementGroup<1> TextElementGroup; + typedef ElementGroup<1> IconElementGroup; + public: SymbolBucket(const StyleBucketSymbol &properties, Collision &collision); @@ -94,13 +97,13 @@ private: struct { TextVertexBuffer vertices; TriangleElementsBuffer triangles; - std::vector<ElementGroup> groups; + std::vector<TextElementGroup> groups; } text; struct { IconVertexBuffer vertices; TriangleElementsBuffer triangles; - std::vector<ElementGroup> groups; + std::vector<IconElementGroup> groups; } icon; }; diff --git a/include/mbgl/shader/composite_shader.hpp b/include/mbgl/shader/composite_shader.hpp deleted file mode 100644 index c0c1704f3d..0000000000 --- a/include/mbgl/shader/composite_shader.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MBGL_SHADER_COMPOSITE_SHADER -#define MBGL_SHADER_COMPOSITE_SHADER - -#include <mbgl/shader/shader.hpp> - -namespace mbgl { - -class CompositeShader : public Shader { -public: - CompositeShader(); - - void bind(char *offset); - - void setImage(int32_t image); - void setOpacity(float opacity); - -private: - int32_t a_pos = -1; - - int32_t image = 0; - int32_t u_image = -1; - - float opacity = 0; - int32_t u_opacity = -1; -}; - -} - -#endif diff --git a/include/mbgl/shader/pattern_shader.hpp b/include/mbgl/shader/pattern_shader.hpp index b1b49b54df..e574b755dc 100644 --- a/include/mbgl/shader/pattern_shader.hpp +++ b/include/mbgl/shader/pattern_shader.hpp @@ -11,33 +11,33 @@ public: void bind(char *offset); - void setColor(const std::array<float, 4>& color); - void setOffset(const std::array<float, 2>& offset); - void setPatternSize(const std::array<float, 2>& pattern_size); void setPatternTopLeft(const std::array<float, 2>& pattern_tl); void setPatternBottomRight(const std::array<float, 2>& pattern_br); + void setOpacity(float opacity); + void setImage(int image); void setMix(float mix); + void setPatternMatrix(const std::array<float, 9> &patternmatrix); private: int32_t a_pos = -1; - std::array<float, 4> color = {{}}; - int32_t u_color = -1; - - std::array<float, 2> offset = {{}}; - int32_t u_offset = -1; - - std::array<float, 2> pattern_size = {{}}; - int32_t u_pattern_size = -1; - std::array<float, 2> pattern_tl = {{}}; int32_t u_pattern_tl = -1; std::array<float, 2> pattern_br = {{}}; int32_t u_pattern_br = -1; + float opacity = 0; + int32_t u_opacity = -1; + + int image = 0; + int32_t u_image = -1; + float mix = 0; int32_t u_mix = -1; + + std::array<float, 9> patternmatrix = {{}}; + int32_t u_patternmatrix = -1; }; } diff --git a/include/mbgl/shader/shader.hpp b/include/mbgl/shader/shader.hpp index 2398cb12e3..fa2d5a0a8e 100644 --- a/include/mbgl/shader/shader.hpp +++ b/include/mbgl/shader/shader.hpp @@ -9,13 +9,18 @@ namespace mbgl { class Shader : private util::noncopyable { public: - Shader(const char *vertex, const char *fragment); + Shader(const char *name, const char *vertex, const char *fragment); ~Shader(); + const char *name; bool valid; uint32_t program; void setMatrix(const std::array<float, 16>& matrix); + inline uint32_t getID() const { + return program; + } + private: bool compileShader(uint32_t *shader, uint32_t type, const char *source); diff --git a/include/mbgl/style/filter_expression.hpp b/include/mbgl/style/filter_expression.hpp index 2a6a2927e7..2a96578792 100644 --- a/include/mbgl/style/filter_expression.hpp +++ b/include/mbgl/style/filter_expression.hpp @@ -10,7 +10,7 @@ namespace mbgl { class FilterExpression { public: - typedef util::recursive_wrapper<FilterExpression> Wrapper; + typedef mapbox::util::recursive_wrapper<FilterExpression> Wrapper; enum class Operator : uint8_t { And, diff --git a/include/mbgl/style/function_properties.hpp b/include/mbgl/style/function_properties.hpp index 8cd7ce6e28..56092f9a63 100644 --- a/include/mbgl/style/function_properties.hpp +++ b/include/mbgl/style/function_properties.hpp @@ -27,7 +27,7 @@ private: }; template <typename T> -using Function = util::variant< +using Function = mapbox::util::variant< std::false_type, ConstantFunction<T>, StopsFunction<T> diff --git a/include/mbgl/style/property_key.hpp b/include/mbgl/style/property_key.hpp index aee5db0385..ec68ea991e 100644 --- a/include/mbgl/style/property_key.hpp +++ b/include/mbgl/style/property_key.hpp @@ -51,8 +51,6 @@ enum class PropertyKey { TextTranslateY, TextTranslateAnchor, - CompositeOpacity, - RasterOpacity, RasterHueRotate, RasterBrightness, // for transitions only diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp index 4d148dc029..1b22b31177 100644 --- a/include/mbgl/style/property_value.hpp +++ b/include/mbgl/style/property_value.hpp @@ -7,7 +7,7 @@ namespace mbgl { -typedef util::variant< +typedef mapbox::util::variant< std::string, TranslateAnchorType, RotateAnchorType, diff --git a/include/mbgl/style/style_bucket.hpp b/include/mbgl/style/style_bucket.hpp index 11b87d849d..67c3142059 100644 --- a/include/mbgl/style/style_bucket.hpp +++ b/include/mbgl/style/style_bucket.hpp @@ -40,6 +40,7 @@ public: PlacementType placement = PlacementType::Point; float min_distance = 250.0f; + bool avoid_edges = false; struct { bool allow_overlap = false; @@ -88,8 +89,8 @@ public: float buffer = 0.03125f; }; -typedef util::variant<StyleBucketFill, StyleBucketLine, StyleBucketSymbol, - StyleBucketRaster, std::false_type> StyleBucketRender; +typedef mapbox::util::variant<StyleBucketFill, StyleBucketLine, StyleBucketSymbol, + StyleBucketRaster, std::false_type> StyleBucketRender; class StyleBucket { diff --git a/include/mbgl/style/style_properties.hpp b/include/mbgl/style/style_properties.hpp index f12ab430e3..bbe8812bc7 100644 --- a/include/mbgl/style/style_properties.hpp +++ b/include/mbgl/style/style_properties.hpp @@ -76,16 +76,6 @@ struct SymbolProperties { } }; - -struct CompositeProperties { - inline CompositeProperties() {} - float opacity = 1.0f; - - inline bool isVisible() const { - return opacity > 0; - } -}; - struct RasterProperties { inline RasterProperties() {} float opacity = 1.0f; @@ -105,11 +95,10 @@ struct BackgroundProperties { Color color = {{ 0, 0, 0, 1 }}; }; -typedef util::variant< +typedef mapbox::util::variant< FillProperties, LineProperties, SymbolProperties, - CompositeProperties, RasterProperties, BackgroundProperties, std::false_type diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index 55b7685fd3..fa21f819a5 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -19,7 +19,6 @@ enum class StyleLayerType : uint8_t { Line, Symbol, Raster, - Composite, Background }; @@ -29,7 +28,6 @@ MBGL_DEFINE_ENUM_CLASS(StyleLayerTypeClass, StyleLayerType, { { StyleLayerType::Line, "line" }, { StyleLayerType::Symbol, "symbol" }, { StyleLayerType::Raster, "raster" }, - { StyleLayerType::Composite, "composite" }, { StyleLayerType::Background, "background" }, { StyleLayerType(-1), "unknown" }, }); diff --git a/include/mbgl/style/value.hpp b/include/mbgl/style/value.hpp index 5e6260e5a6..b981f1db9c 100644 --- a/include/mbgl/style/value.hpp +++ b/include/mbgl/style/value.hpp @@ -9,7 +9,7 @@ namespace mbgl { -typedef util::variant<bool, int64_t, uint64_t, double, std::string> Value; +typedef mapbox::util::variant<bool, int64_t, uint64_t, double, std::string> Value; std::string toString(const Value &value); diff --git a/include/mbgl/text/collision.hpp b/include/mbgl/text/collision.hpp index 87ebdb279e..7e65e979da 100644 --- a/include/mbgl/text/collision.hpp +++ b/include/mbgl/text/collision.hpp @@ -3,23 +3,47 @@ #include <mbgl/text/types.hpp> +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wdeprecated-register" +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif +#include <boost/geometry.hpp> +#include <boost/geometry/geometries/point.hpp> +#include <boost/geometry/geometries/box.hpp> +#include <boost/geometry/index/rtree.hpp> +#pragma GCC diagnostic pop + namespace mbgl { +namespace bg = boost::geometry; +namespace bgm = bg::model; +namespace bgi = bg::index; +typedef bgm::point<float, 2, bg::cs::cartesian> Point; +typedef bgm::box<Point> Box; +typedef std::pair<Box, PlacementBox> PlacementValue; +typedef bgi::rtree<PlacementValue, bgi::rstar<16>> Tree; + class Collision { public: Collision(float zoom, float tileExtent, float tileSize, float placementDepth = 1); - ~Collision(); - float getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale); + float getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale, bool avoidEdges); PlacementRange getPlacementRange(const GlyphBoxes &glyphs, float placementScale, bool horizontal); void insert(const GlyphBoxes &glyphs, const CollisionAnchor &anchor, float placementScale, const PlacementRange &placementRange, bool horizontal); private: - void *hTree; - void *cTree; + Tree hTree; + Tree cTree; + PlacementValue leftEdge; + PlacementValue topEdge; + PlacementValue rightEdge; + PlacementValue bottomEdge; public: const float tilePixelRatio; diff --git a/include/mbgl/util/mat3.hpp b/include/mbgl/util/mat3.hpp new file mode 100644 index 0000000000..d44b1435d3 --- /dev/null +++ b/include/mbgl/util/mat3.hpp @@ -0,0 +1,40 @@ +// This is an incomplete port of http://glmatrix.net/ +// +// Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the +// use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not claim +// that you wrote the original software. If you use this software in a +// product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. + +#ifndef MBGL_UTIL_MAT3 +#define MBGL_UTIL_MAT3 + +#include <array> + +namespace mbgl { + +typedef std::array<float, 9> mat3; + +namespace matrix { + +void identity(mat3& out); +void scale(mat3& out, const mat3& a, float x, float y); + +} +} + +#endif diff --git a/include/mbgl/util/recursive_wrapper.hpp b/include/mbgl/util/recursive_wrapper.hpp index a616805c0f..54b27634a3 100644 --- a/include/mbgl/util/recursive_wrapper.hpp +++ b/include/mbgl/util/recursive_wrapper.hpp @@ -3,7 +3,7 @@ #include <utility> -namespace mbgl { namespace util { +namespace mapbox { namespace util { template <typename T> class recursive_wrapper diff --git a/include/mbgl/util/variant.hpp b/include/mbgl/util/variant.hpp index ddc82ee311..1eca5160c7 100644 --- a/include/mbgl/util/variant.hpp +++ b/include/mbgl/util/variant.hpp @@ -35,7 +35,7 @@ // translates to 100 #define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION) -namespace mbgl { namespace util { namespace detail { +namespace mapbox { namespace util { namespace detail { static constexpr std::size_t invalid_value = std::size_t(-1); @@ -487,6 +487,8 @@ private: } // namespace detail +struct no_init {}; + template<typename... Types> class variant { @@ -503,12 +505,16 @@ private: public: + VARIANT_INLINE variant() : type_index(sizeof...(Types) - 1) { new (&data) typename detail::select_type<0, Types...>::type(); } + VARIANT_INLINE variant(no_init) + : type_index(detail::invalid_value) {} + template <typename T, class = typename std::enable_if< detail::is_valid_type<T, Types...>::value>::type> VARIANT_INLINE explicit variant(T const& val) noexcept @@ -715,11 +721,24 @@ auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::bin return V::binary_visit(v0, v1, f); } +// getter interface +template<typename ResultType, typename T> +ResultType & get(T & var) +{ + return var.template get<ResultType>(); +} + +template<typename ResultType, typename T> +ResultType const& get(T const& var) +{ + return var.template get<ResultType>(); +} + // operator<< -template <typename charT, typename traits, typename Variant> +template <typename charT, typename traits, typename... Types> VARIANT_INLINE std::basic_ostream<charT, traits>& -operator<< (std::basic_ostream<charT, traits>& out, Variant const& rhs) +operator<< (std::basic_ostream<charT, traits>& out, variant<Types...> const& rhs) { detail::printer<std::basic_ostream<charT, traits>> visitor(out); apply_visitor(visitor, rhs); diff --git a/ios/mapbox-gl-cocoa b/ios/mapbox-gl-cocoa -Subproject 9d4320aefaa3868ecd5d0a4e0ce902b0adef78c +Subproject e1c709a8de0b69aa6bfbcd9ea4faf981b6e799b diff --git a/scripts/flags.sh b/scripts/flags.sh index 0c0981cdc1..0c0981cdc1 100644..100755 --- a/scripts/flags.sh +++ b/scripts/flags.sh diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh deleted file mode 100755 index 7165948248..0000000000 --- a/scripts/run_tests.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -cd build/Testing - -for TEST in ./test_* ; do - ${TEST} -done diff --git a/scripts/setup_travis.sh b/scripts/travis_before_install.sh index 128f6bbf72..e9b3384dec 100755 --- a/scripts/setup_travis.sh +++ b/scripts/travis_before_install.sh @@ -4,16 +4,24 @@ set -e set -o pipefail if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then - + # + # install Linux dependencies + # if [[ `lsb_release -r` =~ "12.04" ]]; then sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test fi sudo apt-get update -y sudo apt-get -y install gcc-4.8 g++-4.8 - sudo apt-get -y install git build-essential zlib1g-dev automake libtool xutils-dev make cmake pkg-config python-pip - sudo apt-get -y install libxi-dev libglu1-mesa-dev x11proto-randr-dev x11proto-xext-dev libxrandr-dev x11proto-xf86vidmode-dev libxxf86vm-dev libxcursor-dev - + sudo apt-get -y install git build-essential zlib1g-dev automake \ + libtool xutils-dev make cmake pkg-config python-pip + sudo apt-get -y install libxi-dev libglu1-mesa-dev x11proto-randr-dev \ + x11proto-xext-dev libxrandr-dev \ + x11proto-xf86vidmode-dev libxxf86vm-dev libxcursor-dev sudo pip install awscli elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then + # + # install OS X dependencies + # brew install autoconf automake libtool makedepend cmake pkg-config node git + sudo pip install awscli fi diff --git a/scripts/travis_install.sh b/scripts/travis_install.sh new file mode 100755 index 0000000000..eca24e719c --- /dev/null +++ b/scripts/travis_install.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then + # + # we'll need the test suite on Linux + # + npm install git+https://github.com/mapbox/mapbox-gl-test-suite.git +fi diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh new file mode 100755 index 0000000000..61c2e52059 --- /dev/null +++ b/scripts/travis_script.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then + # + # build & test Linux + # + make linux -j4 BUILDTYPE=${BUILDTYPE} + make test -j4 BUILDTYPE=${BUILDTYPE} + cd build/Testing + for TEST in ./test_* ; do + ${TEST} + done + cd ../.. + (cd ./node_modules/mapbox-gl-test-suite/ && (./bin/compare_images.js || true; ./bin/deploy_results.sh)) +elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then + # + # build OS X + # + make xproj-cli + xcodebuild -project ./build/macosx/mapboxgl-app.xcodeproj + # + # build iOS + # + git clone --depth 1 https://github.com/mapbox/mapbox-gl-cocoa ios/mapbox-gl-cocoa + make iproj-cli + xcodebuild -project ./build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO +fi diff --git a/setup-libraries.sh b/setup-libraries.sh index c8a9bc1c25..e1ad79daf0 100755 --- a/setup-libraries.sh +++ b/setup-libraries.sh @@ -16,7 +16,6 @@ ensure_dep cmake ensure_dep automake ensure_dep autoconf ensure_dep pkg-config -ensure_dep node if [ ${UNAME} = 'Darwin' ]; then ensure_dep makedepend if [[ ! `which libtool` ]] && [[ ! `which glibtool` ]]; then @@ -30,29 +29,51 @@ fi if [[ $MISSING_DEPS != "" ]]; then if [ ${UNAME} = 'Darwin' ]; then echo "Missing build deps: ${MISSING_DEPS}" - echo 'Please run "brew install autoconf automake libtool makedepend cmake pkg-config node"' + echo 'Please run "brew install autoconf automake libtool makedepend cmake pkg-config"' echo 'and then re-run ./setup-libraries.sh' elif [ ${UNAME} = 'Linux' ]; then echo "Missing build deps: ${MISSING_DEPS}" - echo 'Please run "sudo apt-get install git build-essential zlib1g-dev automake libtool xutils-dev make cmake pkg-config nodejs-legacy libxi-dev libglu1-mesa-dev x11proto-randr-dev x11proto-xext-dev libxrandr-dev x11proto-xf86vidmode-dev libxxf86vm-dev libxcursor-dev"' + echo 'Please run "sudo apt-get install git build-essential zlib1g-dev automake libtool xutils-dev make cmake pkg-config libxi-dev libglu1-mesa-dev x11proto-randr-dev x11proto-xext-dev libxrandr-dev x11proto-xf86vidmode-dev libxxf86vm-dev libxcursor-dev"' echo 'and then re-run ./setup-libraries.sh' fi exit 1 fi -NODE=`which node` -NPM=`which npm` +# bootstrap node install +if [[ ! -d ~/.nvm ]]; then + git clone --depth 1 https://github.com/creationix/nvm.git ~/.nvm +fi +set +u +source ~/.nvm/nvm.sh +nvm install 0.10 +set -u + +NODE=$(which node) +NPM=$(which npm) -if [ ! -d 'mapnik-packaging/.git' ]; then - git clone --depth=1 https://github.com/mapnik/mapnik-packaging.git +MP_HASH="6d7e83e8042" +if [ ! -d 'mapnik-packaging/' ]; then + git clone https://github.com/mapnik/mapnik-packaging.git fi -cd mapnik-packaging/osx/ -git pull +cd mapnik-packaging +git fetch +git checkout ${MP_HASH} +cd ./osx/ export CXX11=true if [ ${UNAME} = 'Darwin' ]; then + +if [ ! -z "${TRAVIS:-}" ]; then + if aws s3 cp s3://mapbox-gl-testing/dependencies/build-cpp11-libcpp-universal_${MP_HASH}.tar.gz ./out/ ; then + rm -rf out/build-cpp11-libcpp-universal + tar -xzf out/build-cpp11-libcpp-universal_${MP_HASH}.tar.gz + fi +fi + +if test -z "${TRAVIS:-}" || ! test -d out/build-cpp11-libcpp-universal; then + source iPhoneOS.sh export LIBUV_VERSION=0.10.28 if [ ! -f out/build-cpp11-libcpp-armv7-iphoneos/lib/libpng.a ] ; then ./scripts/build_png.sh ; fi @@ -96,6 +117,13 @@ export LIBUV_VERSION=0.10.28 ./scripts/make_universal.sh +if [ ! -z "${TRAVIS:-}" ]; then + tar -zcf out/build-cpp11-libcpp-universal_${MP_HASH}.tar.gz out/build-cpp11-libcpp-universal + aws s3 cp out/build-cpp11-libcpp-universal_${MP_HASH}.tar.gz s3://mapbox-gl-testing/dependencies/ +fi + +fi + cd ../../ ./configure \ --pkg-config-root=`pwd`/mapnik-packaging/osx/out/build-cpp11-libcpp-universal/lib/pkgconfig \ diff --git a/src/geometry/glyph_atlas.cpp b/src/geometry/glyph_atlas.cpp index 76df941d90..9e74e21b24 100644 --- a/src/geometry/glyph_atlas.cpp +++ b/src/geometry/glyph_atlas.cpp @@ -120,6 +120,46 @@ void GlyphAtlas::removeGlyphs(uint64_t tile_id) { } } +void GlyphAtlas::upload() { + if (dirty) { + const bool exists = texture; + bind(); + + std::lock_guard<std::mutex> lock(mtx); + + if (!exists) { + glTexImage2D( + GL_TEXTURE_2D, // GLenum target + 0, // GLint level + GL_ALPHA, // GLint internalformat + width, // GLsizei width + height, // GLsizei height + 0, // GLint border + GL_ALPHA, // GLenum format + GL_UNSIGNED_BYTE, // GLenum type + data // const GLvoid * data + ); + } else { + glTexSubImage2D( + GL_TEXTURE_2D, // GLenum target + 0, // GLint level + 0, // GLint xoffset + 0, // GLint yoffset + width, // GLsizei width + height, // GLsizei height + GL_ALPHA, // GLenum format + GL_UNSIGNED_BYTE, // GLenum type + data // const GLvoid *pixels + ); + } + dirty = false; + +#if defined(DEBUG) + // platform::show_debug_image("Glyph Atlas", data, width, height); +#endif + } +} + void GlyphAtlas::bind() { if (!texture) { glGenTextures(1, &texture); @@ -131,14 +171,4 @@ void GlyphAtlas::bind() { } else { glBindTexture(GL_TEXTURE_2D, texture); } - - if (dirty) { - std::lock_guard<std::mutex> lock(mtx); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); - dirty = false; - -#if defined(DEBUG) - // platform::show_debug_image("Glyph Atlas", data, width, height); -#endif - } }; diff --git a/src/geometry/sprite_atlas.cpp b/src/geometry/sprite_atlas.cpp index 71d3cbee99..730551dbeb 100644 --- a/src/geometry/sprite_atlas.cpp +++ b/src/geometry/sprite_atlas.cpp @@ -196,13 +196,11 @@ void SpriteAtlas::update(const Sprite &sprite) { } void SpriteAtlas::bind(bool linear) { - bool first = false; if (!texture) { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - first = true; } else { glBindTexture(GL_TEXTURE_2D, texture); } @@ -213,12 +211,17 @@ void SpriteAtlas::bind(bool linear) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_val); filter = filter_val; } +} +void SpriteAtlas::upload() { if (dirty) { + const bool exists = texture; + bind(filter); // Make sure we don't change the filter value. + std::lock_guard<std::mutex> lock(mtx); allocate(); - if (first) { + if (!exists) { glTexImage2D( GL_TEXTURE_2D, // GLenum target 0, // GLint level @@ -231,7 +234,8 @@ void SpriteAtlas::bind(bool linear) { data // const GLvoid * data ); } else { - glTexSubImage2D(GL_TEXTURE_2D, // GLenum target + glTexSubImage2D( + GL_TEXTURE_2D, // GLenum target 0, // GLint level 0, // GLint xoffset 0, // GLint yoffset @@ -248,7 +252,7 @@ void SpriteAtlas::bind(bool linear) { #endif dirty = false; } -}; +} SpriteAtlas::~SpriteAtlas() { std::lock_guard<std::mutex> lock(mtx); diff --git a/src/geometry/static_vertex_buffer.cpp b/src/geometry/static_vertex_buffer.cpp new file mode 100644 index 0000000000..c86211c50f --- /dev/null +++ b/src/geometry/static_vertex_buffer.cpp @@ -0,0 +1,14 @@ +#include <mbgl/geometry/static_vertex_buffer.hpp> +#include <mbgl/platform/gl.hpp> + +namespace mbgl { + +StaticVertexBuffer::StaticVertexBuffer(std::initializer_list<std::pair<int16_t, int16_t>> init) { + for (const std::pair<int16_t, int16_t> &vertex : init) { + vertex_type *vertices = static_cast<vertex_type *>(addElement()); + vertices[0] = vertex.first; + vertices[1] = vertex.second; + } +} + +} diff --git a/src/geometry/vao.cpp b/src/geometry/vao.cpp new file mode 100644 index 0000000000..4c459c436d --- /dev/null +++ b/src/geometry/vao.cpp @@ -0,0 +1,46 @@ +#include <mbgl/geometry/vao.hpp> + +namespace mbgl { + +#if GL_ARB_vertex_array_object + +VertexArrayObject::~VertexArrayObject() { + if (vao) { + glDeleteVertexArrays(1, &vao); + } +} + +void VertexArrayObject::bindVertexArrayObject() { + if (!vao) { + glGenVertexArrays(1, &vao); + } + glBindVertexArray(vao); +} + +void VertexArrayObject::verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, + char *offset) { + if (bound_shader != shader.getID()) { + throw std::runtime_error(std::string("trying to rebind VAO to another shader from " + + std::to_string(bound_shader) + "(" + bound_shader_name + ") to " + + std::to_string(shader.getID()) + "(" + shader.name + ")" )); + } else if (bound_offset != offset) { + throw std::runtime_error("trying to bind VAO to another offset"); + } else if (bound_vertex_buffer != vertexBuffer) { + throw std::runtime_error("trying to bind VAO to another vertex buffer"); + } else if (bound_elements_buffer != elementsBuffer) { + throw std::runtime_error("trying to bind VAO to another elements buffer"); + } +} + +void VertexArrayObject::storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, + char *offset) { + bound_shader = shader.getID(); + bound_shader_name = shader.name; + bound_offset = offset; + bound_vertex_buffer = vertexBuffer; + bound_elements_buffer = elementsBuffer; +} + +#endif + +} diff --git a/src/geometry/vertex_buffer.cpp b/src/geometry/vertex_buffer.cpp deleted file mode 100644 index 56072e161d..0000000000 --- a/src/geometry/vertex_buffer.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include <mbgl/geometry/vertex_buffer.hpp> -#include <mbgl/platform/gl.hpp> - -using namespace mbgl; - - -VertexBuffer::VertexBuffer(std::initializer_list<int16_t> init) : array(init) {} - -VertexBuffer::~VertexBuffer() { - if (buffer != 0) { - glDeleteBuffers(1, &buffer); - } -} - -size_t VertexBuffer::index() const { - // We store 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes) - return array.size() / 2; -} - -void VertexBuffer::bind() { - if (buffer == 0) { - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(vertex_type), array.data(), GL_STATIC_DRAW); - } else { - glBindBuffer(GL_ARRAY_BUFFER, buffer); - } -} diff --git a/src/map/map.cpp b/src/map/map.cpp index 60ddaa5976..6aa9071a4f 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -532,17 +532,8 @@ void Map::prepare() { transform.updateTransitions(animationTime); } - const TransformState oldState = state; state = transform.currentState(); - bool pixelRatioChanged = oldState.getPixelRatio() != state.getPixelRatio(); - bool dimensionsChanged = oldState.getFramebufferWidth() != state.getFramebufferWidth() || - oldState.getFramebufferHeight() != state.getFramebufferHeight(); - - if (pixelRatioChanged || dimensionsChanged) { - painter.clearFramebuffers(); - } - animationTime = util::now(); updateSources(); style->updateProperties(state.getNormalizedZoom(), animationTime); @@ -558,9 +549,11 @@ void Map::render() { #if defined(DEBUG) std::vector<std::string> debug; #endif - painter.clear(); - painter.resetFramebuffer(); + glyphAtlas->upload(); + spriteAtlas->upload(); + + painter.clear(); painter.resize(); @@ -635,33 +628,7 @@ void Map::renderLayers(std::shared_ptr<StyleLayerGroup> group) { } void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass, const Tile::ID* id, const mat4* matrix) { - if (layer_desc->layers && layer_desc->type != StyleLayerType::Raster) { - // This is a layer group. We render them during our translucent render pass. - if (pass == RenderPass::Translucent) { - const CompositeProperties &properties = layer_desc->getProperties<CompositeProperties>(); - if (properties.isVisible()) { - gl::group group(std::string("group: ") + layer_desc->id); - - if (debug::renderTree) { - std::cout << std::string(indent++ * 4, ' ') << "+ " << layer_desc->id - << " (Composite) {" << std::endl; - } - - painter.pushFramebuffer(); - - renderLayers(layer_desc->layers); - - GLuint texture = painter.popFramebuffer(); - - // Render the previous texture onto the screen. - painter.drawComposite(texture, properties); - - if (debug::renderTree) { - std::cout << std::string(--indent * 4, ' ') << "}" << std::endl; - } - } - } - } else if (layer_desc->type == StyleLayerType::Background) { + if (layer_desc->type == StyleLayerType::Background) { // This layer defines the background color. } else { // This is a singular layer. diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp index 6069ad82cb..6923c1a422 100644 --- a/src/map/tile_parser.cpp +++ b/src/map/tile_parser.cpp @@ -13,6 +13,7 @@ #include <mbgl/util/token.hpp> #include <mbgl/geometry/glyph_atlas.hpp> #include <mbgl/text/glyph_store.hpp> +#include <mbgl/text/collision.hpp> #include <mbgl/text/glyph.hpp> #include <mbgl/map/map.hpp> @@ -29,7 +30,12 @@ namespace regex_impl = boost; namespace regex_impl = std; #endif -using namespace mbgl; +namespace mbgl { + +// Note: This destructor is seemingly empty, but we need to declare it anyway +// because this object has a std::unique_ptr<> of a forward-declare type in +// its header file. +TileParser::~TileParser() = default; TileParser::TileParser(const std::string &data, VectorTileData &tile, const std::shared_ptr<const Style> &style, @@ -44,7 +50,7 @@ TileParser::TileParser(const std::string &data, VectorTileData &tile, glyphStore(glyphStore), spriteAtlas(spriteAtlas), sprite(sprite), - collision(tile.id.z, 4096, tile.source.tile_size, tile.depth) { + collision(std::make_unique<Collision>(tile.id.z, 4096, tile.source.tile_size, tile.depth)) { } void TileParser::parse() { @@ -163,7 +169,9 @@ std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& laye } std::unique_ptr<Bucket> TileParser::createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol) { - std::unique_ptr<SymbolBucket> bucket = std::make_unique<SymbolBucket>(symbol, collision); + std::unique_ptr<SymbolBucket> bucket = std::make_unique<SymbolBucket>(symbol, *collision); bucket->addFeatures(layer, filter, tile.id, *spriteAtlas, *sprite, *glyphAtlas, *glyphStore); return obsolete() ? nullptr : std::move(bucket); } + +} diff --git a/src/map/transform.cpp b/src/map/transform.cpp index a68cffdc7e..6c5e70cc2f 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -128,9 +128,9 @@ void Transform::getLonLat(double &lon, double &lat) const { } void Transform::getLonLatZoom(double &lon, double &lat, double &zoom) const { - uv::readlock lock(mtx); - getLonLat(lon, lat); + + uv::readlock lock(mtx); zoom = getZoom(); } @@ -192,7 +192,7 @@ void Transform::setZoom(const double zoom, const timestamp duration) { double Transform::getZoom() const { uv::readlock lock(mtx); - return log(final.scale) / M_LN2; + return std::log(final.scale) / M_LN2; } double Transform::getScale() const { diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index 4b4000ce97..875cc279b9 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -216,7 +216,7 @@ void FillBucket::drawElements(PlainShader& 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); + group.array[0].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; @@ -227,7 +227,7 @@ 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); + group.array[1].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; @@ -238,7 +238,7 @@ void FillBucket::drawVertices(OutlineShader& shader) { char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); char *elements_index = BUFFER_OFFSET(line_elements_start * lineElementsBuffer.itemSize); for (line_group_type& group : lineGroups) { - group.array.bind(shader, vertexBuffer, lineElementsBuffer, vertex_index); + group.array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index); glDrawElements(GL_LINES, group.elements_length * 2, GL_UNSIGNED_SHORT, elements_index); vertex_index += group.vertex_length * vertexBuffer.itemSize; elements_index += group.elements_length * lineElementsBuffer.itemSize; diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index 949d71e134..e089d7f61b 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -367,7 +367,7 @@ void LineBucket::drawLines(LineShader& shader) { if (!group.elements_length) { continue; } - group.array.bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); + group.array[0].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; @@ -381,7 +381,7 @@ void LineBucket::drawPoints(LinejoinShader& shader) { if (!group.elements_length) { continue; } - group.array.bind(shader, vertexBuffer, pointElementsBuffer, vertex_index); + group.array[0].bind(shader, vertexBuffer, pointElementsBuffer, vertex_index); glDrawElements(GL_POINTS, group.elements_length, GL_UNSIGNED_SHORT, elements_index); vertex_index += group.vertex_length * vertexBuffer.itemSize; elements_index += group.elements_length * pointElementsBuffer.itemSize; diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 956543d26b..e813ad24eb 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -45,7 +45,6 @@ void Painter::setup() { assert(rasterShader); assert(textShader); assert(dotShader); - assert(compositeShader); assert(gaussianShader); @@ -67,21 +66,19 @@ void Painter::setup() { } void Painter::setupShaders() { - plainShader = std::make_unique<PlainShader>(); - outlineShader = std::make_unique<OutlineShader>(); - lineShader = std::make_unique<LineShader>(); - linejoinShader = std::make_unique<LinejoinShader>(); - patternShader = std::make_unique<PatternShader>(); - iconShader = std::make_unique<IconShader>(); - rasterShader = std::make_unique<RasterShader>(); - textShader = std::make_unique<TextShader>(); - dotShader = std::make_unique<DotShader>(); - compositeShader = std::make_unique<CompositeShader>(); - gaussianShader = std::make_unique<GaussianShader>(); + if (!plainShader) plainShader = std::make_unique<PlainShader>(); + if (!outlineShader) outlineShader = std::make_unique<OutlineShader>(); + if (!lineShader) lineShader = std::make_unique<LineShader>(); + if (!linejoinShader) linejoinShader = std::make_unique<LinejoinShader>(); + if (!patternShader) patternShader = std::make_unique<PatternShader>(); + if (!iconShader) iconShader = std::make_unique<IconShader>(); + if (!rasterShader) rasterShader = std::make_unique<RasterShader>(); + if (!textShader) textShader = std::make_unique<TextShader>(); + if (!dotShader) dotShader = std::make_unique<DotShader>(); + if (!gaussianShader) gaussianShader = std::make_unique<GaussianShader>(); } void Painter::cleanup() { - clearFramebuffers(); } void Painter::resize() { @@ -118,6 +115,14 @@ void Painter::depthMask(bool value) { } } +void Painter::depthRange(const float near, const float far) { + if (gl_depthRange[0] != near || gl_depthRange[1] != far) { + glDepthRange(near, far); + gl_depthRange = {{ near, far }}; + } +} + + void Painter::changeMatrix() { // Initialize projection matrix matrix::ortho(projMatrix, 0, map.getState().getWidth(), map.getState().getHeight(), 0, 0, 1); diff --git a/src/renderer/painter_clipping.cpp b/src/renderer/painter_clipping.cpp index 95e97eadc9..e94646d922 100644 --- a/src/renderer/painter_clipping.cpp +++ b/src/renderer/painter_clipping.cpp @@ -13,7 +13,7 @@ void Painter::drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &so glDisable(GL_DEPTH_TEST); depthMask(false); glColorMask(false, false, false, false); - glDepthRange(1.0f, 1.0f); + depthRange(1.0f, 1.0f); glStencilMask(0xFF); coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0)); diff --git a/src/renderer/painter_composite.cpp b/src/renderer/painter_composite.cpp deleted file mode 100644 index 42d0ad5592..0000000000 --- a/src/renderer/painter_composite.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include <mbgl/renderer/painter.hpp> -#include <mbgl/style/style_properties.hpp> - -#include <iostream> - -using namespace mbgl; - -void Painter::drawComposite(GLuint texture, const CompositeProperties &properties) { - // We're doing full-screen framebuffer blending, so no need to do stencil testing here. - glDisable(GL_STENCIL_TEST); - - useProgram(compositeShader->program); - compositeShader->setMatrix(nativeMatrix); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - compositeShader->setImage(0); - - // TODO: translate - compositeShader->setOpacity(properties.opacity); - - // Draw the full screen texture. - // TODO: Do more blend effects like multiply + blur - compositeArray.bind(*compositeShader, tileStencilBuffer, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); - - glBindTexture(GL_TEXTURE_2D, 0); - - // Reset back. - glEnable(GL_STENCIL_TEST); -} diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 8306dd0a2e..fe08d4c2fa 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -6,6 +6,7 @@ #include <mbgl/map/sprite.hpp> #include <mbgl/geometry/sprite_atlas.hpp> #include <mbgl/util/std.hpp> +#include <mbgl/util/mat3.hpp> using namespace mbgl; @@ -28,13 +29,10 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c stroke_color[3] *= properties.opacity; } - bool outline = properties.antialias && properties.stroke_color != properties.fill_color; - bool fringeline = properties.antialias && properties.stroke_color == properties.fill_color; - if (fringeline) { - outline = true; - stroke_color = fill_color; - } + const bool pattern = properties.image.size(); + bool outline = properties.antialias && !pattern && properties.stroke_color != properties.fill_color; + bool fringeline = properties.antialias && !pattern && properties.stroke_color == properties.fill_color; // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) @@ -50,68 +48,61 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c static_cast<float>(map.getState().getFramebufferWidth()), static_cast<float>(map.getState().getFramebufferHeight()) }}); - glDepthRange(strata, 1.0f); + depthRange(strata, 1.0f); bucket.drawVertices(*outlineShader); - } else if (fringeline) { - // // We're only drawing to the first seven bits (== support a maximum of - // // 127 overlapping polygons in one place before we get rendering errors). - // glStencilMask(0x3F); - // glClear(GL_STENCIL_BUFFER_BIT); - - // // Draw front facing triangles. Wherever the 0x80 bit is 1, we are - // // increasing the lower 7 bits by one if the triangle is a front-facing - // // triangle. This means that all visible polygons should be in CCW - // // orientation, while all holes (see below) are in CW orientation. - // glStencilFunc(GL_EQUAL, 0x80, 0x80); - - // // When we do a nonzero fill, we count the number of times a pixel is - // // covered by a counterclockwise polygon, and subtract the number of - // // times it is "uncovered" by a clockwise polygon. - // glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP); } - if ((fill_color[3] >= 1.0f) == (pass == RenderPass::Opaque)) { + if (pattern) { + // Image fill. Sprite &sprite = *map.getSprite(); - if (properties.image.size() && sprite) { + if (pass == RenderPass::Translucent && sprite) { SpriteAtlas &spriteAtlas = *map.getSpriteAtlas(); - Rect<uint16_t> imagePos = spriteAtlas.getImage(properties.image, sprite); - - - float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z); - float mix = std::fmod(map.getState().getZoom(), 1.0); - - std::array<float, 2> imageSize = {{ - imagePos.w * factor, - imagePos.h * factor - } - }; - - std::array<float, 2> offset = {{ - (float)std::fmod(id.x * 4096, imageSize[0]), - (float)std::fmod(id.y * 4096, imageSize[1]) - } - }; + const Rect<uint16_t> pos = spriteAtlas.getImage(properties.image, sprite); + + // `repeating` indicates that the image will be used in a repeating pattern + // repeating pattern images are assumed to have a 1px padding that mirrors the opposite edge + // positions for repeating images are adjusted to exclude the edge + const int repeating = 1; + const std::array<float, 2> size {{ + float(pos.w) / spriteAtlas.getPixelRatio(), + float(pos.h) / spriteAtlas.getPixelRatio(), + }}; + const std::array<float, 2> tl {{ + (float(pos.x + repeating) / spriteAtlas.getWidth()), + (float(pos.y + repeating) / spriteAtlas.getHeight()), + }}; + const std::array<float, 2> br {{ + (float(pos.x + pos.w - 2 * repeating) / spriteAtlas.getWidth()), + (float(pos.y + pos.h - 2 * repeating) / spriteAtlas.getHeight()), + }}; + const float mix = std::fmod(float(map.getState().getZoom()), 1.0f); + + const float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z); + + mat3 patternMatrix; + matrix::identity(patternMatrix); + matrix::scale(patternMatrix, patternMatrix, 1.0f / (size[0] * factor), 1.0f / (size[1] * factor)); useProgram(patternShader->program); patternShader->setMatrix(vtxMatrix); - patternShader->setOffset(offset); - patternShader->setPatternSize(imageSize); - patternShader->setPatternTopLeft({{ - float(imagePos.x) / spriteAtlas.getWidth(), - float(imagePos.y) / spriteAtlas.getHeight(), - }}); - patternShader->setPatternBottomRight({{ - float(imagePos.x + imagePos.w) / spriteAtlas.getWidth(), - float(imagePos.y + imagePos.h) / spriteAtlas.getHeight(), - }}); - patternShader->setColor(fill_color); + patternShader->setPatternTopLeft(tl); + patternShader->setPatternBottomRight(br); + patternShader->setOpacity(properties.opacity); + patternShader->setImage(0); patternShader->setMix(mix); + patternShader->setPatternMatrix(patternMatrix); + + glActiveTexture(GL_TEXTURE0); spriteAtlas.bind(true); // Draw the actual triangles into the color & stencil buffer. - glDepthRange(strata + strata_epsilon, 1.0f); + depthRange(strata, 1.0f); bucket.drawElements(*patternShader); - } else { + } + } + else { + // No image fill. + if ((fill_color[3] >= 1.0f) == (pass == RenderPass::Opaque)) { // Only draw the fill when it's either opaque and we're drawing opaque // fragments or when it's translucent and we're drawing translucent // fragments @@ -121,7 +112,7 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c plainShader->setColor(fill_color); // Draw the actual triangles into the color & stencil buffer. - glDepthRange(strata + strata_epsilon, 1.0f); + depthRange(strata + strata_epsilon, 1.0f); bucket.drawElements(*plainShader); } } @@ -141,7 +132,7 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c static_cast<float>(map.getState().getFramebufferHeight()) }}); - glDepthRange(strata + strata_epsilon, 1.0f); + depthRange(strata + strata_epsilon, 1.0f); bucket.drawVertices(*outlineShader); } } diff --git a/src/renderer/painter_framebuffers.cpp b/src/renderer/painter_framebuffers.cpp deleted file mode 100644 index f221b884ce..0000000000 --- a/src/renderer/painter_framebuffers.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include <mbgl/renderer/painter.hpp> -#include <mbgl/renderer/fill_bucket.hpp> -#include <mbgl/map/map.hpp> -#include <mbgl/map/view.hpp> -#include <mbgl/util/clip_ids.hpp> - -using namespace mbgl; - - -void Painter::clearFramebuffers() { - glBindFramebuffer(GL_FRAMEBUFFER, map.view.root_fbo()); - - // Delete any framebuffers that we might have allocated - glDeleteTextures((int)fbos_color.size(), fbos.data()); - fbos_color.clear(); - - if (fbo_depth_stencil != 0) { - glDeleteRenderbuffers(1, &fbo_depth_stencil); - fbo_depth_stencil = 0; - } - - glDeleteFramebuffers((int)fbos.size(), fbos.data()); - fbos.clear(); -} - -void Painter::bindFramebuffer() { - if (fbo_level < 0) { - glBindFramebuffer(GL_FRAMEBUFFER, map.view.root_fbo()); - } else if (fbos.size() > (size_t) fbo_level) { - GLuint fbo = fbos[fbo_level]; - glBindFramebuffer(GL_FRAMEBUFFER, fbo); -#if GL_EXT_discard_framebuffer - const GLenum discards[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; - glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards); -#endif - } else { - // TODO: Convert this to textures so we can composite them and use them in blend operations - - GLuint fbo_color; - glGenTextures(1, &fbo_color); - glBindTexture(GL_TEXTURE_2D, fbo_color); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, map.getState().getFramebufferWidth(), map.getState().getFramebufferHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, 0); - fbos_color.emplace_back(fbo_color); - - // Use a shared depth/stencil buffer for all framebuffer objects - if (fbo_depth_stencil == 0) { - // Create depth/stencil buffer - glGenRenderbuffers(1, &fbo_depth_stencil); - glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_stencil); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, map.getState().getFramebufferWidth(), map.getState().getFramebufferHeight()); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - } - - // Allocate new framebuffer - GLuint fbo = 0; - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - fbos.emplace_back(fbo); - - // Assemble the FBO - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_color, 0); -#ifdef GL_ES_VERSION_2_0 - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth_stencil); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo_depth_stencil); -#else - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo_depth_stencil); -#endif - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - fprintf(stderr, "Couldn't create framebuffer: "); - switch (status) { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: fprintf(stderr, "incomplete attachment\n"); break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: fprintf(stderr, "incomplete missing attachment\n"); break; -#ifdef GL_ES_VERSION_2_0 - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: fprintf(stderr, "incomplete dimensions\n"); break; -#else - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: fprintf(stderr, "incomplete draw buffer\n"); break; -#endif - case GL_FRAMEBUFFER_UNSUPPORTED: fprintf(stderr, "unsupported\n"); break; - default: fprintf(stderr, "other\n"); break; - } - return; - } - } -} - -void Painter::resetFramebuffer() { - if (fbo_level >= 0) { - fbo_level = -1; - bindFramebuffer(); - } - - fbo_depth_stencil_valid = false; -} - -void Painter::pushFramebuffer() { - fbo_level++; - bindFramebuffer(); - - if (fbo_depth_stencil_valid) { - glClear(GL_COLOR_BUFFER_BIT); - } else { - depthMask(true); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glColorMask(false, false, false, false); - - drawClippingMasks(map.getActiveSources()); - - glColorMask(true, true, true, true); - fbo_depth_stencil_valid = true; - } -} - -GLuint Painter::popFramebuffer() { - GLuint texture = fbos_color[fbo_level]; - fbo_level--; - bindFramebuffer(); - return texture; -} diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 375b99297d..24358c51dd 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -33,7 +33,7 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d const mat4 &vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor); - glDepthRange(strata, 1.0f); + depthRange(strata, 1.0f); // We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway. if (bucket.hasPoints() && outset > 1.0f) { diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp index 1a54336923..14a15effe1 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -28,7 +28,7 @@ void Painter::renderPrerenderedTexture(RasterBucket &bucket, const mat4 &matrix, rasterShader->setMatrix(matrix); rasterShader->setOpacity(1); - glDepthRange(strata, 1.0f); + depthRange(strata, 1.0f); glActiveTexture(GL_TEXTURE0); rasterShader->setImage(0); diff --git a/src/renderer/painter_raster.cpp b/src/renderer/painter_raster.cpp index b67b4b553f..946f6216c7 100644 --- a/src/renderer/painter_raster.cpp +++ b/src/renderer/painter_raster.cpp @@ -71,7 +71,7 @@ void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> lay rasterShader->setContrast(properties.contrast); rasterShader->setSpin(spinWeights(properties.hue_rotate)); - glDepthRange(strata + strata_epsilon, 1.0f); + depthRange(strata + strata_epsilon, 1.0f); bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray); diff --git a/src/renderer/painter_symbol.cpp b/src/renderer/painter_symbol.cpp index 720f84d24e..66961b3183 100644 --- a/src/renderer/painter_symbol.cpp +++ b/src/renderer/painter_symbol.cpp @@ -18,6 +18,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> lay const SymbolProperties &properties = layer_desc->getProperties<SymbolProperties>(); + glDisable(GL_STENCIL_TEST); if (bucket.hasTextData()) { mat4 exMatrix; @@ -143,7 +144,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> lay textShader->setColor(properties.text.halo_color); } textShader->setBuffer(haloWidth); - glDepthRange(strata, 1.0f); + depthRange(strata, 1.0f); bucket.drawGlyphs(*textShader); } @@ -161,7 +162,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> lay textShader->setColor(properties.text.color); } textShader->setBuffer((256.0f - 64.0f) / 256.0f); - glDepthRange(strata + strata_epsilon, 1.0f); + depthRange(strata + strata_epsilon, 1.0f); bucket.drawGlyphs(*textShader); } } @@ -210,8 +211,10 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> lay iconShader->setFadeZoom(map.getState().getNormalizedZoom() * 10); iconShader->setOpacity(properties.icon.opacity); - glDepthRange(strata, 1.0f); + depthRange(strata, 1.0f); bucket.drawIcons(*iconShader); } + + glEnable(GL_STENCIL_TEST); } } diff --git a/src/renderer/raster_bucket.cpp b/src/renderer/raster_bucket.cpp index ddfff119e0..10dadc03fc 100644 --- a/src/renderer/raster_bucket.cpp +++ b/src/renderer/raster_bucket.cpp @@ -17,14 +17,14 @@ bool RasterBucket::setImage(const std::string &data) { return raster.load(data); } -void RasterBucket::drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array) { +void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array) { raster.bind(true); shader.setImage(0); array.bind(shader, vertices, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index()); } -void RasterBucket::drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array, GLuint texture) { +void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, GLuint texture) { raster.bind(texture); shader.setImage(0); array.bind(shader, vertices, BUFFER_OFFSET(0)); diff --git a/src/renderer/symbol_bucket.cpp b/src/renderer/symbol_bucket.cpp index 459c235da7..30110faf02 100644 --- a/src/renderer/symbol_bucket.cpp +++ b/src/renderer/symbol_bucket.cpp @@ -212,6 +212,7 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping const float iconBoxScale = collision.tilePixelRatio * properties.icon.max_size; const bool iconWithoutText = properties.text.optional || !shaping.size(); const bool textWithoutIcon = properties.icon.optional || !image; + const bool avoidEdges = properties.avoid_edges && properties.placement != PlacementType::Line; Anchors anchors; @@ -239,6 +240,9 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping Placement iconPlacement; float glyphScale = 0; float iconScale = 0; + const bool inside = !(anchor.x < 0 || anchor.x > 4096 || anchor.y < 0 || anchor.y > 4096); + + if (avoidEdges && !inside) continue; if (shaping.size()) { glyphPlacement = Placement::getGlyphs(anchor, origin, shaping, face, textBoxScale, @@ -246,7 +250,7 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping glyphScale = properties.text.allow_overlap ? glyphPlacement.minScale - : collision.getPlacementScale(glyphPlacement.boxes, glyphPlacement.minScale); + : collision.getPlacementScale(glyphPlacement.boxes, glyphPlacement.minScale, avoidEdges); if (!glyphScale && !iconWithoutText) continue; } @@ -256,7 +260,7 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping iconScale = properties.icon.allow_overlap ? iconPlacement.minScale - : collision.getPlacementScale(iconPlacement.boxes, iconPlacement.minScale); + : collision.getPlacementScale(iconPlacement.boxes, iconPlacement.minScale, avoidEdges); if (!iconScale && !textWithoutIcon) continue; } @@ -297,14 +301,14 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping collision.insert(glyphPlacement.boxes, anchor, glyphScale, glyphRange, horizontalText); } - addSymbols(text, glyphPlacement.shapes, glyphScale, glyphRange); + if (inside) addSymbols(text, glyphPlacement.shapes, glyphScale, glyphRange); } if (iconScale) { if (!properties.icon.ignore_placement) { collision.insert(iconPlacement.boxes, anchor, iconScale, iconRange, horizontalIcon); } - addSymbols(icon, iconPlacement.shapes, iconScale, iconRange); + if (inside) addSymbols(icon, iconPlacement.shapes, iconScale, iconRange); } } } @@ -348,7 +352,7 @@ void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float // We're generating triangle fans, so we always start with the first // coordinate in this polygon. - ElementGroup &triangleGroup = buffer.groups.back(); + TextElementGroup &triangleGroup = buffer.groups.back(); uint32_t triangleIndex = triangleGroup.vertex_length; // coordinates (2 triangles) @@ -373,8 +377,8 @@ void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float void SymbolBucket::drawGlyphs(TextShader &shader) { char *vertex_index = BUFFER_OFFSET(0); char *elements_index = BUFFER_OFFSET(0); - for (ElementGroup &group : text.groups) { - group.array.bind(shader, text.vertices, text.triangles, vertex_index); + for (TextElementGroup &group : text.groups) { + group.array[0].bind(shader, text.vertices, text.triangles, vertex_index); glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index); vertex_index += group.vertex_length * text.vertices.itemSize; elements_index += group.elements_length * text.triangles.itemSize; @@ -384,8 +388,8 @@ void SymbolBucket::drawGlyphs(TextShader &shader) { void SymbolBucket::drawIcons(IconShader &shader) { char *vertex_index = BUFFER_OFFSET(0); char *elements_index = BUFFER_OFFSET(0); - for (ElementGroup &group : icon.groups) { - group.array.bind(shader, icon.vertices, icon.triangles, vertex_index); + for (IconElementGroup &group : icon.groups) { + group.array[0].bind(shader, icon.vertices, icon.triangles, vertex_index); glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index); vertex_index += group.vertex_length * icon.vertices.itemSize; elements_index += group.elements_length * icon.triangles.itemSize; diff --git a/src/shader/composite.fragment.glsl b/src/shader/composite.fragment.glsl deleted file mode 100644 index d5adc402e6..0000000000 --- a/src/shader/composite.fragment.glsl +++ /dev/null @@ -1,9 +0,0 @@ -uniform sampler2D u_image; -uniform float u_opacity; - -varying vec2 v_pos; - -void main() { - vec4 color = texture2D(u_image, v_pos); - gl_FragColor = color * u_opacity; -} diff --git a/src/shader/composite.vertex.glsl b/src/shader/composite.vertex.glsl deleted file mode 100644 index d7e8f0a8af..0000000000 --- a/src/shader/composite.vertex.glsl +++ /dev/null @@ -1,9 +0,0 @@ -attribute vec2 a_pos; - -uniform mat4 u_matrix; -varying vec2 v_pos; - -void main() { - gl_Position = u_matrix * vec4(a_pos, 0, 1); - v_pos = (gl_Position.xy + 1.0) / 2.0; -} diff --git a/src/shader/composite_shader.cpp b/src/shader/composite_shader.cpp deleted file mode 100644 index 07fe0c0740..0000000000 --- a/src/shader/composite_shader.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include <mbgl/shader/composite_shader.hpp> -#include <mbgl/shader/shaders.hpp> -#include <mbgl/platform/gl.hpp> - -#include <cstdio> - -using namespace mbgl; - -CompositeShader::CompositeShader() - : Shader( - shaders[COMPOSITE_SHADER].vertex, - shaders[COMPOSITE_SHADER].fragment - ) { - if (!valid) { - fprintf(stderr, "invalid composite shader\n"); - return; - } - - a_pos = glGetAttribLocation(program, "a_pos"); - - u_matrix = glGetUniformLocation(program, "u_matrix"); - u_image = glGetUniformLocation(program, "u_image"); - u_opacity = glGetUniformLocation(program, "u_opacity"); - - // fprintf(stderr, "CompositeShader:\n"); - // fprintf(stderr, " - u_matrix: %d\n", u_matrix); - // fprintf(stderr, " - u_image: %d\n", u_image); - // fprintf(stderr, " - u_opacity: %f\n", u_opacity); -} - -void CompositeShader::bind(char *offset) { - glEnableVertexAttribArray(a_pos); - glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); -} - -void CompositeShader::setImage(int32_t new_image) { - if (image != new_image) { - glUniform1i(u_image, new_image); - image = new_image; - } -} - -void CompositeShader::setOpacity(float new_opacity) { - if (opacity != new_opacity) { - glUniform1f(u_opacity, new_opacity); - opacity = new_opacity; - } -} diff --git a/src/shader/dot_shader.cpp b/src/shader/dot_shader.cpp index 8e2837f2cc..54163d6982 100644 --- a/src/shader/dot_shader.cpp +++ b/src/shader/dot_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; DotShader::DotShader() : Shader( + "dot", shaders[DOT_SHADER].vertex, shaders[DOT_SHADER].fragment ) { diff --git a/src/shader/gaussian_shader.cpp b/src/shader/gaussian_shader.cpp index eb88677565..d22006020c 100644 --- a/src/shader/gaussian_shader.cpp +++ b/src/shader/gaussian_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; GaussianShader::GaussianShader() : Shader( + "gaussian", shaders[GAUSSIAN_SHADER].vertex, shaders[GAUSSIAN_SHADER].fragment ) { diff --git a/src/shader/icon_shader.cpp b/src/shader/icon_shader.cpp index 6455d870a2..4973dc4119 100644 --- a/src/shader/icon_shader.cpp +++ b/src/shader/icon_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; IconShader::IconShader() : Shader( + "icon", shaders[ICON_SHADER].vertex, shaders[ICON_SHADER].fragment ) { diff --git a/src/shader/line_shader.cpp b/src/shader/line_shader.cpp index 529ab0d316..1b0527366e 100644 --- a/src/shader/line_shader.cpp +++ b/src/shader/line_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; LineShader::LineShader() : Shader( + "line", shaders[LINE_SHADER].vertex, shaders[LINE_SHADER].fragment ) { diff --git a/src/shader/linejoin_shader.cpp b/src/shader/linejoin_shader.cpp index 73b7a1e745..e8ec306ed9 100644 --- a/src/shader/linejoin_shader.cpp +++ b/src/shader/linejoin_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; LinejoinShader::LinejoinShader() : Shader( + "linejoin", shaders[LINEJOIN_SHADER].vertex, shaders[LINEJOIN_SHADER].fragment ) { diff --git a/src/shader/outline_shader.cpp b/src/shader/outline_shader.cpp index b1e57bf0f3..d9c19fa805 100644 --- a/src/shader/outline_shader.cpp +++ b/src/shader/outline_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; OutlineShader::OutlineShader() : Shader( + "outline", shaders[OUTLINE_SHADER].vertex, shaders[OUTLINE_SHADER].fragment ) { diff --git a/src/shader/pattern.fragment.glsl b/src/shader/pattern.fragment.glsl index 850c7afaff..ba6aed3023 100644 --- a/src/shader/pattern.fragment.glsl +++ b/src/shader/pattern.fragment.glsl @@ -1,19 +1,15 @@ -uniform vec4 u_color; - -uniform vec2 u_offset; -uniform vec2 u_pattern_size; +uniform float u_opacity; uniform vec2 u_pattern_tl; uniform vec2 u_pattern_br; uniform float u_mix; - uniform sampler2D u_image; varying vec2 v_pos; void main() { - vec2 imagecoord = mod((v_pos + u_offset) / u_pattern_size, 1.0); + vec2 imagecoord = mod(v_pos, 1.0); vec2 pos = mix(u_pattern_tl, u_pattern_br, imagecoord); vec4 color1 = texture2D(u_image, pos); @@ -21,6 +17,5 @@ void main() { vec2 pos2 = mix(u_pattern_tl, u_pattern_br, imagecoord2); vec4 color2 = texture2D(u_image, pos2); - vec4 color = mix(color1, color2, u_mix); - gl_FragColor = color + u_color * (1.0 - color.a); + gl_FragColor = mix(color1, color2, u_mix) * u_opacity; } diff --git a/src/shader/pattern.vertex.glsl b/src/shader/pattern.vertex.glsl index eeee39930f..f2de884ead 100644 --- a/src/shader/pattern.vertex.glsl +++ b/src/shader/pattern.vertex.glsl @@ -1,10 +1,11 @@ uniform mat4 u_matrix; +uniform mat3 u_patternmatrix; attribute vec2 a_pos; varying vec2 v_pos; void main() { - v_pos = a_pos; gl_Position = u_matrix * vec4(a_pos, 0, 1); + v_pos = (u_patternmatrix * vec3(a_pos, 1)).xy; } diff --git a/src/shader/pattern_shader.cpp b/src/shader/pattern_shader.cpp index f3943b964e..8fe6a34e93 100644 --- a/src/shader/pattern_shader.cpp +++ b/src/shader/pattern_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; PatternShader::PatternShader() : Shader( + "pattern", shaders[PATTERN_SHADER].vertex, shaders[PATTERN_SHADER].fragment ) { @@ -19,21 +20,21 @@ PatternShader::PatternShader() a_pos = glGetAttribLocation(program, "a_pos"); u_matrix = glGetUniformLocation(program, "u_matrix"); - u_color = glGetUniformLocation(program, "u_color"); - u_offset = glGetUniformLocation(program, "u_offset"); - u_pattern_size = glGetUniformLocation(program, "u_pattern_size"); u_pattern_tl = glGetUniformLocation(program, "u_pattern_tl"); u_pattern_br = glGetUniformLocation(program, "u_pattern_br"); + u_opacity = glGetUniformLocation(program, "u_opacity"); + u_image = glGetUniformLocation(program, "u_image"); u_mix = glGetUniformLocation(program, "u_mix"); + u_patternmatrix = glGetUniformLocation(program, "u_patternmatrix"); // fprintf(stderr, "PatternShader:\n"); // fprintf(stderr, " - u_matrix: %d\n", u_matrix); - // fprintf(stderr, " - u_color: %d\n", u_color); - // fprintf(stderr, " - u_offset: %d\n", u_offset); - // fprintf(stderr, " - u_pattern_size: %d\n", u_pattern_size); // fprintf(stderr, " - u_pattern_tl: %d\n", u_pattern_tl); // fprintf(stderr, " - u_pattern_br: %d\n", u_pattern_br); + // fprintf(stderr, " - u_opacity: %d\n", u_opacity); + // fprintf(stderr, " - u_image: %d\n", u_image); // fprintf(stderr, " - u_mix: %d\n", u_mix); + // fprintf(stderr, " - u_patternmatrix: %d\n", u_patternmatrix); } void PatternShader::bind(char *offset) { @@ -41,27 +42,6 @@ void PatternShader::bind(char *offset) { glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset); } -void PatternShader::setColor(const std::array<float, 4>& new_color) { - if (color != new_color) { - glUniform4fv(u_color, 1, new_color.data()); - color = new_color; - } -} - -void PatternShader::setOffset(const std::array<float, 2>& new_offset) { - if (offset != new_offset) { - glUniform2fv(u_offset, 1, new_offset.data()); - offset = new_offset; - } -} - -void PatternShader::setPatternSize(const std::array<float, 2>& new_pattern_size) { - if (pattern_size != new_pattern_size) { - glUniform2fv(u_pattern_size, 1, new_pattern_size.data()); - pattern_size = new_pattern_size; - } -} - void PatternShader::setPatternTopLeft(const std::array<float, 2>& new_pattern_tl) { if (pattern_tl != new_pattern_tl) { glUniform2fv(u_pattern_tl, 1, new_pattern_tl.data()); @@ -76,6 +56,20 @@ void PatternShader::setPatternBottomRight(const std::array<float, 2>& new_patter } } +void PatternShader::setOpacity(float new_opacity) { + if (opacity != new_opacity) { + glUniform1f(u_opacity, new_opacity); + opacity = new_opacity; + } +} + +void PatternShader::setImage(int new_image) { + if (image != new_image) { + glUniform1i(u_image, new_image); + image = new_image; + } +} + void PatternShader::setMix(float new_mix) { if (mix != new_mix) { glUniform1f(u_mix, new_mix); @@ -83,3 +77,10 @@ void PatternShader::setMix(float new_mix) { } } +void PatternShader::setPatternMatrix(const std::array<float, 9>& new_patternmatrix) { + if (patternmatrix != new_patternmatrix) { + glUniformMatrix3fv(u_patternmatrix, 1, GL_FALSE, new_patternmatrix.data()); + patternmatrix = new_patternmatrix; + } +} + diff --git a/src/shader/plain_shader.cpp b/src/shader/plain_shader.cpp index 3abc57eaa4..bb0c228992 100644 --- a/src/shader/plain_shader.cpp +++ b/src/shader/plain_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; PlainShader::PlainShader() : Shader( + "plain", shaders[PLAIN_SHADER].vertex, shaders[PLAIN_SHADER].fragment ) { diff --git a/src/shader/raster_shader.cpp b/src/shader/raster_shader.cpp index 51b328fa8f..60d81c61bd 100644 --- a/src/shader/raster_shader.cpp +++ b/src/shader/raster_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; RasterShader::RasterShader() : Shader( + "raster", shaders[RASTER_SHADER].vertex, shaders[RASTER_SHADER].fragment ) { diff --git a/src/shader/shader.cpp b/src/shader/shader.cpp index fa073c42d0..171ce9b7c1 100644 --- a/src/shader/shader.cpp +++ b/src/shader/shader.cpp @@ -8,8 +8,9 @@ using namespace mbgl; -Shader::Shader(const GLchar *vertSource, const GLchar *fragSource) - : valid(false), +Shader::Shader(const char *name, const GLchar *vertSource, const GLchar *fragSource) + : name(name), + valid(false), program(0) { util::timer timer("shader compilation", Event::Shader); diff --git a/src/shader/text_shader.cpp b/src/shader/text_shader.cpp index c9e70825ce..f6de934e2f 100644 --- a/src/shader/text_shader.cpp +++ b/src/shader/text_shader.cpp @@ -8,6 +8,7 @@ using namespace mbgl; TextShader::TextShader() : Shader( + "text", shaders[TEXT_SHADER].vertex, shaders[TEXT_SHADER].fragment ) { diff --git a/src/style/property_fallback.cpp b/src/style/property_fallback.cpp index 4028980cbe..0f8335dd66 100644 --- a/src/style/property_fallback.cpp +++ b/src/style/property_fallback.cpp @@ -44,8 +44,6 @@ const std::map<PropertyKey, PropertyValue> PropertyFallbackValue::properties = { { PropertyKey::TextTranslateY, defaultStyleProperties<SymbolProperties>().text.translate[1] }, { PropertyKey::TextTranslateAnchor, defaultStyleProperties<SymbolProperties>().text.translate_anchor }, - { PropertyKey::CompositeOpacity, defaultStyleProperties<CompositeProperties>().opacity }, - { PropertyKey::RasterOpacity, defaultStyleProperties<RasterProperties>().opacity }, { PropertyKey::RasterHueRotate, defaultStyleProperties<RasterProperties>().hue_rotate }, { PropertyKey::RasterBrightnessLow, defaultStyleProperties<RasterProperties>().brightness[0] }, diff --git a/src/style/style_layer.cpp b/src/style/style_layer.cpp index 520c183780..4994cf3efa 100644 --- a/src/style/style_layer.cpp +++ b/src/style/style_layer.cpp @@ -105,7 +105,7 @@ struct PropertyEvaluator { } T operator()(const Function<T> &value) const { - return util::apply_visitor(FunctionEvaluator<T>(z), value); + return mapbox::util::apply_visitor(FunctionEvaluator<T>(z), value); } template <typename P, typename std::enable_if<!std::is_convertible<P, T>::value, int>::type = 0> @@ -146,11 +146,11 @@ void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, c for (AppliedClassProperty &property : applied.properties) { if (now >= property.end) { // We overwrite the current property with the new value. - target = util::apply_visitor(evaluator, property.value); + target = mapbox::util::apply_visitor(evaluator, property.value); } else if (now >= property.begin) { // We overwrite the current property partially with the new value. float progress = float(now - property.begin) / float(property.end - property.begin); - target = interpolate(target, util::apply_visitor(evaluator, property.value), progress); + target = interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress); } else { // Do not apply this property because its transition hasn't begun yet. } @@ -217,13 +217,6 @@ void StyleLayer::applyStyleProperties<SymbolProperties>(const float z, const tim } template <> -void StyleLayer::applyStyleProperties<CompositeProperties>(const float z, const timestamp now) { - properties.set<CompositeProperties>(); - CompositeProperties &composite = properties.get<CompositeProperties>(); - applyStyleProperty(PropertyKey::CompositeOpacity, composite.opacity, z, now); -} - -template <> void StyleLayer::applyStyleProperties<RasterProperties>(const float z, const timestamp now) { properties.set<RasterProperties>(); RasterProperties &raster = properties.get<RasterProperties>(); @@ -255,7 +248,6 @@ void StyleLayer::updateProperties(float z, const timestamp now) { case StyleLayerType::Line: applyStyleProperties<LineProperties>(z, now); break; case StyleLayerType::Symbol: applyStyleProperties<SymbolProperties>(z, now); break; case StyleLayerType::Raster: applyStyleProperties<RasterProperties>(z, now); break; - case StyleLayerType::Composite: applyStyleProperties<CompositeProperties>(z, now); break; case StyleLayerType::Background: applyStyleProperties<BackgroundProperties>(z, now); break; default: properties.set<std::false_type>(); break; } diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 43790e21b3..c2689162e2 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -465,6 +465,7 @@ std::unique_ptr<StyleLayerGroup> StyleParser::createLayers(JSVal value) { return group; } else { Log::Warning(Event::ParseStyle, "layers must be an array"); + return nullptr; } } @@ -628,9 +629,6 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) { parseOptionalProperty<Function<float>>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value); parseOptionalProperty<PropertyTransition>("transition-text-translate", Key::TextTranslate, klass, value); - parseOptionalProperty<Function<float>>("composite-opacity", Key::CompositeOpacity, klass, value); - parseOptionalProperty<PropertyTransition>("transition-composite-opacity", Key::CompositeOpacity, klass, value); - parseOptionalProperty<Function<float>>("raster-opacity", Key::RasterOpacity, klass, value); parseOptionalProperty<PropertyTransition>("transition-raster-opacity", Key::RasterOpacity, klass, value); parseOptionalProperty<Function<float>>("raster-hue-rotate", Key::RasterHueRotate, klass, value); @@ -862,6 +860,7 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer) { } parseRenderProperty(value, render.min_distance, "symbol-min-distance"); + parseRenderProperty(value, render.avoid_edges, "symbol-avoid-edges"); parseRenderProperty(value, render.icon.allow_overlap, "icon-allow-overlap"); parseRenderProperty(value, render.icon.ignore_placement, "icon-ignore-placement"); diff --git a/src/style/style_properties.cpp b/src/style/style_properties.cpp index 1b05528d2f..29730fb85b 100644 --- a/src/style/style_properties.cpp +++ b/src/style/style_properties.cpp @@ -5,7 +5,6 @@ namespace mbgl { template<> const FillProperties &defaultStyleProperties() { static const FillProperties p; return p; } template<> const LineProperties &defaultStyleProperties() { static const LineProperties p; return p; } template<> const SymbolProperties &defaultStyleProperties() { static const SymbolProperties p; return p; } -template<> const CompositeProperties &defaultStyleProperties() { static const CompositeProperties p; return p; } template<> const RasterProperties &defaultStyleProperties() { static const RasterProperties p; return p; } template<> const BackgroundProperties &defaultStyleProperties() { static const BackgroundProperties p; return p; } diff --git a/src/text/collision.cpp b/src/text/collision.cpp index 4621423569..89e91d6844 100644 --- a/src/text/collision.cpp +++ b/src/text/collision.cpp @@ -2,41 +2,26 @@ #include <mbgl/text/rotation_range.hpp> #include <mbgl/util/math.hpp> -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#ifndef __clang__ -#pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif -#include <boost/geometry.hpp> -#include <boost/geometry/geometries/point.hpp> -#include <boost/geometry/geometries/box.hpp> -#include <boost/geometry/index/rtree.hpp> -#pragma GCC diagnostic pop - -namespace mbgl { -namespace bg = boost::geometry; -namespace bgm = bg::model; -namespace bgi = bg::index; -typedef bgm::point<float, 2, bg::cs::cartesian> Point; -typedef bgm::box<Point> Box; -typedef std::pair<Box, PlacementBox> PlacementValue; -typedef bgi::rtree<PlacementValue, bgi::rstar<16>> Tree; -} using namespace mbgl; -Collision::~Collision() { - delete ((Tree *)cTree); - delete ((Tree *)hTree); -} +Box getBox(const CollisionAnchor &anchor, const CollisionRect &bbox, float minScale, + float maxScale) { + return Box{ + Point{ + anchor.x + util::min(bbox.tl.x / minScale, bbox.tl.x / maxScale), + anchor.y + util::min(bbox.tl.y / minScale, bbox.tl.y / maxScale), + }, + Point{ + anchor.x + util::max(bbox.br.x / minScale, bbox.br.x / maxScale), + anchor.y + util::max(bbox.br.y / minScale, bbox.br.y / maxScale), + }, + }; +}; Collision::Collision(float zoom, float tileExtent, float tileSize, float placementDepth) - : hTree(new Tree()), // tree for horizontal labels - cTree(new Tree()), // tree for glyphs from curved labels - // tile pixels per screen pixels at the tile's zoom level - tilePixelRatio(tileExtent / tileSize), + : tilePixelRatio(tileExtent / tileSize), zoom(zoom), @@ -52,32 +37,51 @@ Collision::Collision(float zoom, float tileExtent, float tileSize, float placeme const float m = 4096; const float edge = m * tilePixelRatio * 2; - // Hack to prevent cross-tile labels - insert( - /* glyphs */ { - GlyphBox{/* box */ CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{0, edge}}, - /* minScale */ 0, - /* padding */ 2}, - GlyphBox{/* box */ CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{edge, 0}}, - /* minScale */ 0, - /* padding */ 2}}, - /* anchor */ CollisionAnchor(0, 0), - /* placementScale */ 1, - /* placementRange */ {{M_PI * 2, 0}}, - /* horizontal */ false); - - insert( - /* glyphs */ { - GlyphBox{/* box*/ CollisionRect{CollisionPoint{-edge, 0}, CollisionPoint{edge, edge}}, - /* minScale */ 0, - /* padding */ 2}, - GlyphBox{/* box */ CollisionRect{CollisionPoint{0, -edge}, CollisionPoint{edge, edge}}, - /* minScale */ 0, - /* padding */ 2}}, - /* anchor */ CollisionAnchor(m, m), - /* placementScale */ 1, - /* placementRange */ {{M_PI * 2, 0}}, - /* horizontal */ false); + + PlacementBox left; + left.anchor = CollisionAnchor{ 0.0f, 0.0f }; + left.box = CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{0, edge}}; + left.placementRange = {{ 2.0f * M_PI, 0.0f }}; + left.placementScale = 0.5f; + left.maxScale = std::numeric_limits<float>::infinity(); + left.padding = 0.0f; + leftEdge = PlacementValue{ + getBox(left.anchor, left.box, left.placementScale, left.maxScale), + left}; + + PlacementBox top; + top.anchor = CollisionAnchor{ 0.0f, 0.0f }; + top.box = CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{edge, 0}}; + top.placementRange = {{ 2.0f * M_PI, 0.0f }}; + top.placementScale = 0.5f; + top.maxScale = std::numeric_limits<float>::infinity(); + top.padding = 0.0f; + topEdge = PlacementValue{ + getBox(top.anchor, top.box, top.placementScale, top.maxScale), + top}; + + PlacementBox bottom; + bottom.anchor = CollisionAnchor{ m, m }; + bottom.box = CollisionRect{CollisionPoint{-edge, 0}, CollisionPoint{edge, edge}}; + bottom.placementRange = {{ 2.0f * M_PI, 0.0f }}; + bottom.placementScale = 0.5f; + bottom.maxScale = std::numeric_limits<float>::infinity(); + bottom.padding = 0.0f; + bottomEdge = PlacementValue{ + getBox(bottom.anchor, bottom.box, bottom.placementScale, bottom.maxScale), + bottom}; + + PlacementBox right; + right.anchor = CollisionAnchor{ m, m }; + right.box = CollisionRect{CollisionPoint{0, -edge}, CollisionPoint{edge, edge}}; + right.placementRange = {{ 2.0f * M_PI, 0.0f }}; + right.placementScale = 0.5f; + right.maxScale = std::numeric_limits<float>::infinity(); + right.padding = 0.0f; + rightEdge = PlacementValue{ + getBox(right.anchor, right.box, right.placementScale, right.maxScale), + right}; + } GlyphBox getMergedGlyphs(const GlyphBoxes &boxes, const CollisionAnchor &anchor) { @@ -99,21 +103,7 @@ GlyphBox getMergedGlyphs(const GlyphBoxes &boxes, const CollisionAnchor &anchor) return mergedGlyphs; } -Box getBox(const CollisionAnchor &anchor, const CollisionRect &bbox, float minScale, - float maxScale) { - return Box{ - Point{ - anchor.x + util::min(bbox.tl.x / minScale, bbox.tl.x / maxScale), - anchor.y + util::min(bbox.tl.y / minScale, bbox.tl.y / maxScale), - }, - Point{ - anchor.x + util::max(bbox.br.x / minScale, bbox.br.x / maxScale), - anchor.y + util::max(bbox.br.y / minScale, bbox.br.y / maxScale), - }, - }; -}; - -float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale) { +float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale, bool avoidEdges) { for (const GlyphBox &glyph : glyphs) { const CollisionRect &box = glyph.box; @@ -121,6 +111,7 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementS const CollisionAnchor &anchor = glyph.anchor; const float pad = glyph.padding; + if (anchor.x < 0 || anchor.x > 4096 || anchor.y < 0 || anchor.y > 4096) { return 0; } @@ -136,8 +127,15 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementS const Box searchBox = getBox(anchor, bbox, minScale, maxScale); std::vector<PlacementValue> blocking; - ((Tree *)hTree)->query(bgi::intersects(searchBox), std::back_inserter(blocking)); - ((Tree *)cTree)->query(bgi::intersects(searchBox), std::back_inserter(blocking)); + hTree.query(bgi::intersects(searchBox), std::back_inserter(blocking)); + cTree.query(bgi::intersects(searchBox), std::back_inserter(blocking)); + + if (avoidEdges) { + if (searchBox.min_corner().get<0>() < 0) blocking.emplace_back(leftEdge); + if (searchBox.min_corner().get<1>() < 0) blocking.emplace_back(topEdge); + if (searchBox.max_corner().get<0>() >= 4096) blocking.emplace_back(rightEdge); + if (searchBox.max_corner().get<1>() >= 4096) blocking.emplace_back(bottomEdge); + } if (blocking.size()) { const CollisionAnchor &na = anchor; // new anchor @@ -212,10 +210,10 @@ PlacementRange Collision::getPlacementRange(const GlyphBoxes &glyphs, float plac Box query_box{Point{minPlacedX, minPlacedY}, Point{maxPlacedX, maxPlacedY}}; std::vector<PlacementValue> blocking; - ((Tree *)hTree)->query(bgi::intersects(query_box), std::back_inserter(blocking)); + hTree.query(bgi::intersects(query_box), std::back_inserter(blocking)); if (horizontal) { - ((Tree *)cTree)->query(bgi::intersects(query_box), std::back_inserter(blocking)); + cTree.query(bgi::intersects(query_box), std::back_inserter(blocking)); } for (const PlacementValue &value : blocking) { @@ -292,8 +290,8 @@ void Collision::insert(const GlyphBoxes &glyphs, const CollisionAnchor &anchor, // Bulk-insert all glyph boxes if (horizontal) { - ((Tree *)hTree)->insert(allBounds.begin(), allBounds.end()); + hTree.insert(allBounds.begin(), allBounds.end()); } else { - ((Tree *)cTree)->insert(allBounds.begin(), allBounds.end()); + cTree.insert(allBounds.begin(), allBounds.end()); } } diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp index c32e1642e5..09f2fbc7b3 100644 --- a/src/text/glyph_store.cpp +++ b/src/text/glyph_store.cpp @@ -132,7 +132,7 @@ void FontStack::lineWrap(Shaping &shaping, const float lineHeight, const float m maxLineLength = maxLineLength || shaping.back().x; - justifyLine(shaping, metrics, lineStartIndex, shaping.size() - 1, justify); + justifyLine(shaping, metrics, lineStartIndex, uint32_t(shaping.size()) - 1, justify); align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line); } diff --git a/src/util/filesource.cpp b/src/util/filesource.cpp index 2bbf146b0c..503d4dfb1d 100644 --- a/src/util/filesource.cpp +++ b/src/util/filesource.cpp @@ -17,7 +17,7 @@ const std::string &FileSource::getBase() const { return base; } -void FileSource::load(ResourceType type, const std::string &url, std::function<void(platform::Response *)> callback, const std::shared_ptr<uv::loop> loop) { +void FileSource::load(ResourceType /*type*/, const std::string &url, std::function<void(platform::Response *)> callback, const std::shared_ptr<uv::loop> loop) { // convert relative URLs to absolute URLs const std::string absoluteURL = [&]() -> std::string { diff --git a/src/util/mat3.cpp b/src/util/mat3.cpp new file mode 100644 index 0000000000..38858d2385 --- /dev/null +++ b/src/util/mat3.cpp @@ -0,0 +1,51 @@ +// This is an incomplete port of http://glmatrix.net/ +// +// Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the +// use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not claim +// that you wrote the original software. If you use this software in a +// product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. + +#include <mbgl/util/mat3.hpp> + +#include <cmath> + +using namespace mbgl; + +void matrix::identity(mat3& out) { + out[0] = 1.0f; + out[1] = 0.0f; + out[2] = 0.0f; + out[3] = 0.0f; + out[4] = 1.0f; + out[5] = 0.0f; + out[6] = 0.0f; + out[7] = 0.0f; + out[8] = 1.0f; +} + +void matrix::scale(mat3& out, const mat3& a, const float x, const float y) { + out[0] = x * a[0]; + out[1] = x * a[1]; + out[2] = x * a[2]; + out[3] = y * a[3]; + out[4] = y * a[4]; + out[5] = y * a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; +} diff --git a/styles/bright/style.json b/styles/bright/style.json index 1ee81a499b..d132efe982 100644 --- a/styles/bright/style.json +++ b/styles/bright/style.json @@ -11,6 +11,7 @@ "@land": "#f8f4f0", "@water": "#a0c8f0", "@admin": "#446", + "@admin-opacity": 0.5, "@park": "#d8e8c8", "@cemetary": "#e0e4dd", "@hospital": "#fde", @@ -688,97 +689,95 @@ "line-width": "@rail_hatch_width" } }, { - "id": "admin", - "type": "composite", - "style": { - "composite-opacity": 0.5 - }, - "layers": [{ - "id": "admin_level_3", - "source": "mapbox", - "source-layer": "admin", - "filter": { - "admin_level": {">=": 3}, - "maritime": 0 - }, - "render": { - "line-join": "round" - }, - "style": { - "line-color": "@admin", - "line-dasharray": [10, 3], - "line-width": "@admin_level_3_width" - }, - "type": "line" - }, { - "id": "admin_level_2", - "source": "mapbox", - "source-layer": "admin", - "filter": { - "admin_level": 2, - "disputed": 0, - "maritime": 0 - }, - "render": { - "line-cap": "round" - }, - "style": { - "line-color": "@admin", - "line-width": "@admin_level_2_width" - }, - "type": "line" - }, { - "id": "admin_level_2_disputed", - "source": "mapbox", - "source-layer": "admin", - "filter": { - "admin_level": 2, - "disputed": 1, - "maritime": 0 - }, - "render": { - "line-cap": "round" - }, - "style": { - "line-color": "@admin", - "line-dasharray": [4, 4], - "line-width": "@admin_level_2_width" - }, - "type": "line" - }, { - "id": "admin_level_3_maritime", - "source": "mapbox", - "source-layer": "admin", - "filter": { - "admin_level": {">=": 3}, - "maritime": 1 - }, - "render": { - "line-join": "round" - }, - "style": { - "line-color": "@water", - "line-dasharray": [10, 3], - "line-width": "@admin_level_3_width" - }, - "type": "line" - }, { - "id": "admin_level_2_maritime", - "source": "mapbox", - "source-layer": "admin", - "filter": { - "admin_level": 2, - "maritime": 1 - }, - "render": { - "line-cap": "round" - }, - "style": { - "line-color": "@water", - "line-width": "@admin_level_2_width" - }, - "type": "line" - }] + "id": "admin_level_3", + "source": "mapbox", + "source-layer": "admin", + "filter": { + "admin_level": {">=": 3}, + "maritime": 0 + }, + "render": { + "line-join": "round" + }, + "style": { + "line-color": "@admin", + "line-opacity": "@admin-opacity", + "line-dasharray": [10, 3], + "line-width": "@admin_level_3_width" + }, + "type": "line" + }, { + "id": "admin_level_2", + "source": "mapbox", + "source-layer": "admin", + "filter": { + "admin_level": 2, + "disputed": 0, + "maritime": 0 + }, + "render": { + "line-cap": "round" + }, + "style": { + "line-color": "@admin", + "line-opacity": "@admin-opacity", + "line-width": "@admin_level_2_width" + }, + "type": "line" + }, { + "id": "admin_level_2_disputed", + "source": "mapbox", + "source-layer": "admin", + "filter": { + "admin_level": 2, + "disputed": 1, + "maritime": 0 + }, + "render": { + "line-cap": "round" + }, + "style": { + "line-color": "@admin", + "line-opacity": "@admin-opacity", + "line-dasharray": [4, 4], + "line-width": "@admin_level_2_width" + }, + "type": "line" + }, { + "id": "admin_level_3_maritime", + "source": "mapbox", + "source-layer": "admin", + "filter": { + "admin_level": {">=": 3}, + "maritime": 1 + }, + "render": { + "line-join": "round" + }, + "style": { + "line-color": "@water", + "line-opacity": "@admin-opacity", + "line-dasharray": [10, 3], + "line-width": "@admin_level_3_width" + }, + "type": "line" + }, { + "id": "admin_level_2_maritime", + "source": "mapbox", + "source-layer": "admin", + "filter": { + "admin_level": 2, + "maritime": 1 + }, + "render": { + "line-cap": "round" + }, + "style": { + "line-color": "@water", + "line-opacity": "@admin-opacity", + "line-width": "@admin_level_2_width" + }, + "type": "line" }, { "id": "country_label_line", "source": "mapbox", @@ -1333,4 +1332,4 @@ }, "type": "symbol" }] -}
\ No newline at end of file +} diff --git a/test/enums.cpp b/test/enums.cpp index f909631e3e..dce20ca592 100644 --- a/test/enums.cpp +++ b/test/enums.cpp @@ -15,7 +15,6 @@ TEST(Enums, StyleLayerType) { ASSERT_EQ(StyleLayerType::Line, StyleLayerTypeClass("line")); ASSERT_EQ(StyleLayerType::Symbol, StyleLayerTypeClass("symbol")); ASSERT_EQ(StyleLayerType::Raster, StyleLayerTypeClass("raster")); - ASSERT_EQ(StyleLayerType::Composite, StyleLayerTypeClass("composite")); ASSERT_EQ(StyleLayerType::Background, StyleLayerTypeClass("background")); ASSERT_EQ(StyleLayerType::Unknown, StyleLayerTypeClass(StyleLayerType::Unknown)); @@ -23,7 +22,6 @@ TEST(Enums, StyleLayerType) { ASSERT_EQ(StyleLayerType::Line, StyleLayerTypeClass(StyleLayerType::Line)); ASSERT_EQ(StyleLayerType::Symbol, StyleLayerTypeClass(StyleLayerType::Symbol)); ASSERT_EQ(StyleLayerType::Raster, StyleLayerTypeClass(StyleLayerType::Raster)); - ASSERT_EQ(StyleLayerType::Composite, StyleLayerTypeClass(StyleLayerType::Composite)); ASSERT_EQ(StyleLayerType::Background, StyleLayerTypeClass(StyleLayerType::Background)); ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Unknown), StyleLayerTypeClass(StyleLayerType::Unknown)); @@ -31,7 +29,6 @@ TEST(Enums, StyleLayerType) { ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Line), StyleLayerTypeClass(StyleLayerType::Line)); ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Symbol), StyleLayerTypeClass(StyleLayerType::Symbol)); ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Raster), StyleLayerTypeClass(StyleLayerType::Raster)); - ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Composite), StyleLayerTypeClass(StyleLayerType::Composite)); ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Background), StyleLayerTypeClass(StyleLayerType::Background)); ASSERT_EQ(false, StyleLayerTypeClass("").valid()); diff --git a/test/style_parser.cpp b/test/style_parser.cpp index 53113ad53e..d530fe1f8b 100644 --- a/test/style_parser.cpp +++ b/test/style_parser.cpp @@ -75,7 +75,7 @@ TEST_P(StyleParserTest, ParseStyle) { std::cerr << "Unchecked Log Messages (" << base << "/" << name << "): " << std::endl << unchecked; } - ASSERT_EQ(0, unchecked.size()); + ASSERT_EQ(0ul, unchecked.size()); } } |