Merge branch 'master' into libuv010

This commit is contained in:
Mike Morris
2014-08-19 14:16:01 -04:00
88 changed files with 832 additions and 886 deletions

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -32,6 +32,7 @@ public:
const SDFGlyph& glyph);
void removeGlyphs(uint64_t tile_id);
void bind();
void upload();
public:
const uint16_t width = 0;

View File

@@ -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();

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};
}

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
};
}

View File

@@ -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);

View File

@@ -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,

View File

@@ -27,7 +27,7 @@ private:
};
template <typename T>
using Function = util::variant<
using Function = mapbox::util::variant<
std::false_type,
ConstantFunction<T>,
StopsFunction<T>

View File

@@ -51,8 +51,6 @@ enum class PropertyKey {
TextTranslateY,
TextTranslateAnchor,
CompositeOpacity,
RasterOpacity,
RasterHueRotate,
RasterBrightness, // for transitions only

View File

@@ -7,7 +7,7 @@
namespace mbgl {
typedef util::variant<
typedef mapbox::util::variant<
std::string,
TranslateAnchorType,
RotateAnchorType,

View File

@@ -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 {

View File

@@ -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

View File

@@ -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" },
});

View File

@@ -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);

View File

@@ -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;

View 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

View File

@@ -3,7 +3,7 @@
#include <utility>
namespace mbgl { namespace util {
namespace mapbox { namespace util {
template <typename T>
class recursive_wrapper

View File

@@ -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);

0
scripts/flags.sh Normal file → Executable file
View File

View File

@@ -1,10 +0,0 @@
#!/usr/bin/env bash
set -e
set -o pipefail
cd build/Testing
for TEST in ./test_* ; do
${TEST}
done

View File

@@ -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
View 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
View 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

View File

@@ -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 \

View File

@@ -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
}
};

View File

@@ -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);

View 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
View 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
}

View File

@@ -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);
}
}

View File

@@ -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.

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
DotShader::DotShader()
: Shader(
"dot",
shaders[DOT_SHADER].vertex,
shaders[DOT_SHADER].fragment
) {

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
GaussianShader::GaussianShader()
: Shader(
"gaussian",
shaders[GAUSSIAN_SHADER].vertex,
shaders[GAUSSIAN_SHADER].fragment
) {

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
IconShader::IconShader()
: Shader(
"icon",
shaders[ICON_SHADER].vertex,
shaders[ICON_SHADER].fragment
) {

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
LineShader::LineShader()
: Shader(
"line",
shaders[LINE_SHADER].vertex,
shaders[LINE_SHADER].fragment
) {

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
LinejoinShader::LinejoinShader()
: Shader(
"linejoin",
shaders[LINEJOIN_SHADER].vertex,
shaders[LINEJOIN_SHADER].fragment
) {

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
OutlineShader::OutlineShader()
: Shader(
"outline",
shaders[OUTLINE_SHADER].vertex,
shaders[OUTLINE_SHADER].fragment
) {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
PlainShader::PlainShader()
: Shader(
"plain",
shaders[PLAIN_SHADER].vertex,
shaders[PLAIN_SHADER].fragment
) {

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
RasterShader::RasterShader()
: Shader(
"raster",
shaders[RASTER_SHADER].vertex,
shaders[RASTER_SHADER].fragment
) {

View File

@@ -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);

View File

@@ -8,6 +8,7 @@ using namespace mbgl;
TextShader::TextShader()
: Shader(
"text",
shaders[TEXT_SHADER].vertex,
shaders[TEXT_SHADER].fragment
) {

View File

@@ -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] },

View File

@@ -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;
}

View File

@@ -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");

View File

@@ -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; }

View File

@@ -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());
}
}

View File

@@ -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);
}

View File

@@ -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
View 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];
}

View File

@@ -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"
}]
}
}

View File

@@ -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());

View File

@@ -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());
}
}