Merge branch 'master' into libuv010
This commit is contained in:
13
.travis.yml
13
.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:
|
||||
|
||||
4
Makefile
4
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
|
||||
|
||||
20
README.md
20
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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
const SDFGlyph& glyph);
|
||||
void removeGlyphs(uint64_t tile_id);
|
||||
void bind();
|
||||
void upload();
|
||||
|
||||
public:
|
||||
const uint16_t width = 0;
|
||||
|
||||
@@ -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();
|
||||
|
||||
26
include/mbgl/geometry/static_vertex_buffer.hpp
Normal file
26
include/mbgl/geometry/static_vertex_buffer.hpp
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -27,7 +27,7 @@ private:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using Function = util::variant<
|
||||
using Function = mapbox::util::variant<
|
||||
std::false_type,
|
||||
ConstantFunction<T>,
|
||||
StopsFunction<T>
|
||||
|
||||
@@ -51,8 +51,6 @@ enum class PropertyKey {
|
||||
TextTranslateY,
|
||||
TextTranslateAnchor,
|
||||
|
||||
CompositeOpacity,
|
||||
|
||||
RasterOpacity,
|
||||
RasterHueRotate,
|
||||
RasterBrightness, // for transitions only
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
typedef util::variant<
|
||||
typedef mapbox::util::variant<
|
||||
std::string,
|
||||
TranslateAnchorType,
|
||||
RotateAnchorType,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" },
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
40
include/mbgl/util/mat3.hpp
Normal file
40
include/mbgl/util/mat3.hpp
Normal file
@@ -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
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
template <typename T>
|
||||
class recursive_wrapper
|
||||
|
||||
@@ -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);
|
||||
|
||||
Submodule ios/mapbox-gl-cocoa updated: 9d4320aefa...e1c709a8de
0
scripts/flags.sh
Normal file → Executable file
0
scripts/flags.sh
Normal file → Executable file
@@ -1,10 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
cd build/Testing
|
||||
|
||||
for TEST in ./test_* ; do
|
||||
${TEST}
|
||||
done
|
||||
@@ -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
|
||||
8
scripts/travis_install.sh
Executable file
8
scripts/travis_install.sh
Executable file
@@ -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
|
||||
30
scripts/travis_script.sh
Executable file
30
scripts/travis_script.sh
Executable file
@@ -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
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
14
src/geometry/static_vertex_buffer.cpp
Normal file
14
src/geometry/static_vertex_buffer.cpp
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
46
src/geometry/vao.cpp
Normal file
46
src/geometry/vao.cpp
Normal file
@@ -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
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
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<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])
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
DotShader::DotShader()
|
||||
: Shader(
|
||||
"dot",
|
||||
shaders[DOT_SHADER].vertex,
|
||||
shaders[DOT_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
GaussianShader::GaussianShader()
|
||||
: Shader(
|
||||
"gaussian",
|
||||
shaders[GAUSSIAN_SHADER].vertex,
|
||||
shaders[GAUSSIAN_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
IconShader::IconShader()
|
||||
: Shader(
|
||||
"icon",
|
||||
shaders[ICON_SHADER].vertex,
|
||||
shaders[ICON_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
LineShader::LineShader()
|
||||
: Shader(
|
||||
"line",
|
||||
shaders[LINE_SHADER].vertex,
|
||||
shaders[LINE_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
LinejoinShader::LinejoinShader()
|
||||
: Shader(
|
||||
"linejoin",
|
||||
shaders[LINEJOIN_SHADER].vertex,
|
||||
shaders[LINEJOIN_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
OutlineShader::OutlineShader()
|
||||
: Shader(
|
||||
"outline",
|
||||
shaders[OUTLINE_SHADER].vertex,
|
||||
shaders[OUTLINE_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
PlainShader::PlainShader()
|
||||
: Shader(
|
||||
"plain",
|
||||
shaders[PLAIN_SHADER].vertex,
|
||||
shaders[PLAIN_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
RasterShader::RasterShader()
|
||||
: Shader(
|
||||
"raster",
|
||||
shaders[RASTER_SHADER].vertex,
|
||||
shaders[RASTER_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using namespace mbgl;
|
||||
|
||||
TextShader::TextShader()
|
||||
: Shader(
|
||||
"text",
|
||||
shaders[TEXT_SHADER].vertex,
|
||||
shaders[TEXT_SHADER].fragment
|
||||
) {
|
||||
|
||||
@@ -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] },
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
@@ -216,13 +216,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>();
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
51
src/util/mat3.cpp
Normal file
51
src/util/mat3.cpp
Normal file
@@ -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];
|
||||
}
|
||||
@@ -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
|
||||
"id": "admin_level_3",
|
||||
"source": "mapbox",
|
||||
"source-layer": "admin",
|
||||
"filter": {
|
||||
"admin_level": {">=": 3},
|
||||
"maritime": 0
|
||||
},
|
||||
"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"
|
||||
}]
|
||||
"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"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user