diff --git a/.travis.yml b/.travis.yml
index eb4e700b1..b641c1158 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 #%{build_number}: %{author} tested %{commit} in branch %{branch} of %{repository_name}: %{commit_message}
%{message} (%{duration}) - Compare: 1 2 3 4'
+ - 'Build #%{build_number}: %{author} tested %{commit} in branch %{branch} of %{repository_name}: %{commit_message}
%{message} (%{duration})'
format: html
git:
diff --git a/Makefile b/Makefile
index efc2385ce..fe44e914d 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/README.md b/README.md
index 9a67c51b5..64ffe2514 100644
--- a/README.md
+++ b/README.md
@@ -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 6a7d75d75..3fb090f2b 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 20489cb33..446177d44 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 ed60338e0..1282beb23 100644
--- a/include/mbgl/geometry/elements_buffer.hpp
+++ b/include/mbgl/geometry/elements_buffer.hpp
@@ -4,10 +4,13 @@
#include
#include
+#include
+
namespace mbgl {
+template
struct ElementGroup {
- VertexArrayObject array;
+ std::array 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 e05cbe3b9..07011d324 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 dc2378c2f..c30499a53 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 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 000000000..ce932269f
--- /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
+
+#include
+#include
+#include
+#include
+
+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> init);
+};
+
+}
+
+#endif
diff --git a/include/mbgl/geometry/vao.hpp b/include/mbgl/geometry/vao.hpp
index 71d7ff89f..87408ddba 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
#include
#include
namespace mbgl {
+#if GL_ARB_vertex_array_object
class VertexArrayObject {
public:
template
- 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
- 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
+ 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 58fd4a9d0..000000000
--- a/include/mbgl/geometry/vertex_buffer.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef MBGL_GEOMETRY_VERTEX_BUFFER
-#define MBGL_GEOMETRY_VERTEX_BUFFER
-
-#include
-#include
-#include
-#include
-
-namespace mbgl {
-
-class VertexBuffer {
-public:
- typedef int16_t vertex_type;
- VertexBuffer(std::initializer_list 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 array;
- uint32_t buffer = 0;
-};
-
-}
-
-#endif
diff --git a/include/mbgl/map/tile_parser.hpp b/include/mbgl/map/tile_parser.hpp
index f011d47a3..fa64dad6d 100644
--- a/include/mbgl/map/tile_parser.hpp
+++ b/include/mbgl/map/tile_parser.hpp
@@ -4,7 +4,6 @@
#include
#include
#include
-#include
#include
#include
@@ -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,
const std::shared_ptr &spriteAtlas,
const std::shared_ptr &sprite);
+ ~TileParser();
public:
void parse();
@@ -65,7 +66,7 @@ private:
std::shared_ptr sprite;
std::shared_ptr texturePool;
- Collision collision;
+ std::unique_ptr collision;
};
}
diff --git a/include/mbgl/platform/gl.hpp b/include/mbgl/platform/gl.hpp
index a29b230db..cc2a681d4 100644
--- a/include/mbgl/platform/gl.hpp
+++ b/include/mbgl/platform/gl.hpp
@@ -26,9 +26,12 @@
#elif TARGET_OS_MAC
#include
#include
- #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 e9340cce6..e8d6bf99e 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 f65ca3560..a33dde34e 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 26e1bd395..eb5f42789 100644
--- a/include/mbgl/renderer/painter.hpp
+++ b/include/mbgl/renderer/painter.hpp
@@ -3,7 +3,7 @@
#include
#include
-#include
+#include
#include
#include
#include
@@ -18,7 +18,6 @@
#include
#include
#include
-#include
#include
#include
@@ -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> &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 gl_viewport = {{ 0, 0 }};
+ std::array 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;
std::unique_ptr textShader;
std::unique_ptr dotShader;
- std::unique_ptr compositeShader;
std::unique_ptr 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 a68475565..66cceac8e 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 e89027423..fb1678fc8 100644
--- a/include/mbgl/renderer/symbol_bucket.hpp
+++ b/include/mbgl/renderer/symbol_bucket.hpp
@@ -50,6 +50,9 @@ typedef std::vector 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 groups;
+ std::vector groups;
} text;
struct {
IconVertexBuffer vertices;
TriangleElementsBuffer triangles;
- std::vector groups;
+ std::vector groups;
} icon;
};
diff --git a/include/mbgl/shader/composite_shader.hpp b/include/mbgl/shader/composite_shader.hpp
deleted file mode 100644
index c0c1704f3..000000000
--- a/include/mbgl/shader/composite_shader.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef MBGL_SHADER_COMPOSITE_SHADER
-#define MBGL_SHADER_COMPOSITE_SHADER
-
-#include
-
-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 b1b49b54d..e574b755d 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& color);
- void setOffset(const std::array& offset);
- void setPatternSize(const std::array& pattern_size);
void setPatternTopLeft(const std::array& pattern_tl);
void setPatternBottomRight(const std::array& pattern_br);
+ void setOpacity(float opacity);
+ void setImage(int image);
void setMix(float mix);
+ void setPatternMatrix(const std::array &patternmatrix);
private:
int32_t a_pos = -1;
- std::array color = {{}};
- int32_t u_color = -1;
-
- std::array offset = {{}};
- int32_t u_offset = -1;
-
- std::array pattern_size = {{}};
- int32_t u_pattern_size = -1;
-
std::array pattern_tl = {{}};
int32_t u_pattern_tl = -1;
std::array 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 patternmatrix = {{}};
+ int32_t u_patternmatrix = -1;
};
}
diff --git a/include/mbgl/shader/shader.hpp b/include/mbgl/shader/shader.hpp
index 2398cb12e..fa2d5a0a8 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& 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 2a6a2927e..2a9657879 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 Wrapper;
+ typedef mapbox::util::recursive_wrapper Wrapper;
enum class Operator : uint8_t {
And,
diff --git a/include/mbgl/style/function_properties.hpp b/include/mbgl/style/function_properties.hpp
index 8cd7ce6e2..56092f9a6 100644
--- a/include/mbgl/style/function_properties.hpp
+++ b/include/mbgl/style/function_properties.hpp
@@ -27,7 +27,7 @@ private:
};
template
-using Function = util::variant<
+using Function = mapbox::util::variant<
std::false_type,
ConstantFunction,
StopsFunction
diff --git a/include/mbgl/style/property_key.hpp b/include/mbgl/style/property_key.hpp
index aee5db038..ec68ea991 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 4d148dc02..1b22b3117 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 11b87d849..67c314205 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 StyleBucketRender;
+typedef mapbox::util::variant StyleBucketRender;
class StyleBucket {
diff --git a/include/mbgl/style/style_properties.hpp b/include/mbgl/style/style_properties.hpp
index f12ab430e..bbe8812bc 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 55b7685fd..fa21f819a 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 5e6260e5a..b981f1db9 100644
--- a/include/mbgl/style/value.hpp
+++ b/include/mbgl/style/value.hpp
@@ -9,7 +9,7 @@
namespace mbgl {
-typedef util::variant Value;
+typedef mapbox::util::variant Value;
std::string toString(const Value &value);
diff --git a/include/mbgl/text/collision.hpp b/include/mbgl/text/collision.hpp
index 87ebdb279..7e65e979d 100644
--- a/include/mbgl/text/collision.hpp
+++ b/include/mbgl/text/collision.hpp
@@ -3,23 +3,47 @@
#include
+#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
+#include
+#include
+#include
+#pragma GCC diagnostic pop
+
namespace mbgl {
+namespace bg = boost::geometry;
+namespace bgm = bg::model;
+namespace bgi = bg::index;
+typedef bgm::point Point;
+typedef bgm::box Box;
+typedef std::pair PlacementValue;
+typedef bgi::rtree> 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 000000000..d44b1435d
--- /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
+
+namespace mbgl {
+
+typedef std::array 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 a616805c0..54b27634a 100644
--- a/include/mbgl/util/recursive_wrapper.hpp
+++ b/include/mbgl/util/recursive_wrapper.hpp
@@ -3,7 +3,7 @@
#include
-namespace mbgl { namespace util {
+namespace mapbox { namespace util {
template
class recursive_wrapper
diff --git a/include/mbgl/util/variant.hpp b/include/mbgl/util/variant.hpp
index ddc82ee31..1eca5160c 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
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 ::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
+ResultType & get(T & var)
+{
+ return var.template get();
+}
+
+template
+ResultType const& get(T const& var)
+{
+ return var.template get();
+}
+
// operator<<
-template
+template
VARIANT_INLINE std::basic_ostream&
-operator<< (std::basic_ostream& out, Variant const& rhs)
+operator<< (std::basic_ostream& out, variant const& rhs)
{
detail::printer> visitor(out);
apply_visitor(visitor, rhs);
diff --git a/ios/mapbox-gl-cocoa b/ios/mapbox-gl-cocoa
index 9d4320aef..e1c709a8d 160000
--- a/ios/mapbox-gl-cocoa
+++ b/ios/mapbox-gl-cocoa
@@ -1 +1 @@
-Subproject commit 9d4320aefaa3868ecd5d0a4e0ce902b0adef78c1
+Subproject commit e1c709a8de0b69aa6bfbcd9ea4faf981b6e799b2
diff --git a/scripts/flags.sh b/scripts/flags.sh
old mode 100644
new mode 100755
diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh
deleted file mode 100755
index 716594824..000000000
--- 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
similarity index 60%
rename from scripts/setup_travis.sh
rename to scripts/travis_before_install.sh
index 128f6bbf7..e9b3384de 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 000000000..eca24e719
--- /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 000000000..61c2e5205
--- /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 c8a9bc1c2..e1ad79daf 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
-if [ ! -d 'mapnik-packaging/.git' ]; then
- git clone --depth=1 https://github.com/mapnik/mapnik-packaging.git
+NODE=$(which node)
+NPM=$(which npm)
+
+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 76df941d9..9e74e21b2 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 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 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 71d3cbee9..730551dbe 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 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 lock(mtx);
diff --git a/src/geometry/static_vertex_buffer.cpp b/src/geometry/static_vertex_buffer.cpp
new file mode 100644
index 000000000..c86211c50
--- /dev/null
+++ b/src/geometry/static_vertex_buffer.cpp
@@ -0,0 +1,14 @@
+#include
+#include
+
+namespace mbgl {
+
+StaticVertexBuffer::StaticVertexBuffer(std::initializer_list> init) {
+ for (const std::pair &vertex : init) {
+ vertex_type *vertices = static_cast(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 000000000..4c459c436
--- /dev/null
+++ b/src/geometry/vao.cpp
@@ -0,0 +1,46 @@
+#include
+
+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 56072e161..000000000
--- a/src/geometry/vertex_buffer.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include
-#include
-
-using namespace mbgl;
-
-
-VertexBuffer::VertexBuffer(std::initializer_list 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 60ddaa597..6aa9071a4 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 debug;
#endif
- painter.clear();
- painter.resetFramebuffer();
+ glyphAtlas->upload();
+ spriteAtlas->upload();
+
+ painter.clear();
painter.resize();
@@ -635,33 +628,7 @@ void Map::renderLayers(std::shared_ptr group) {
}
void Map::renderLayer(std::shared_ptr 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();
- 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 6069ad82c..6923c1a42 100644
--- a/src/map/tile_parser.cpp
+++ b/src/map/tile_parser.cpp
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
@@ -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 &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(tile.id.z, 4096, tile.source.tile_size, tile.depth)) {
}
void TileParser::parse() {
@@ -163,7 +169,9 @@ std::unique_ptr TileParser::createLineBucket(const VectorTileLayer& laye
}
std::unique_ptr TileParser::createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol) {
- std::unique_ptr bucket = std::make_unique(symbol, collision);
+ std::unique_ptr bucket = std::make_unique(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 a68cffdc7..6c5e70cc2 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 4b4000ce9..875cc279b 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 949d71e13..e089d7f61 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 956543d26..e813ad24e 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();
- outlineShader = std::make_unique();
- lineShader = std::make_unique();
- linejoinShader = std::make_unique();
- patternShader = std::make_unique();
- iconShader = std::make_unique();
- rasterShader = std::make_unique();
- textShader = std::make_unique();
- dotShader = std::make_unique();
- compositeShader = std::make_unique();
- gaussianShader = std::make_unique();
+ if (!plainShader) plainShader = std::make_unique();
+ if (!outlineShader) outlineShader = std::make_unique();
+ if (!lineShader) lineShader = std::make_unique();
+ if (!linejoinShader) linejoinShader = std::make_unique();
+ if (!patternShader) patternShader = std::make_unique();
+ if (!iconShader) iconShader = std::make_unique();
+ if (!rasterShader) rasterShader = std::make_unique();
+ if (!textShader) textShader = std::make_unique();
+ if (!dotShader) dotShader = std::make_unique();
+ if (!gaussianShader) gaussianShader = std::make_unique();
}
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 95e97eadc..e94646d92 100644
--- a/src/renderer/painter_clipping.cpp
+++ b/src/renderer/painter_clipping.cpp
@@ -13,7 +13,7 @@ void Painter::drawClippingMasks(const std::set> &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 42d0ad559..000000000
--- a/src/renderer/painter_composite.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include
-#include
-
-#include
-
-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 8306dd0a2..fe08d4c2f 100644
--- a/src/renderer/painter_fill.cpp
+++ b/src/renderer/painter_fill.cpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
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(map.getState().getFramebufferWidth()),
static_cast(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 imagePos = spriteAtlas.getImage(properties.image, sprite);
+ const Rect 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 size {{
+ float(pos.w) / spriteAtlas.getPixelRatio(),
+ float(pos.h) / spriteAtlas.getPixelRatio(),
+ }};
+ const std::array tl {{
+ (float(pos.x + repeating) / spriteAtlas.getWidth()),
+ (float(pos.y + repeating) / spriteAtlas.getHeight()),
+ }};
+ const std::array 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);
- float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z);
- float mix = std::fmod(map.getState().getZoom(), 1.0);
+ const float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z);
- std::array imageSize = {{
- imagePos.w * factor,
- imagePos.h * factor
- }
- };
-
- std::array offset = {{
- (float)std::fmod(id.x * 4096, imageSize[0]),
- (float)std::fmod(id.y * 4096, imageSize[1])
- }
- };
+ 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(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 f221b884c..000000000
--- a/src/renderer/painter_framebuffers.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-
-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 375b99297..24358c51d 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 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 1a5433692..14a15effe 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 b67b4b553..946f6216c 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 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 720f84d24..66961b318 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 lay
const SymbolProperties &properties = layer_desc->getProperties();
+ glDisable(GL_STENCIL_TEST);
if (bucket.hasTextData()) {
mat4 exMatrix;
@@ -143,7 +144,7 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr 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 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 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 ddfff119e..10dadc03f 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 459c235da..30110faf0 100644
--- a/src/renderer/symbol_bucket.cpp
+++ b/src/renderer/symbol_bucket.cpp
@@ -212,6 +212,7 @@ void SymbolBucket::addFeature(const std::vector &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 &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 &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 &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 &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 d5adc402e..000000000
--- 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 d7e8f0a8a..000000000
--- 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 07fe0c074..000000000
--- a/src/shader/composite_shader.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include
-#include
-#include
-
-#include
-
-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 8e2837f2c..54163d698 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 eb8867756..d22006020 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 6455d870a..4973dc411 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 529ab0d31..1b0527366 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 73b7a1e74..e8ec306ed 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 b1e57bf0f..d9c19fa80 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 850c7afaf..ba6aed302 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 eeee39930..f2de884ea 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 f3943b964..8fe6a34e9 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& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void PatternShader::setOffset(const std::array& new_offset) {
- if (offset != new_offset) {
- glUniform2fv(u_offset, 1, new_offset.data());
- offset = new_offset;
- }
-}
-
-void PatternShader::setPatternSize(const std::array& 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& 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& 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& 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 3abc57eaa..bb0c22899 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 51b328fa8..60d81c61b 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 fa073c42d..171ce9b7c 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 c9e70825c..f6de934e2 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 4028980cb..0f8335dd6 100644
--- a/src/style/property_fallback.cpp
+++ b/src/style/property_fallback.cpp
@@ -44,8 +44,6 @@ const std::map PropertyFallbackValue::properties = {
{ PropertyKey::TextTranslateY, defaultStyleProperties().text.translate[1] },
{ PropertyKey::TextTranslateAnchor, defaultStyleProperties().text.translate_anchor },
- { PropertyKey::CompositeOpacity, defaultStyleProperties().opacity },
-
{ PropertyKey::RasterOpacity, defaultStyleProperties().opacity },
{ PropertyKey::RasterHueRotate, defaultStyleProperties().hue_rotate },
{ PropertyKey::RasterBrightnessLow, defaultStyleProperties().brightness[0] },
diff --git a/src/style/style_layer.cpp b/src/style/style_layer.cpp
index 520c18378..4994cf3ef 100644
--- a/src/style/style_layer.cpp
+++ b/src/style/style_layer.cpp
@@ -105,7 +105,7 @@ struct PropertyEvaluator {
}
T operator()(const Function &value) const {
- return util::apply_visitor(FunctionEvaluator(z), value);
+ return mapbox::util::apply_visitor(FunctionEvaluator(z), value);
}
template ::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.
}
@@ -216,13 +216,6 @@ void StyleLayer::applyStyleProperties(const float z, const tim
}
-template <>
-void StyleLayer::applyStyleProperties(const float z, const timestamp now) {
- properties.set();
- CompositeProperties &composite = properties.get();
- applyStyleProperty(PropertyKey::CompositeOpacity, composite.opacity, z, now);
-}
-
template <>
void StyleLayer::applyStyleProperties(const float z, const timestamp now) {
properties.set();
@@ -255,7 +248,6 @@ void StyleLayer::updateProperties(float z, const timestamp now) {
case StyleLayerType::Line: applyStyleProperties(z, now); break;
case StyleLayerType::Symbol: applyStyleProperties(z, now); break;
case StyleLayerType::Raster: applyStyleProperties(z, now); break;
- case StyleLayerType::Composite: applyStyleProperties(z, now); break;
case StyleLayerType::Background: applyStyleProperties(z, now); break;
default: properties.set(); break;
}
diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp
index 43790e21b..c2689162e 100644
--- a/src/style/style_parser.cpp
+++ b/src/style/style_parser.cpp
@@ -465,6 +465,7 @@ std::unique_ptr 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>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value);
parseOptionalProperty("transition-text-translate", Key::TextTranslate, klass, value);
- parseOptionalProperty>("composite-opacity", Key::CompositeOpacity, klass, value);
- parseOptionalProperty("transition-composite-opacity", Key::CompositeOpacity, klass, value);
-
parseOptionalProperty>("raster-opacity", Key::RasterOpacity, klass, value);
parseOptionalProperty("transition-raster-opacity", Key::RasterOpacity, klass, value);
parseOptionalProperty>("raster-hue-rotate", Key::RasterHueRotate, klass, value);
@@ -862,6 +860,7 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr &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 1b05528d2..29730fb85 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 462142356..89e91d684 100644
--- a/src/text/collision.cpp
+++ b/src/text/collision.cpp
@@ -2,41 +2,26 @@
#include
#include
-#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
-#include
-#include
-#include
-#pragma GCC diagnostic pop
-
-namespace mbgl {
-namespace bg = boost::geometry;
-namespace bgm = bg::model;
-namespace bgi = bg::index;
-typedef bgm::point Point;
-typedef bgm::box Box;
-typedef std::pair PlacementValue;
-typedef bgi::rtree> 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::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::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