summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Morris <michael.patrick.morris@gmail.com>2014-09-09 17:06:22 -0400
committerMike Morris <michael.patrick.morris@gmail.com>2014-09-09 17:06:22 -0400
commitc32bb852484420647502a58e880bf8251c13416a (patch)
tree649090d7941e47d772017843fd0d339945f1fb6e
parent74c4f976d1437e81e9bd57ee98fde05fba8c6e80 (diff)
parent2a50fccd24e762d0de5a53bac358e5ddfea8d213 (diff)
downloadqtlocation-mapboxgl-c32bb852484420647502a58e880bf8251c13416a.tar.gz
Merge branch 'master' into libuv010
-rw-r--r--.gitignore1
-rw-r--r--Makefile4
-rw-r--r--common/headless_view.cpp7
-rwxr-xr-xconfigure9
-rw-r--r--include/mbgl/geometry/glyph_atlas.hpp1
-rw-r--r--include/mbgl/geometry/sprite_atlas.hpp15
-rw-r--r--include/mbgl/map/sprite.hpp3
-rw-r--r--include/mbgl/platform/event.hpp1
-rw-r--r--include/mbgl/renderer/frame_history.hpp8
-rw-r--r--include/mbgl/renderer/line_bucket.hpp4
-rw-r--r--include/mbgl/renderer/painter.hpp23
-rw-r--r--include/mbgl/renderer/symbol_bucket.hpp8
-rw-r--r--include/mbgl/shader/dot_shader.hpp29
-rw-r--r--include/mbgl/shader/gaussian_shader.hpp12
-rw-r--r--include/mbgl/shader/icon_shader.hpp52
-rw-r--r--include/mbgl/shader/line_shader.hpp33
-rw-r--r--include/mbgl/shader/linejoin_shader.hpp22
-rw-r--r--include/mbgl/shader/linepattern_shader.hpp33
-rw-r--r--include/mbgl/shader/outline_shader.hpp12
-rw-r--r--include/mbgl/shader/pattern_shader.hpp32
-rw-r--r--include/mbgl/shader/plain_shader.hpp8
-rw-r--r--include/mbgl/shader/raster_shader.hpp42
-rw-r--r--include/mbgl/shader/sdf_shader.hpp53
-rw-r--r--include/mbgl/shader/shader.hpp6
-rw-r--r--include/mbgl/shader/text_shader.hpp72
-rw-r--r--include/mbgl/shader/uniform.hpp53
-rw-r--r--include/mbgl/style/style_bucket.hpp2
-rw-r--r--src/geometry/glyph_atlas.cpp50
-rw-r--r--src/geometry/sprite_atlas.cpp23
-rw-r--r--src/geometry/text_buffer.cpp20
-rw-r--r--src/map/map.cpp4
-rw-r--r--src/map/sprite.cpp9
-rw-r--r--src/renderer/frame_history.cpp39
-rw-r--r--src/renderer/line_bucket.cpp14
-rw-r--r--src/renderer/painter.cpp12
-rw-r--r--src/renderer/painter_clipping.cpp2
-rw-r--r--src/renderer/painter_debug.cpp16
-rw-r--r--src/renderer/painter_fill.cpp56
-rw-r--r--src/renderer/painter_line.cpp81
-rw-r--r--src/renderer/painter_prerender.cpp19
-rw-r--r--src/renderer/painter_raster.cpp31
-rw-r--r--src/renderer/painter_symbol.cpp331
-rw-r--r--src/renderer/prerendered_texture.cpp8
-rw-r--r--src/renderer/raster_bucket.cpp4
-rw-r--r--src/renderer/symbol_bucket.cpp21
-rw-r--r--src/shader/dot.fragment.glsl4
-rw-r--r--src/shader/dot.vertex.glsl4
-rw-r--r--src/shader/dot_shader.cpp32
-rw-r--r--src/shader/gaussian.fragment.glsl5
-rw-r--r--src/shader/gaussian.vertex.glsl2
-rw-r--r--src/shader/gaussian_shader.cpp23
-rw-r--r--src/shader/icon.fragment.glsl2
-rw-r--r--src/shader/icon.vertex.glsl2
-rw-r--r--src/shader/icon_shader.cpp95
-rw-r--r--src/shader/line.vertex.glsl4
-rw-r--r--src/shader/line_shader.cpp58
-rw-r--r--src/shader/linejoin_shader.cpp41
-rw-r--r--src/shader/linepattern.fragment.glsl37
-rw-r--r--src/shader/linepattern.vertex.glsl57
-rw-r--r--src/shader/linepattern_shader.cpp35
-rw-r--r--src/shader/outline_shader.cpp23
-rw-r--r--src/shader/pattern_shader.cpp60
-rw-r--r--src/shader/plain_shader.cpp19
-rw-r--r--src/shader/raster.fragment.glsl6
-rw-r--r--src/shader/raster_shader.cpp79
-rw-r--r--src/shader/sdf.fragment.glsl (renamed from src/shader/text.fragment.glsl)0
-rw-r--r--src/shader/sdf.vertex.glsl (renamed from src/shader/text.vertex.glsl)22
-rw-r--r--src/shader/sdf_shader.cpp91
-rw-r--r--src/shader/shader.cpp9
-rw-r--r--src/shader/text_shader.cpp159
-rw-r--r--src/shader/uniform.cpp47
-rw-r--r--src/style/style_parser.cpp4
72 files changed, 951 insertions, 1254 deletions
diff --git a/.gitignore b/.gitignore
index 740653e6a2..23dbb0f8f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,6 @@
/macosx/build
/ios/build
/config.gypi
-/config.mk
/config/constants_local.cpp
/build
/bin/node_modules
diff --git a/Makefile b/Makefile
index c8d11b407e..d5d7136130 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,3 @@
--include config.mk
-
BUILDTYPE ?= Release
PYTHON ?= python
V ?= 1
@@ -97,11 +95,9 @@ lproj: config.gypi linux/mapboxgl-app.gyp clear_xcode_cache node
clean: clear_xcode_cache
-find ./deps/gyp -name "*.pyc" -exec rm {} \;
-rm -rf ./build/
- -rm -rf ./config.mk
-rm -rf ./config.gypi
distclean: clean
- -rm -rf ./config.mk
-rm -rf ./config.gypi
-rm -rf ./mapnik-packaging/osx/out/
diff --git a/common/headless_view.cpp b/common/headless_view.cpp
index 3fb090f2b5..f790d90cec 100644
--- a/common/headless_view.cpp
+++ b/common/headless_view.cpp
@@ -151,6 +151,13 @@ HeadlessView::~HeadlessView() {
#if MBGL_USE_CGL
CGLDestroyContext(gl_context);
#endif
+
+#if MBGL_USE_GLX
+ glXMakeCurrent(x_display, None, NULL);
+ glXDestroyContext(x_display, gl_context);
+ XFree(x_info);
+ XCloseDisplay(x_display);
+#endif
}
void HeadlessView::notify_map_change(mbgl::MapChange /*change*/, mbgl::timestamp /*delay*/) {
diff --git a/configure b/configure
index a38c587d69..e8f880b543 100755
--- a/configure
+++ b/configure
@@ -133,12 +133,3 @@ if __name__ == '__main__':
write('config.gypi', "# Do not edit. Generated by the configure script.\n" +
pprint.pformat(output, indent=2) + "\n")
-
- config = {
- 'BUILDTYPE': 'Debug' if options.debug else 'Release',
- 'PYTHON': sys.executable,
- }
- config = '\n'.join(map('='.join, config.iteritems())) + '\n'
-
- write('config.mk',
- '# Do not edit. Generated by the configure script.\n' + config)
diff --git a/include/mbgl/geometry/glyph_atlas.hpp b/include/mbgl/geometry/glyph_atlas.hpp
index 8df9fd0f73..336c4af284 100644
--- a/include/mbgl/geometry/glyph_atlas.hpp
+++ b/include/mbgl/geometry/glyph_atlas.hpp
@@ -33,7 +33,6 @@ public:
const SDFGlyph& glyph);
void removeGlyphs(uint64_t tile_id);
void bind();
- void upload();
public:
const uint16_t width = 0;
diff --git a/include/mbgl/geometry/sprite_atlas.hpp b/include/mbgl/geometry/sprite_atlas.hpp
index 36f0f338ea..0946f0fc48 100644
--- a/include/mbgl/geometry/sprite_atlas.hpp
+++ b/include/mbgl/geometry/sprite_atlas.hpp
@@ -9,12 +9,19 @@
#include <mutex>
#include <atomic>
#include <set>
+#include <array>
namespace mbgl {
class Sprite;
class SpritePosition;
+struct SpriteAtlasPosition {
+ std::array<float, 2> size;
+ std::array<float, 2> tl;
+ std::array<float, 2> br;
+};
+
class SpriteAtlas : public util::noncopyable {
public:
typedef uint16_t dimension;
@@ -42,11 +49,11 @@ 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.
- void bind(bool linear = false);
+ SpriteAtlasPosition getPosition(const std::string &name, const Sprite &sprite, bool repeating = false);
- // Uploads the image buffer to the GPU if it is out of date.
- void upload();
+ // Binds the image buffer of this sprite atlas to the GPU, and uploads data if it is out
+ // of date.
+ void bind(bool linear = false);
inline float getWidth() const { return width; }
inline float getHeight() const { return height; }
diff --git a/include/mbgl/map/sprite.hpp b/include/mbgl/map/sprite.hpp
index 7bc6665570..6461a5e33d 100644
--- a/include/mbgl/map/sprite.hpp
+++ b/include/mbgl/map/sprite.hpp
@@ -19,7 +19,7 @@ class FileSource;
class SpritePosition {
public:
explicit SpritePosition() {}
- explicit SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio = 1.0f);
+ explicit SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio, bool sdf);
operator bool() const {
return !(width == 0 && height == 0 && x == 0 && y == 0);
@@ -28,6 +28,7 @@ public:
uint16_t x = 0, y = 0;
uint16_t width = 0, height = 0;
float pixelRatio = 1.0f;
+ bool sdf = false;
};
class Sprite : public std::enable_shared_from_this<Sprite>, private util::noncopyable {
diff --git a/include/mbgl/platform/event.hpp b/include/mbgl/platform/event.hpp
index 1befd0af3b..1676f40d2c 100644
--- a/include/mbgl/platform/event.hpp
+++ b/include/mbgl/platform/event.hpp
@@ -59,7 +59,6 @@ constexpr EventSeverity disabledEventSeverities[] = {
#if !DEBUG
EventSeverity::Debug,
#endif
- EventSeverity(-1) // Avoid zero size array
};
diff --git a/include/mbgl/renderer/frame_history.hpp b/include/mbgl/renderer/frame_history.hpp
index a5dbe21bca..b1f0bcb597 100644
--- a/include/mbgl/renderer/frame_history.hpp
+++ b/include/mbgl/renderer/frame_history.hpp
@@ -16,12 +16,20 @@ struct FrameSnapshot {
float z;
};
+struct FadeProperties {
+ float fadedist;
+ float minfadezoom;
+ float maxfadezoom;
+ float bump;
+};
+
class FrameHistory {
public:
// Record frame history that will be used to calculate fading params
void record(timestamp now, float zoom);
bool needsAnimation(timestamp duration) const;
+ FadeProperties getFadeProperties(timestamp duration);
public:
std::deque<FrameSnapshot> history;
diff --git a/include/mbgl/renderer/line_bucket.hpp b/include/mbgl/renderer/line_bucket.hpp
index c7e375a0a1..8babb734ed 100644
--- a/include/mbgl/renderer/line_bucket.hpp
+++ b/include/mbgl/renderer/line_bucket.hpp
@@ -17,10 +17,11 @@ class LineVertexBuffer;
class TriangleElementsBuffer;
class LineShader;
class LinejoinShader;
+class LinepatternShader;
struct pbf;
class LineBucket : public Bucket {
- typedef ElementGroup<1> triangle_group_type;
+ typedef ElementGroup<2> triangle_group_type;
typedef ElementGroup<1> point_group_type;
public:
@@ -38,6 +39,7 @@ public:
bool hasPoints() const;
void drawLines(LineShader& shader);
+ void drawLinePatterns(LinepatternShader& shader);
void drawPoints(LinejoinShader& shader);
public:
diff --git a/include/mbgl/renderer/painter.hpp b/include/mbgl/renderer/painter.hpp
index a8fe62b550..75529d1136 100644
--- a/include/mbgl/renderer/painter.hpp
+++ b/include/mbgl/renderer/painter.hpp
@@ -14,9 +14,10 @@
#include <mbgl/shader/pattern_shader.hpp>
#include <mbgl/shader/line_shader.hpp>
#include <mbgl/shader/linejoin_shader.hpp>
+#include <mbgl/shader/linepattern_shader.hpp>
#include <mbgl/shader/icon_shader.hpp>
#include <mbgl/shader/raster_shader.hpp>
-#include <mbgl/shader/text_shader.hpp>
+#include <mbgl/shader/sdf_shader.hpp>
#include <mbgl/shader/dot_shader.hpp>
#include <mbgl/shader/gaussian_shader.hpp>
@@ -87,6 +88,8 @@ public:
void renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
void renderBackground(std::shared_ptr<StyleLayer> layer_desc);
+ float saturationFactor(float saturation);
+ float contrastFactor(float contrast);
std::array<float, 3> spinWeights(float spin_value);
void preparePrerender(RasterBucket &bucket);
@@ -117,12 +120,24 @@ public:
void discardFramebuffers();
bool needsAnimation() const;
+
private:
void setupShaders();
- mat4 translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor = TranslateAnchorType::Map);
+ mat4 translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor);
void prepareTile(const Tile& tile);
+ template <typename BucketProperties, typename StyleProperties>
+ void renderSDF(SymbolBucket &bucket,
+ const Tile::ID &id,
+ const mat4 &matrixSymbol,
+ const BucketProperties& bucketProperties,
+ const StyleProperties& styleProperties,
+ float scaleDivisor,
+ std::array<float, 2> texsize,
+ SDFShader& sdfShader,
+ void (SymbolBucket::*drawSDF)(SDFShader&));
+
public:
void useProgram(uint32_t program);
void lineWidth(float lineWidth);
@@ -169,10 +184,12 @@ public:
std::unique_ptr<OutlineShader> outlineShader;
std::unique_ptr<LineShader> lineShader;
std::unique_ptr<LinejoinShader> linejoinShader;
+ std::unique_ptr<LinepatternShader> linepatternShader;
std::unique_ptr<PatternShader> patternShader;
std::unique_ptr<IconShader> iconShader;
std::unique_ptr<RasterShader> rasterShader;
- std::unique_ptr<TextShader> textShader;
+ std::unique_ptr<SDFGlyphShader> sdfGlyphShader;
+ std::unique_ptr<SDFIconShader> sdfIconShader;
std::unique_ptr<DotShader> dotShader;
std::unique_ptr<GaussianShader> gaussianShader;
diff --git a/include/mbgl/renderer/symbol_bucket.hpp b/include/mbgl/renderer/symbol_bucket.hpp
index fb1678fc8b..c71d276456 100644
--- a/include/mbgl/renderer/symbol_bucket.hpp
+++ b/include/mbgl/renderer/symbol_bucket.hpp
@@ -18,7 +18,7 @@
namespace mbgl {
class Style;
-class TextShader;
+class SDFShader;
class IconShader;
class DotShader;
class Collision;
@@ -51,7 +51,7 @@ typedef std::vector<Symbol> Symbols;
class SymbolBucket : public Bucket {
typedef ElementGroup<1> TextElementGroup;
- typedef ElementGroup<1> IconElementGroup;
+ typedef ElementGroup<2> IconElementGroup;
public:
SymbolBucket(const StyleBucketSymbol &properties, Collision &collision);
@@ -68,7 +68,8 @@ public:
void addGlyphs(const PlacedGlyphs &glyphs, float placementZoom, PlacementRange placementRange,
float zoom);
- void drawGlyphs(TextShader &shader);
+ void drawGlyphs(SDFShader& shader);
+ void drawIcons(SDFShader& shader);
void drawIcons(IconShader& shader);
private:
@@ -90,6 +91,7 @@ private:
public:
const StyleBucketSymbol &properties;
+ bool sdfIcons = false;
private:
Collision &collision;
diff --git a/include/mbgl/shader/dot_shader.hpp b/include/mbgl/shader/dot_shader.hpp
index d8d649db9c..2c4176f364 100644
--- a/include/mbgl/shader/dot_shader.hpp
+++ b/include/mbgl/shader/dot_shader.hpp
@@ -2,30 +2,23 @@
#define MBGL_SHADER_SHADER_DOT
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
- class DotShader : public Shader {
- public:
- DotShader();
+class DotShader : public Shader {
+public:
+ DotShader();
- void bind(char *offset);
+ void bind(char *offset);
- void setColor(const std::array<float, 4>& color);
- void setSize(float size);
- void setBlur(float blur);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<std::array<float, 4>> u_color = {"u_color", *this};
+ Uniform<float> u_size = {"u_size", *this};
+ Uniform<float> u_blur = {"u_blur", *this};
- private:
- int32_t a_pos = -1;
-
- std::array<float, 4> color = {{}};
- int32_t u_color = -1;
-
- float size = 0;
- int32_t u_size = -1;
-
- float blur = 0;
- int32_t u_blur = -1;
+private:
+ int32_t a_pos = -1;
};
}
diff --git a/include/mbgl/shader/gaussian_shader.hpp b/include/mbgl/shader/gaussian_shader.hpp
index a4b9d09f3a..0f494f5c7e 100644
--- a/include/mbgl/shader/gaussian_shader.hpp
+++ b/include/mbgl/shader/gaussian_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_RENDERER_SHADER_GAUSSIAN
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,17 +12,12 @@ public:
void bind(char *offset);
- void setImage(int32_t image);
- void setOffset(const std::array<float, 2>& offset);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<std::array<float, 2>> u_offset = {"u_offset", *this};
+ Uniform<int32_t> u_image = {"u_image", *this};
private:
int32_t a_pos = -1;
-
- int32_t image = 0;
- int32_t u_image = -1;
-
- std::array<float, 2> offset = {{}};
- int32_t u_offset = -1;
};
}
diff --git a/include/mbgl/shader/icon_shader.hpp b/include/mbgl/shader/icon_shader.hpp
index 54869fe48d..645d7e21b6 100644
--- a/include/mbgl/shader/icon_shader.hpp
+++ b/include/mbgl/shader/icon_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_SHADER_SHADER_ICON
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,16 +12,17 @@ public:
void bind(char *offset);
- void setExtrudeMatrix(const std::array<float, 16>& exmatrix);
- void setAngle(float angle);
- void setZoom(float zoom);
- void setFlip(float flip);
- void setFadeDist(float fadedist);
- void setMinFadeZoom(float minfadezoom);
- void setMaxFadeZoom(float maxfadezoom);
- void setFadeZoom(float fadezoom);
- void setOpacity(float opacity);
- void setTextureSize(const std::array<float, 2> &texsize);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this};
+ Uniform<float> u_angle = {"u_angle", *this};
+ Uniform<float> u_zoom = {"u_zoom", *this};
+ Uniform<float> u_flip = {"u_flip", *this};
+ Uniform<float> u_fadedist = {"u_fadedist", *this};
+ Uniform<float> u_minfadezoom = {"u_minfadezoom", *this};
+ Uniform<float> u_maxfadezoom = {"u_maxfadezoom", *this};
+ Uniform<float> u_fadezoom = {"u_fadezoom", *this};
+ Uniform<float> u_opacity = {"u_opacity", *this};
+ Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
private:
int32_t a_pos = -1;
@@ -32,36 +34,6 @@ private:
int32_t a_rangeend = -1;
int32_t a_rangestart = -1;
int32_t a_labelminzoom = -1;
-
- std::array<float, 16> exmatrix = {{}};
- int32_t u_exmatrix = -1;
-
- float angle = 0;
- int32_t u_angle = -1;
-
- float zoom = 0;
- int32_t u_zoom = -1;
-
- float flip = 0;
- int32_t u_flip = -1;
-
- float fadedist = 0;
- int32_t u_fadedist = -1;
-
- float minfadezoom = 0;
- int32_t u_minfadezoom = -1;
-
- float maxfadezoom = 0;
- int32_t u_maxfadezoom = -1;
-
- float fadezoom = 0;
- int32_t u_fadezoom = -1;
-
- float opacity = 0;
- int32_t u_opacity = -1;
-
- std::array<float, 2> texsize = {{}};
- int32_t u_texsize = -1;
};
}
diff --git a/include/mbgl/shader/line_shader.hpp b/include/mbgl/shader/line_shader.hpp
index c476b5c4c6..b789330882 100644
--- a/include/mbgl/shader/line_shader.hpp
+++ b/include/mbgl/shader/line_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_SHADER_SHADER_LINE
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,36 +12,18 @@ public:
void bind(char *offset);
- void setExtrudeMatrix(const std::array<float, 16>& exmatrix);
- void setColor(const std::array<float, 4>& color);
- void setLineWidth(const std::array<float, 2>& linewidth);
- void setRatio(float ratio);
- void setDashArray(const std::array<float, 2>& dasharray);
- void setBlur(float blur);
- void setDebug(float debug);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this};
+ Uniform<std::array<float, 4>> u_color = {"u_color", *this};
+ Uniform<std::array<float, 2>> u_linewidth = {"u_linewidth", *this};
+ Uniform<std::array<float, 2>> u_dasharray = {"u_dasharray", *this};
+ Uniform<float> u_ratio = {"u_ratio", *this};
+ Uniform<float> u_blur = {"u_blur", *this};
private:
int32_t a_pos = -1;
int32_t a_extrude = -1;
int32_t a_linesofar = -1;
-
- std::array<float, 16> exmatrix = {{}};
- int32_t u_exmatrix = -1;
-
- std::array<float, 4> color = {{}};
- int32_t u_color = -1;
-
- std::array<float, 2> linewidth = {{}};
- int32_t u_linewidth = -1;
-
- float ratio = 0;
- int32_t u_ratio = -1;
-
- std::array<float, 2> dasharray = {{}};
- int32_t u_dasharray = -1;
-
- float blur = 0.0f;
- int32_t u_blur = -1;
};
diff --git a/include/mbgl/shader/linejoin_shader.hpp b/include/mbgl/shader/linejoin_shader.hpp
index 5a5c97e921..61406fd45c 100644
--- a/include/mbgl/shader/linejoin_shader.hpp
+++ b/include/mbgl/shader/linejoin_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_SHADER_SHADER_LINEJOIN
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,25 +12,14 @@ public:
void bind(char *offset);
- void setColor(const std::array<float, 4>& color);
- void setWorld(const std::array<float, 2>& world);
- void setLineWidth(const std::array<float, 2>& linewidth);
- void setSize(float size);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<std::array<float, 4>> u_color = {"u_color", *this};
+ Uniform<std::array<float, 2>> u_world = {"u_world", *this};
+ Uniform<std::array<float, 2>> u_linewidth = {"u_linewidth", *this};
+ Uniform<float> u_size = {"u_size", *this};
private:
int32_t a_pos = -1;
-
- std::array<float, 4> color = {{}};
- int32_t u_color = -1;
-
- std::array<float, 2> world = {{}};
- int32_t u_world = -1;
-
- std::array<float, 2> linewidth = {{}};
- int32_t u_linewidth = -1;
-
- float size = 0;
- int32_t u_size = -1;
};
}
diff --git a/include/mbgl/shader/linepattern_shader.hpp b/include/mbgl/shader/linepattern_shader.hpp
new file mode 100644
index 0000000000..bf85940b8a
--- /dev/null
+++ b/include/mbgl/shader/linepattern_shader.hpp
@@ -0,0 +1,33 @@
+#ifndef MBGL_SHADER_SHADER_LINEPATTERN
+#define MBGL_SHADER_SHADER_LINEPATTERN
+
+#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
+
+namespace mbgl {
+
+class LinepatternShader : public Shader {
+public:
+ LinepatternShader();
+
+ void bind(char *offset);
+
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this};
+ Uniform<std::array<float, 2>> u_linewidth = {"u_linewidth", *this};
+ Uniform<std::array<float, 2>> u_pattern_size = {"u_pattern_size", *this};
+ Uniform<std::array<float, 2>> u_pattern_tl = {"u_pattern_tl", *this};
+ Uniform<std::array<float, 2>> u_pattern_br = {"u_pattern_br", *this};
+ Uniform<float> u_ratio = {"u_ratio", *this};
+ Uniform<float> u_point = {"u_point", *this};
+ Uniform<float> u_blur = {"u_blur", *this};
+ Uniform<float> u_fade = {"u_fade", *this};
+
+private:
+ int32_t a_pos = -1;
+ int32_t a_extrude = -1;
+ int32_t a_linesofar = -1;
+};
+}
+
+#endif
diff --git a/include/mbgl/shader/outline_shader.hpp b/include/mbgl/shader/outline_shader.hpp
index 551e31ca57..f3e8175fd7 100644
--- a/include/mbgl/shader/outline_shader.hpp
+++ b/include/mbgl/shader/outline_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_SHADER_SHADER_OUTLINE
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,17 +12,12 @@ public:
void bind(char *offset);
- void setColor(const std::array<float, 4>& color);
- void setWorld(const std::array<float, 2>& world);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<std::array<float, 4>> u_color = {"u_color", *this};
+ Uniform<std::array<float, 2>> u_world = {"u_world", *this};
private:
int32_t a_pos = -1;
-
- std::array<float, 4> color = {{}};
- int32_t u_color = -1;
-
- std::array<float, 2> world = {{}};
- int32_t u_world = -1;
};
}
diff --git a/include/mbgl/shader/pattern_shader.hpp b/include/mbgl/shader/pattern_shader.hpp
index e574b755dc..9fabd8e18a 100644
--- a/include/mbgl/shader/pattern_shader.hpp
+++ b/include/mbgl/shader/pattern_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_SHADER_SHADER_PATTERN
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,33 +12,16 @@ public:
void bind(char *offset);
- 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);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<std::array<float, 2>> u_pattern_tl = {"u_pattern_tl", *this};
+ Uniform<std::array<float, 2>> u_pattern_br = {"u_pattern_br", *this};
+ Uniform<float> u_opacity = {"u_opacity", *this};
+ Uniform<float> u_mix = {"u_mix", *this};
+ Uniform<int32_t> u_image = {"u_image", *this};
+ UniformMatrix<3> u_patternmatrix = {"u_patternmatrix", *this};
private:
int32_t a_pos = -1;
-
- std::array<float, 2> pattern_tl = {{}};
- int32_t u_pattern_tl = -1;
-
- std::array<float, 2> pattern_br = {{}};
- int32_t u_pattern_br = -1;
-
- float opacity = 0;
- int32_t u_opacity = -1;
-
- int image = 0;
- int32_t u_image = -1;
-
- float mix = 0;
- int32_t u_mix = -1;
-
- std::array<float, 9> patternmatrix = {{}};
- int32_t u_patternmatrix = -1;
};
}
diff --git a/include/mbgl/shader/plain_shader.hpp b/include/mbgl/shader/plain_shader.hpp
index 277788431f..051501c3c9 100644
--- a/include/mbgl/shader/plain_shader.hpp
+++ b/include/mbgl/shader/plain_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_SHADER_SHADER_PLAIN
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,14 +12,11 @@ public:
void bind(char *offset);
- void setColor(float r, float g, float b, float a);
- void setColor(const std::array<float, 4>& color);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<std::array<float, 4>> u_color = {"u_color", *this};
private:
int32_t a_pos = -1;
-
- std::array<float, 4> color = {{}};
- int32_t u_color = -1;
};
}
diff --git a/include/mbgl/shader/raster_shader.hpp b/include/mbgl/shader/raster_shader.hpp
index 11765413f4..8cf97055a2 100644
--- a/include/mbgl/shader/raster_shader.hpp
+++ b/include/mbgl/shader/raster_shader.hpp
@@ -2,6 +2,7 @@
#define MBGL_RENDERER_SHADER_RASTER
#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
namespace mbgl {
@@ -11,41 +12,18 @@ public:
void bind(char *offset);
- void setImage(int32_t image);
- void setOpacity(float opacity);
- void setBuffer(float buffer);
- void setBrightness(float brightness_low, float brightness_high);
- void setSaturation(float saturation_factor);
- void setContrast(float contrast_factor);
- void setSpin(std::array<float, 3> spin_weights);
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ Uniform<int32_t> u_image = {"u_image", *this};
+ Uniform<float> u_opacity = {"u_opacity", *this};
+ Uniform<float> u_buffer = {"u_buffer", *this};
+ Uniform<float> u_brightness_low = {"u_brightness_low", *this};
+ Uniform<float> u_brightness_high = {"u_brightness_high", *this};
+ Uniform<float> u_saturation_factor = {"u_saturation_factor", *this};
+ Uniform<float> u_contrast_factor = {"u_contrast_factor", *this};
+ Uniform<std::array<float, 3>> u_spin_weights = {"u_spin_weights", *this};
private:
int32_t a_pos = -1;
-
- int32_t image = 0;
- int32_t u_image = -1;
-
- float opacity = 0;
- int32_t u_opacity = -1;
-
- float buffer = 0;
- int32_t u_buffer = -1;
-
- float brightness_low = 0;
- int32_t u_brightness_low = -1;
-
- float brightness_high = 0;
- int32_t u_brightness_high = -1;
-
- float saturation_factor = 0;
- int32_t u_saturation_factor = -1;
-
- float contrast_factor = 1;
- int32_t u_contrast_factor = -1;
-
- std::array<float, 3> spin_weights = {{}};
- int32_t u_spin_weights = -1;
-
};
}
diff --git a/include/mbgl/shader/sdf_shader.hpp b/include/mbgl/shader/sdf_shader.hpp
new file mode 100644
index 0000000000..0737c25ee1
--- /dev/null
+++ b/include/mbgl/shader/sdf_shader.hpp
@@ -0,0 +1,53 @@
+#ifndef MBGL_SHADER_SDF_SHADER
+#define MBGL_SHADER_SDF_SHADER
+
+#include <mbgl/shader/shader.hpp>
+#include <mbgl/shader/uniform.hpp>
+
+namespace mbgl {
+
+class SDFShader : public Shader {
+public:
+ SDFShader();
+
+ virtual void bind(char *offset) = 0;
+
+ UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this};
+ Uniform<std::array<float, 4>> u_color = {"u_color", *this};
+ Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
+ Uniform<float> u_buffer = {"u_buffer", *this};
+ Uniform<float> u_gamma = {"u_gamma", *this};
+ Uniform<float> u_angle = {"u_angle", *this};
+ Uniform<float> u_zoom = {"u_zoom", *this};
+ Uniform<float> u_flip = {"u_flip", *this};
+ Uniform<float> u_fadedist = {"u_fadedist", *this};
+ Uniform<float> u_minfadezoom = {"u_minfadezoom", *this};
+ Uniform<float> u_maxfadezoom = {"u_maxfadezoom", *this};
+ Uniform<float> u_fadezoom = {"u_fadezoom", *this};
+
+protected:
+ int32_t a_pos = -1;
+ int32_t a_offset = -1;
+ int32_t a_tex = -1;
+ int32_t a_angle = -1;
+ int32_t a_minzoom = -1;
+ int32_t a_maxzoom = -1;
+ int32_t a_rangeend = -1;
+ int32_t a_rangestart = -1;
+ int32_t a_labelminzoom = -1;
+};
+
+class SDFGlyphShader : public SDFShader {
+public:
+ void bind(char *offset);
+};
+
+class SDFIconShader : public SDFShader {
+public:
+ void bind(char *offset);
+};
+
+}
+
+#endif
diff --git a/include/mbgl/shader/shader.hpp b/include/mbgl/shader/shader.hpp
index fa2d5a0a8e..27e831a510 100644
--- a/include/mbgl/shader/shader.hpp
+++ b/include/mbgl/shader/shader.hpp
@@ -15,18 +15,12 @@ public:
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);
-
-protected:
- std::array<float, 16> matrix = {{}};
- int32_t u_matrix = -1;
};
}
diff --git a/include/mbgl/shader/text_shader.hpp b/include/mbgl/shader/text_shader.hpp
deleted file mode 100644
index 554b890fb0..0000000000
--- a/include/mbgl/shader/text_shader.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef MBGL_SHADER_TEXT_SHADER
-#define MBGL_SHADER_TEXT_SHADER
-
-#include "shader.hpp"
-
-namespace mbgl {
-
-class TextShader : public Shader {
-public:
- TextShader();
-
- void bind(char *offset);
-
- void setColor(float r, float g, float b, float a);
- void setColor(const std::array<float, 4> &color);
- void setBuffer(float buffer);
- void setGamma(float gamma);
- void setExtrudeMatrix(const std::array<float, 16> &exmatrix);
- void setAngle(float angle);
- void setZoom(float zoom);
- void setFlip(float flip);
- void setFadeDist(float fadedist);
- void setMinFadeZoom(float minfadezoom);
- void setMaxFadeZoom(float maxfadezoom);
- void setFadeZoom(float fadezoom);
- void setTextureSize(const std::array<float, 2> &texsize);
-
-private:
- int32_t a_pos = -1;
- int32_t a_offset = -1;
- int32_t a_data1 = -1;
- int32_t a_data2 = -1;
-
- std::array<float, 4> color = {{}};
- int32_t u_color = -1;
-
- float buffer = 0.0f;
- int32_t u_buffer = -1;
-
- float gamma = 0.0f;
- int32_t u_gamma = -1;
-
- std::array<float, 16> exmatrix = {{}};
- int32_t u_exmatrix = -1;
-
- float angle = 0.0f;
- int32_t u_angle = -1;
-
- float zoom = 0.0f;
- int32_t u_zoom = -1;
-
- float flip = 0.0f;
- int32_t u_flip = -1;
-
- float fadedist = 0.0f;
- int32_t u_fadedist = -1;
-
- float minfadezoom = 0.0f;
- int32_t u_minfadezoom = -1;
-
- float maxfadezoom = 0.0f;
- int32_t u_maxfadezoom = -1;
-
- float fadezoom = 0.0f;
- int32_t u_fadezoom = -1;
-
- std::array<float, 2> texsize = {{}};
- int32_t u_texsize = -1;
-};
-}
-
-#endif
diff --git a/include/mbgl/shader/uniform.hpp b/include/mbgl/shader/uniform.hpp
new file mode 100644
index 0000000000..a87bbd7aa3
--- /dev/null
+++ b/include/mbgl/shader/uniform.hpp
@@ -0,0 +1,53 @@
+#ifndef MBGL_SHADER_UNIFORM
+#define MBGL_SHADER_UNIFORM
+
+#include <mbgl/shader/shader.hpp>
+#include <mbgl/platform/gl.hpp>
+
+namespace mbgl {
+
+template <typename T>
+class Uniform {
+public:
+ Uniform(const GLchar* name, const Shader& shader)
+ : location(glGetUniformLocation(shader.program, name)) {}
+
+ void operator=(const T& t) {
+ if (current != t) {
+ current = t;
+ bind(t);
+ }
+ }
+
+private:
+ void bind(const T&);
+
+ T current;
+ GLint location;
+};
+
+template <size_t C, size_t R = C>
+class UniformMatrix {
+public:
+ typedef std::array<float, C*R> T;
+
+ UniformMatrix(const GLchar* name, const Shader& shader)
+ : location(glGetUniformLocation(shader.program, name)) {}
+
+ void operator=(const T& t) {
+ if (current != t) {
+ current = t;
+ bind(t);
+ }
+ }
+
+private:
+ void bind(const T&);
+
+ T current;
+ GLint location;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/style/style_bucket.hpp b/include/mbgl/style/style_bucket.hpp
index 67c3142059..c2cde52aa5 100644
--- a/include/mbgl/style/style_bucket.hpp
+++ b/include/mbgl/style/style_bucket.hpp
@@ -53,7 +53,6 @@ public:
float padding = 2.0f;
bool keep_upright = false;
vec2<float> offset = {0, 0};
- TranslateAnchorType translate_anchor = TranslateAnchorType::Map;
} icon;
struct {
@@ -74,7 +73,6 @@ public:
bool keep_upright = true;
TextTransformType transform = TextTransformType::None;
vec2<float> offset = {0, 0};
- TranslateAnchorType translate_anchor = TranslateAnchorType::Map;
bool allow_overlap = false;
bool ignore_placement = false;
bool optional = false;
diff --git a/src/geometry/glyph_atlas.cpp b/src/geometry/glyph_atlas.cpp
index 9e74e21b24..76df941d90 100644
--- a/src/geometry/glyph_atlas.cpp
+++ b/src/geometry/glyph_atlas.cpp
@@ -120,46 +120,6 @@ 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);
@@ -171,4 +131,14 @@ void GlyphAtlas::bind() {
} else {
glBindTexture(GL_TEXTURE_2D, texture);
}
+
+ if (dirty) {
+ std::lock_guard<std::mutex> lock(mtx);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
+ dirty = false;
+
+#if defined(DEBUG)
+ // platform::show_debug_image("Glyph Atlas", data, width, height);
+#endif
+ }
};
diff --git a/src/geometry/sprite_atlas.cpp b/src/geometry/sprite_atlas.cpp
index 730551dbeb..7ea9d4ce7d 100644
--- a/src/geometry/sprite_atlas.cpp
+++ b/src/geometry/sprite_atlas.cpp
@@ -132,6 +132,18 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string &name, cons
return rect;
}
+SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, const Sprite& sprite, bool repeating) {
+ // `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
+ Rect<dimension> rect = getImage(name, sprite);
+ const int r = repeating ? 1 : 0;
+ return SpriteAtlasPosition {
+ {{ float(rect.w) / pixelRatio, float(rect.h) / pixelRatio }},
+ {{ float(rect.x + r) / width, float(rect.y + r) / height }},
+ {{ float(rect.x + rect.w - 2*r) / width, float(rect.y + rect.h - 2*r) / height }}
+ };
+}
Rect<SpriteAtlas::dimension> SpriteAtlas::waitForImage(const std::string &name, const Sprite &sprite) {
sprite.waitUntilLoaded();
@@ -196,11 +208,13 @@ 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);
}
@@ -211,17 +225,12 @@ 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 (!exists) {
+ if (first) {
glTexImage2D(
GL_TEXTURE_2D, // GLenum target
0, // GLint level
@@ -252,7 +261,7 @@ void SpriteAtlas::upload() {
#endif
dirty = false;
}
-}
+};
SpriteAtlas::~SpriteAtlas() {
std::lock_guard<std::mutex> lock(mtx);
diff --git a/src/geometry/text_buffer.cpp b/src/geometry/text_buffer.cpp
index cb30101839..295ff02efa 100644
--- a/src/geometry/text_buffer.cpp
+++ b/src/geometry/text_buffer.cpp
@@ -19,17 +19,15 @@ size_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t
shorts[3] = std::round(oy * 64);
uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data1
- ubytes[8] = tx / 4;
- ubytes[9] = ty / 4;
- ubytes[10] = labelminzoom * 10;
- ubytes[11] = (int16_t)std::round(angle * angleFactor) % 256;
-
- // a_data2
- ubytes[12] = minzoom * 10; // 1/10 zoom levels: z16 == 160.
- ubytes[13] = std::fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160.
- ubytes[14] = util::max((int16_t)std::round(range[0] * angleFactor), (int16_t)0) % 256;
- ubytes[15] = util::min((int16_t)std::round(range[1] * angleFactor), (int16_t)255) % 256;
+ ubytes[8] = labelminzoom * 10;
+ ubytes[9] = minzoom * 10; // 1/10 zoom levels: z16 == 160.
+ ubytes[10] = fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160.
+ ubytes[11] = (int16_t)round(angle * angleFactor) % 256;
+ ubytes[12] = util::max((int16_t)std::round(range[0] * angleFactor), (int16_t)0) % 256;
+ ubytes[13] = util::min((int16_t)std::round(range[1] * angleFactor), (int16_t)255) % 256;
+
+ ubytes[14] = tx / 4;
+ ubytes[15] = ty / 4;
return idx;
}
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 5c139f3646..1399b97ee2 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -545,10 +545,6 @@ void Map::render() {
#if defined(DEBUG)
std::vector<std::string> debug;
#endif
-
- glyphAtlas->upload();
- spriteAtlas->upload();
-
painter.clear();
painter.resize();
diff --git a/src/map/sprite.cpp b/src/map/sprite.cpp
index a8f4f97185..af9413a0e3 100644
--- a/src/map/sprite.cpp
+++ b/src/map/sprite.cpp
@@ -13,12 +13,13 @@
using namespace mbgl;
-SpritePosition::SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio)
+SpritePosition::SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio, bool sdf)
: x(x),
y(y),
width(width),
height(height),
- pixelRatio(pixelRatio) {
+ pixelRatio(pixelRatio),
+ sdf(sdf) {
}
std::shared_ptr<Sprite> Sprite::Create(const std::string& base_url, float pixelRatio, const std::shared_ptr<FileSource> &fileSource) {
@@ -123,13 +124,15 @@ void Sprite::parseJSON() {
uint16_t width = 0;
uint16_t height = 0;
float pixelRatio = 1.0f;
+ bool sdf = false;
if (value.HasMember("x")) x = value["x"].GetInt();
if (value.HasMember("y")) y = value["y"].GetInt();
if (value.HasMember("width")) width = value["width"].GetInt();
if (value.HasMember("height")) height = value["height"].GetInt();
if (value.HasMember("pixelRatio")) pixelRatio = value["pixelRatio"].GetInt();
- pos.emplace(name, SpritePosition { x, y, width, height, pixelRatio });
+ if (value.HasMember("sdf")) sdf = value["sdf"].GetBool();
+ pos.emplace(name, SpritePosition { x, y, width, height, pixelRatio, sdf });
}
}
} else {
diff --git a/src/renderer/frame_history.cpp b/src/renderer/frame_history.cpp
index 6a11f0d4c6..8b69162a23 100644
--- a/src/renderer/frame_history.cpp
+++ b/src/renderer/frame_history.cpp
@@ -45,4 +45,41 @@ bool FrameHistory::needsAnimation(const timestamp duration) const {
}
return false;
-} \ No newline at end of file
+}
+
+FadeProperties FrameHistory::getFadeProperties(timestamp duration)
+{
+ const timestamp currentTime = util::now();
+
+ // Remove frames until only one is outside the duration, or until there are only three
+ while (history.size() > 3 && history[1].t + duration < currentTime) {
+ history.pop_front();
+ }
+
+ if (history[1].t + duration < currentTime) {
+ history[0].z = history[1].z;
+ }
+
+ // Find the range of zoom levels we want to fade between
+ float startingZ = history.front().z;
+ const FrameSnapshot lastFrame = history.back();
+ float endingZ = lastFrame.z;
+ float lowZ = std::fmin(startingZ, endingZ);
+ float highZ = std::fmax(startingZ, endingZ);
+
+ // Calculate the speed of zooming, and how far it would zoom in terms of zoom levels in one
+ // duration
+ float zoomDiff = endingZ - history[1].z, timeDiff = lastFrame.t - history[1].t;
+ float fadedist = zoomDiff / (timeDiff / duration);
+
+ // At end of a zoom when the zoom stops changing continue pretending to zoom at that speed
+ // bump is how much farther it would have been if it had continued zooming at the same rate
+ float bump = (currentTime - lastFrame.t) / duration * fadedist;
+
+ return FadeProperties {
+ fadedist,
+ lowZ,
+ highZ,
+ bump
+ };
+}
diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp
index e089d7f61b..2e89a7c35d 100644
--- a/src/renderer/line_bucket.cpp
+++ b/src/renderer/line_bucket.cpp
@@ -374,6 +374,20 @@ void LineBucket::drawLines(LineShader& shader) {
}
}
+void LineBucket::drawLinePatterns(LinepatternShader& 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) {
+ if (!group.elements_length) {
+ continue;
+ }
+ 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;
+ }
+}
+
void LineBucket::drawPoints(LinejoinShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(point_elements_start * pointElementsBuffer.itemSize);
diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp
index 2a3d45c9ed..c1705cd7cf 100644
--- a/src/renderer/painter.cpp
+++ b/src/renderer/painter.cpp
@@ -41,9 +41,11 @@ void Painter::setup() {
assert(outlineShader);
assert(lineShader);
assert(linejoinShader);
+ assert(linepatternShader);
assert(patternShader);
assert(rasterShader);
- assert(textShader);
+ assert(sdfGlyphShader);
+ assert(sdfIconShader);
assert(dotShader);
assert(gaussianShader);
@@ -70,10 +72,12 @@ void Painter::setupShaders() {
if (!outlineShader) outlineShader = std::make_unique<OutlineShader>();
if (!lineShader) lineShader = std::make_unique<LineShader>();
if (!linejoinShader) linejoinShader = std::make_unique<LinejoinShader>();
+ if (!linepatternShader) linepatternShader = std::make_unique<LinepatternShader>();
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 (!sdfGlyphShader) sdfGlyphShader = std::make_unique<SDFGlyphShader>();
+ if (!sdfIconShader) sdfIconShader = std::make_unique<SDFIconShader>();
if (!dotShader) dotShader = std::make_unique<DotShader>();
if (!gaussianShader) gaussianShader = std::make_unique<GaussianShader>();
}
@@ -193,8 +197,8 @@ void Painter::renderBackground(std::shared_ptr<StyleLayer> layer_desc) {
if ((color[3] >= 1.0f) == (pass == RenderPass::Opaque)) {
useProgram(plainShader->program);
- plainShader->setMatrix(identityMatrix);
- plainShader->setColor(color);
+ plainShader->u_matrix = identityMatrix;
+ plainShader->u_color = color;
backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0));
glDisable(GL_STENCIL_TEST);
diff --git a/src/renderer/painter_clipping.cpp b/src/renderer/painter_clipping.cpp
index d8fa3693bd..45b14a2f78 100644
--- a/src/renderer/painter_clipping.cpp
+++ b/src/renderer/painter_clipping.cpp
@@ -28,7 +28,7 @@ void Painter::drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &so
}
void Painter::drawClippingMask(const mat4& matrix, const ClipID &clip) {
- plainShader->setMatrix(matrix);
+ plainShader->u_matrix = matrix;
const GLint ref = (GLint)(clip.reference.to_ulong());
const GLuint mask = (GLuint)(clip.mask.to_ulong());
diff --git a/src/renderer/painter_debug.cpp b/src/renderer/painter_debug.cpp
index eae655f1f5..f120533838 100644
--- a/src/renderer/painter_debug.cpp
+++ b/src/renderer/painter_debug.cpp
@@ -21,10 +21,10 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) {
glDisable(GL_DEPTH_TEST);
useProgram(plainShader->program);
- plainShader->setMatrix(matrix);
+ plainShader->u_matrix = matrix;
// Draw white outline
- plainShader->setColor(1.0f, 1.0f, 1.0f, 1.0f);
+ plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
lineWidth(4.0f * map.getState().getPixelRatio());
bucket.drawLines(*plainShader);
@@ -35,7 +35,7 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) {
#endif
// Draw black text.
- plainShader->setColor(0.0f, 0.0f, 0.0f, 1.0f);
+ plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
lineWidth(2.0f * map.getState().getPixelRatio());
bucket.drawLines(*plainShader);
@@ -51,11 +51,11 @@ void Painter::renderDebugFrame(const mat4 &matrix) {
glDisable(GL_DEPTH_TEST);
useProgram(plainShader->program);
- plainShader->setMatrix(matrix);
+ plainShader->u_matrix = matrix;
// draw tile outline
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
- plainShader->setColor(1.0f, 0.0f, 0.0f, 1.0f);
+ plainShader->u_color = {{ 1.0f, 0.0f, 0.0f, 1.0f }};
lineWidth(4.0f * map.getState().getPixelRatio());
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index());
@@ -73,7 +73,7 @@ void Painter::renderDebugText(const std::vector<std::string> &strings) {
glStencilFunc(GL_ALWAYS, 0xFF, 0xFF);
useProgram(plainShader->program);
- plainShader->setMatrix(nativeMatrix);
+ plainShader->u_matrix = nativeMatrix;
DebugFontBuffer debugFontBuffer;
int line = 25;
@@ -86,14 +86,14 @@ void Painter::renderDebugText(const std::vector<std::string> &strings) {
// draw debug info
VertexArrayObject debugFontArray;
debugFontArray.bind(*plainShader, debugFontBuffer, BUFFER_OFFSET(0));
- plainShader->setColor(1.0f, 1.0f, 1.0f, 1.0f);
+ plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
lineWidth(4.0f * map.getState().getPixelRatio());
glDrawArrays(GL_LINES, 0, (GLsizei)debugFontBuffer.index());
#ifndef GL_ES_VERSION_2_0
glPointSize(2);
glDrawArrays(GL_POINTS, 0, (GLsizei)debugFontBuffer.index());
#endif
- plainShader->setColor(0.0f, 0.0f, 0.0f, 1.0f);
+ plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
lineWidth(2.0f * map.getState().getPixelRatio());
glDrawArrays(GL_LINES, 0, (GLsizei)debugFontBuffer.index());
}
diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp
index 97ca1767f9..6d56b9077e 100644
--- a/src/renderer/painter_fill.cpp
+++ b/src/renderer/painter_fill.cpp
@@ -42,16 +42,16 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_d
// below, we have to draw the outline first (!)
if (outline && pass == RenderPass::Translucent) {
useProgram(outlineShader->program);
- outlineShader->setMatrix(vtxMatrix);
+ outlineShader->u_matrix = vtxMatrix;
lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio!
- outlineShader->setColor(stroke_color);
+ outlineShader->u_color = stroke_color;
// Draw the entire line
- outlineShader->setWorld({{
+ outlineShader->u_world = {{
static_cast<float>(map.getState().getFramebufferWidth()),
static_cast<float>(map.getState().getFramebufferHeight())
- }});
+ }};
depthRange(strata, 1.0f);
bucket.drawVertices(*outlineShader);
}
@@ -61,40 +61,22 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_d
Sprite &sprite = *map.getSprite();
if (pass == RenderPass::Translucent && sprite) {
SpriteAtlas &spriteAtlas = *map.getSpriteAtlas();
- 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 SpriteAtlasPosition pos = spriteAtlas.getPosition(properties.image, sprite, true);
const float mix = std::fmod(float(map.getState().getZoom()), 1.0f);
-
const float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z);
mat3 patternMatrix;
matrix::identity(patternMatrix);
- matrix::scale(patternMatrix, patternMatrix, 1.0f / (size[0] * factor), 1.0f / (size[1] * factor));
+ matrix::scale(patternMatrix, patternMatrix, 1.0f / (pos.size[0] * factor), 1.0f / (pos.size[1] * factor));
useProgram(patternShader->program);
- patternShader->setMatrix(vtxMatrix);
- patternShader->setPatternTopLeft(tl);
- patternShader->setPatternBottomRight(br);
- patternShader->setOpacity(properties.opacity);
- patternShader->setImage(0);
- patternShader->setMix(mix);
- patternShader->setPatternMatrix(patternMatrix);
+ patternShader->u_matrix = vtxMatrix;
+ patternShader->u_pattern_tl = pos.tl;
+ patternShader->u_pattern_br = pos.br;
+ patternShader->u_opacity = properties.opacity;
+ patternShader->u_image = 0;
+ patternShader->u_mix = mix;
+ patternShader->u_patternmatrix = patternMatrix;
glActiveTexture(GL_TEXTURE0);
spriteAtlas.bind(true);
@@ -112,8 +94,8 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_d
// fragments
// Draw filling rectangle.
useProgram(plainShader->program);
- plainShader->setMatrix(vtxMatrix);
- plainShader->setColor(fill_color);
+ plainShader->u_matrix = vtxMatrix;
+ plainShader->u_color = fill_color;
// Draw the actual triangles into the color & stencil buffer.
depthRange(strata + strata_epsilon, 1.0f);
@@ -125,16 +107,16 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_d
// below, we have to draw the outline first (!)
if (fringeline && pass == RenderPass::Translucent) {
useProgram(outlineShader->program);
- outlineShader->setMatrix(vtxMatrix);
+ outlineShader->u_matrix = vtxMatrix;
lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio!
- outlineShader->setColor(fill_color);
+ outlineShader->u_color = fill_color;
// Draw the entire line
- outlineShader->setWorld({{
+ outlineShader->u_world = {{
static_cast<float>(map.getState().getFramebufferWidth()),
static_cast<float>(map.getState().getFramebufferHeight())
- }});
+ }};
depthRange(strata + strata_epsilon, 1.0f);
bucket.drawVertices(*outlineShader);
diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp
index ad0778fc0b..161abcd6ff 100644
--- a/src/renderer/painter_line.cpp
+++ b/src/renderer/painter_line.cpp
@@ -1,6 +1,9 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/line_bucket.hpp>
+#include <mbgl/style/style.hpp>
#include <mbgl/style/style_layer.hpp>
+#include <mbgl/map/sprite.hpp>
+#include <mbgl/geometry/sprite_atlas.hpp>
#include <mbgl/map/map.hpp>
using namespace mbgl;
@@ -12,9 +15,9 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d
const LineProperties &properties = layer_desc->getProperties<LineProperties>();
+ float antialiasing = 1 / map.getState().getPixelRatio();
float width = properties.width;
float offset = properties.offset / 2;
- float antialiasing = 1 / map.getState().getPixelRatio();
float blur = properties.blur + antialiasing;
// These are the radii of the line. We are limiting it to 16, which will result
@@ -31,6 +34,7 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d
float dash_length = properties.dash_array[0];
float dash_gap = properties.dash_array[1];
+ float ratio = map.getState().getPixelRatio();
mat4 vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor);
depthRange(strata, 1.0f);
@@ -38,52 +42,63 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d
// 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) {
useProgram(linejoinShader->program);
- linejoinShader->setMatrix(vtxMatrix);
- linejoinShader->setColor(color);
- linejoinShader->setWorld({{
- map.getState().getFramebufferWidth() * 0.5f,
- map.getState().getFramebufferHeight() * 0.5f
- }
- });
- linejoinShader->setLineWidth({{
- ((outset - 0.25f) * map.getState().getPixelRatio()),
- ((inset - 0.25f) * map.getState().getPixelRatio())
- }
- });
+ linejoinShader->u_matrix = vtxMatrix;
+ linejoinShader->u_color = color;
+ linejoinShader->u_world = {{
+ map.getState().getFramebufferWidth() * 0.5f,
+ map.getState().getFramebufferHeight() * 0.5f
+ }};
+ linejoinShader->u_linewidth = {{
+ ((outset - 0.25f) * map.getState().getPixelRatio()),
+ ((inset - 0.25f) * map.getState().getPixelRatio())
+ }};
float pointSize = std::ceil(map.getState().getPixelRatio() * outset * 2.0);
#if defined(GL_ES_VERSION_2_0)
- linejoinShader->setSize(pointSize);
+ linejoinShader->u_size = pointSize;
#else
glPointSize(pointSize);
#endif
bucket.drawPoints(*linejoinShader);
}
- // var imagePos = properties.image && imageSprite.getPosition(properties.image);
- bool imagePos = false;
- if (imagePos) {
- // var factor = 8 / Math.pow(2, painter.transform.zoom - params.z);
+ const std::shared_ptr<Sprite> &sprite = map.getSprite();
+ if (properties.image.size() && sprite) {
+ SpriteAtlasPosition imagePos = map.getSpriteAtlas()->getPosition(properties.image, *sprite);
+
+ float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z);
+ float fade = std::fmod(map.getState().getZoom(), 1.0);
+
+ useProgram(linepatternShader->program);
+
+ linepatternShader->u_matrix = vtxMatrix;
+ linepatternShader->u_exmatrix = extrudeMatrix;
+ linepatternShader->u_linewidth = {{ outset, inset }};
+ linepatternShader->u_ratio = ratio;
+ linepatternShader->u_blur = blur;
- // imageSprite.bind(gl, true);
+ linepatternShader->u_pattern_size = {{imagePos.size[0] * factor, imagePos.size[1]}};
+ linepatternShader->u_pattern_tl = imagePos.tl;
+ linepatternShader->u_pattern_br = imagePos.br;
+ linepatternShader->u_fade = fade;
- // //factor = Math.pow(2, 4 - painter.transform.zoom + params.z);
- // gl.switchShader(painter.linepatternShader, painter.translatedMatrix || painter.posMatrix, painter.extrudeMatrix);
- // shader = painter.linepatternShader;
- // glUniform2fv(painter.linepatternShader.u_pattern_size, [imagePos.size[0] * factor, imagePos.size[1] ]);
- // glUniform2fv(painter.linepatternShader.u_pattern_tl, imagePos.tl);
- // glUniform2fv(painter.linepatternShader.u_pattern_br, imagePos.br);
- // glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0);
+ map.getSpriteAtlas()->bind(true);
+ glDepthRange(strata + strata_epsilon, 1.0f); // may or may not matter
+
+ bucket.drawLinePatterns(*linepatternShader);
} else {
useProgram(lineShader->program);
- lineShader->setMatrix(vtxMatrix);
- lineShader->setExtrudeMatrix(extrudeMatrix);
- lineShader->setDashArray({{ dash_length, dash_gap }});
- lineShader->setLineWidth({{ outset, inset }});
- lineShader->setRatio(map.getState().getPixelRatio());
- lineShader->setBlur(blur);
- lineShader->setColor(color);
+
+ lineShader->u_matrix = vtxMatrix;
+ lineShader->u_exmatrix = extrudeMatrix;
+ lineShader->u_linewidth = {{ outset, inset }};
+ lineShader->u_ratio = ratio;
+ lineShader->u_blur = blur;
+
+ lineShader->u_color = color;
+ lineShader->u_dasharray = {{ dash_length, dash_gap }};
+
bucket.drawLines(*lineShader);
}
}
diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp
index 14a15effe1..f38470530b 100644
--- a/src/renderer/painter_prerender.cpp
+++ b/src/renderer/painter_prerender.cpp
@@ -25,19 +25,20 @@ void Painter::renderPrerenderedTexture(RasterBucket &bucket, const mat4 &matrix,
// draw the texture on a quad
useProgram(rasterShader->program);
- rasterShader->setMatrix(matrix);
- rasterShader->setOpacity(1);
+ rasterShader->u_matrix = matrix;
+ rasterShader->u_opacity = 1;
depthRange(strata, 1.0f);
glActiveTexture(GL_TEXTURE0);
- rasterShader->setImage(0);
- rasterShader->setBuffer(buffer);
- rasterShader->setOpacity(properties.opacity);
- rasterShader->setBrightness(properties.brightness[0], properties.brightness[1]);
- rasterShader->setSaturation(properties.saturation);
- rasterShader->setContrast(properties.contrast);
- rasterShader->setSpin(spinWeights(properties.hue_rotate));
+ rasterShader->u_image = 0;
+ rasterShader->u_buffer = buffer;
+ rasterShader->u_opacity = properties.opacity;
+ rasterShader->u_brightness_low = properties.brightness[0];
+ rasterShader->u_brightness_high = properties.brightness[1];
+ rasterShader->u_saturation_factor = saturationFactor(properties.saturation);
+ rasterShader->u_contrast_factor = contrastFactor(properties.contrast);
+ rasterShader->u_spin_weights = spinWeights(properties.hue_rotate);
bucket.texture.bindTexture();
coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index());
diff --git a/src/renderer/painter_raster.cpp b/src/renderer/painter_raster.cpp
index 946f6216c7..7f7afc3e84 100644
--- a/src/renderer/painter_raster.cpp
+++ b/src/renderer/painter_raster.cpp
@@ -63,13 +63,14 @@ void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> lay
depthMask(false);
useProgram(rasterShader->program);
- rasterShader->setMatrix(matrix);
- rasterShader->setBuffer(0);
- rasterShader->setOpacity(properties.opacity);
- rasterShader->setBrightness(properties.brightness[0], properties.brightness[1]);
- rasterShader->setSaturation(properties.saturation);
- rasterShader->setContrast(properties.contrast);
- rasterShader->setSpin(spinWeights(properties.hue_rotate));
+ rasterShader->u_matrix = matrix;
+ rasterShader->u_buffer = 0;
+ rasterShader->u_opacity = properties.opacity;
+ rasterShader->u_brightness_low = properties.brightness[0];
+ rasterShader->u_brightness_high = properties.brightness[1];
+ rasterShader->u_saturation_factor = saturationFactor(properties.saturation);
+ rasterShader->u_contrast_factor = contrastFactor(properties.contrast);
+ rasterShader->u_spin_weights = spinWeights(properties.hue_rotate);
depthRange(strata + strata_epsilon, 1.0f);
@@ -80,6 +81,22 @@ void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> lay
}
+float Painter::saturationFactor(float saturation) {
+ if (saturation > 0) {
+ return 1 - 1 / (1.001 - saturation);
+ } else {
+ return -saturation;
+ }
+}
+
+float Painter::contrastFactor(float contrast) {
+ if (contrast > 0) {
+ return 1 / (1 - contrast);
+ } else {
+ return 1 + contrast;
+ }
+}
+
std::array<float, 3> Painter::spinWeights(float spin) {
spin *= M_PI / 180;
float s = std::sin(spin);
diff --git a/src/renderer/painter_symbol.cpp b/src/renderer/painter_symbol.cpp
index e412bc49d7..4fce66217f 100644
--- a/src/renderer/painter_symbol.cpp
+++ b/src/renderer/painter_symbol.cpp
@@ -7,7 +7,110 @@
#include <mbgl/util/math.hpp>
#include <cmath>
-namespace mbgl {
+using namespace mbgl;
+
+template <typename BucketProperties, typename StyleProperties>
+void Painter::renderSDF(SymbolBucket &bucket,
+ const Tile::ID &id,
+ const mat4 &matrix,
+ const BucketProperties& bucketProperties,
+ const StyleProperties& styleProperties,
+ float sdfFontSize,
+ std::array<float, 2> texsize,
+ SDFShader& sdfShader,
+ void (SymbolBucket::*drawSDF)(SDFShader&))
+{
+ mat4 vtxMatrix = translatedMatrix(matrix, styleProperties.translate, id, styleProperties.translate_anchor);
+
+ mat4 exMatrix;
+ matrix::copy(exMatrix, projMatrix);
+
+ const float angleOffset =
+ bucketProperties.rotation_alignment == RotationAlignmentType::Map
+ ? map.getState().getAngle()
+ : 0;
+
+ if (angleOffset) {
+ matrix::rotate_z(exMatrix, exMatrix, angleOffset);
+ }
+
+ // If layerStyle.size > bucket.info.fontSize then labels may collide
+ float fontSize = std::fmin(styleProperties.size, bucketProperties.max_size);
+ float fontScale = fontSize / sdfFontSize;
+ matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f);
+
+ useProgram(sdfShader.program);
+ sdfShader.u_matrix = vtxMatrix;
+ sdfShader.u_exmatrix = exMatrix;
+ sdfShader.u_texsize = texsize;
+
+ // Convert the -pi..pi to an int8 range.
+ float angle = std::round(map.getState().getAngle() / M_PI * 128);
+
+ // adjust min/max zooms for variable font sies
+ float zoomAdjust = std::log(fontSize / bucketProperties.max_size) / std::log(2);
+
+ sdfShader.u_angle = (int32_t)(angle + 256) % 256;
+ sdfShader.u_flip = (bucket.properties.placement == PlacementType::Line ? 1 : 0);
+ sdfShader.u_zoom = (map.getState().getNormalizedZoom() - zoomAdjust) * 10; // current zoom level
+
+ FadeProperties f = frameHistory.getFadeProperties(300_milliseconds);
+ sdfShader.u_fadedist = f.fadedist * 10;
+ sdfShader.u_minfadezoom = std::floor(f.minfadezoom * 10);
+ sdfShader.u_maxfadezoom = std::floor(f.maxfadezoom * 10);
+ sdfShader.u_fadezoom = (map.getState().getNormalizedZoom() + f.bump) * 10;
+
+ // The default gamma value has to be adjust for the current pixelratio so that we're not
+ // drawing blurry font on retina screens.
+ const float gamma = 0.105 * sdfFontSize / fontSize / map.getState().getPixelRatio();
+
+ const float sdfPx = 8.0f;
+ const float blurOffset = 1.19f;
+ const float haloOffset = 6.0f;
+
+ // We're drawing in the translucent pass which is bottom-to-top, so we need
+ // to draw the halo first.
+ if (styleProperties.halo_color[3] > 0.0f) {
+ sdfShader.u_gamma = styleProperties.halo_blur * blurOffset / fontScale / sdfPx + gamma;
+
+ if (styleProperties.opacity < 1.0f) {
+ Color color = styleProperties.halo_color;
+ color[0] *= styleProperties.opacity;
+ color[1] *= styleProperties.opacity;
+ color[2] *= styleProperties.opacity;
+ color[3] *= styleProperties.opacity;
+ sdfShader.u_color = color;
+ } else {
+ sdfShader.u_color = styleProperties.halo_color;
+ }
+
+ sdfShader.u_buffer = (haloOffset - styleProperties.halo_width / fontScale) / sdfPx;
+
+ depthRange(strata, 1.0f);
+ (bucket.*drawSDF)(sdfShader);
+ }
+
+ // Then, we draw the text/icon over the halo
+ if (styleProperties.color[3] > 0.0f) {
+ sdfShader.u_gamma = gamma;
+
+ if (styleProperties.opacity < 1.0f) {
+ Color color = styleProperties.color;
+ color[0] *= styleProperties.opacity;
+ color[1] *= styleProperties.opacity;
+ color[2] *= styleProperties.opacity;
+ color[3] *= styleProperties.opacity;
+ sdfShader.u_color = color;
+ } else {
+ sdfShader.u_color = styleProperties.color;
+ }
+
+ sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f;
+
+ depthRange(strata + strata_epsilon, 1.0f);
+ (bucket.*drawSDF)(sdfShader);
+ }
+}
void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix) {
// Abort early.
@@ -20,197 +123,87 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> lay
glDisable(GL_STENCIL_TEST);
if (bucket.hasTextData()) {
- mat4 vtxMatrix = translatedMatrix(matrix, properties.text.translate, id, properties.text.translate_anchor);
-
- mat4 exMatrix;
- matrix::copy(exMatrix, projMatrix);
- if (bucket.properties.placement == PlacementType::Line) {
- matrix::rotate_z(exMatrix, exMatrix, map.getState().getAngle());
- }
-
- // If layerStyle.size > bucket.info.fontSize then labels may collide
- float fontSize = std::fmin(properties.text.size, bucket.properties.text.max_size);
- matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f);
-
- useProgram(textShader->program);
- textShader->setMatrix(vtxMatrix);
- textShader->setExtrudeMatrix(exMatrix);
-
GlyphAtlas &glyphAtlas = *map.getGlyphAtlas();
glyphAtlas.bind();
- textShader->setTextureSize(
- {{static_cast<float>(glyphAtlas.width), static_cast<float>(glyphAtlas.height)}});
-
- // Convert the -pi..pi to an int8 range.
- float angle = std::round((map.getState().getAngle()) / M_PI * 128);
-
- // adjust min/max zooms for variable font sies
- float zoomAdjust = log(fontSize / bucket.properties.text.max_size) / log(2);
-
- textShader->setAngle((int32_t)(angle + 256) % 256);
- textShader->setFlip(bucket.properties.placement == PlacementType::Line ? 1 : 0);
- textShader->setZoom((map.getState().getNormalizedZoom() - zoomAdjust) *
- 10); // current zoom level
-
- // Label fading
- const timestamp duration = 300_milliseconds;
- const timestamp currentTime = util::now();
-
- std::deque<FrameSnapshot> &history = frameHistory.history;
- if (history.size() >= 2) {
- // Remove frames until only one is outside the duration, or until there are only three
- while (history.size() > 3 && history[1].t + duration < currentTime) {
- history.pop_front();
- }
-
- if (history[1].t + duration < currentTime) {
- history[0].z = history[1].z;
- }
-
- // Find the range of zoom levels we want to fade between
- float startingZ = history.front().z;
- const FrameSnapshot lastFrame = history.back();
- float endingZ = lastFrame.z;
- float lowZ = std::fmin(startingZ, endingZ);
- float highZ = std::fmax(startingZ, endingZ);
-
- // Calculate the speed of zooming, and how far it would zoom in terms of zoom levels in one
- // duration
- float zoomDiff = endingZ - history[1].z, timeDiff = lastFrame.t - history[1].t;
- float fadedist = zoomDiff / (timeDiff / duration);
-
- // At end of a zoom when the zoom stops changing continue pretending to zoom at that speed
- // bump is how much farther it would have been if it had continued zooming at the same rate
- float bump = (currentTime - lastFrame.t) / duration * fadedist;
-
- textShader->setFadeDist(fadedist * 10);
- textShader->setMinFadeZoom(std::floor(lowZ * 10));
- textShader->setMaxFadeZoom(std::floor(highZ * 10));
- textShader->setFadeZoom((map.getState().getNormalizedZoom() + bump) * 10);
- }
-
- // This defines the gamma around the SDF cutoff value.
- const float sdfGamma = 1.0f / 10.0f;
-
- // Our signed distance fields are scaled so that 1 pixel is scaled to 32 pixels.
- // Our cutoff between positive and negative values is hard coded to 64 (== 2 pixels).
- // This means that our 6/8 of the value range lies outside the glyph outline.
- const float sdfOffset = (256.0f - 64.0f) / 32.0f;
-
- // Currently, all of our fonts are rendered with a font size of 24px.
- const float sdfFontSize = 24.0f;
-
- // The default gamma value has to be adjust for the current pixelratio so that we're not
- // drawing
- // blurry font on retina screens.
- const float gamma = sdfGamma * sdfFontSize / fontSize / map.getState().getPixelRatio();
-
- // We're drawing in the translucent pass which is bottom-to-top, so we need
- // to draw the halo first.
- if (properties.text.halo_color[3] > 0.0f) {
- const float haloWidth = util::clamp(
- (sdfOffset - properties.text.halo_width / (fontSize / sdfFontSize)) / 8.0f, 0.0f,
- 1.0f);
-
- if (properties.text.halo_blur != 0.0f) {
- // We are converting the halo_blur value to current screen pixels.
- // Then we're dividing it by two because the gamma value is added/subtracted into
- // both
- // directions in the shader, but the halo_blur describes the entire width of the
- // blur.
- // Note that this does *not* have to be adjusted for retina screens, because we want
- // the
- // same blur width when we explicitly specify one.
- textShader->setGamma((properties.text.halo_blur / (fontSize / sdfFontSize)) / 8.0f /
- 2.0f);
- } else {
- textShader->setGamma(sdfGamma);
- }
-
- if (properties.text.opacity < 1.0f) {
- Color color = properties.text.halo_color;
- color[0] *= properties.text.opacity;
- color[1] *= properties.text.opacity;
- color[2] *= properties.text.opacity;
- color[3] *= properties.text.opacity;
- textShader->setColor(color);
- } else {
- textShader->setColor(properties.text.halo_color);
- }
- textShader->setBuffer(haloWidth);
- depthRange(strata, 1.0f);
- bucket.drawGlyphs(*textShader);
- }
- if (properties.text.color[3] > 0.0f) {
- // Then, we draw the text over the halo
- textShader->setGamma(gamma);
- if (properties.text.opacity < 1.0f) {
- Color color = properties.text.color;
- color[0] *= properties.text.opacity;
- color[1] *= properties.text.opacity;
- color[2] *= properties.text.opacity;
- color[3] *= properties.text.opacity;
- textShader->setColor(color);
- } else {
- textShader->setColor(properties.text.color);
- }
- textShader->setBuffer((256.0f - 64.0f) / 256.0f);
- depthRange(strata + strata_epsilon, 1.0f);
- bucket.drawGlyphs(*textShader);
- }
+ renderSDF(bucket,
+ id,
+ matrix,
+ bucket.properties.text,
+ properties.text,
+ 24.0f,
+ {{ float(glyphAtlas.width) / 4, float(glyphAtlas.height) / 4 }},
+ *sdfGlyphShader,
+ &SymbolBucket::drawGlyphs);
}
if (bucket.hasIconData()) {
- mat4 vtxMatrix = translatedMatrix(matrix, properties.icon.translate, id, properties.icon.translate_anchor);
-
- mat4 exMatrix;
- matrix::copy(exMatrix, projMatrix);
+ bool sdf = bucket.sdfIcons;
const float angleOffset =
bucket.properties.icon.rotation_alignment == RotationAlignmentType::Map
? map.getState().getAngle()
: 0;
- if (angleOffset) {
- matrix::rotate_z(exMatrix, exMatrix, angleOffset);
- }
-
// If layerStyle.size > bucket.info.fontSize then labels may collide
const float fontSize = properties.icon.size != 0 ? properties.icon.size : bucket.properties.icon.max_size;
const float fontScale = fontSize / 1.0f;
- matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f);
-
- useProgram(iconShader->program);
- iconShader->setMatrix(vtxMatrix);
- iconShader->setExtrudeMatrix(exMatrix);
SpriteAtlas &spriteAtlas = *map.getSpriteAtlas();
- spriteAtlas.bind(map.getState().isChanging() || bucket.properties.placement == PlacementType::Line || angleOffset != 0 || fontScale != 1);
- iconShader->setTextureSize(
- {{static_cast<float>(spriteAtlas.getWidth()), static_cast<float>(spriteAtlas.getHeight())}});
+ spriteAtlas.bind(map.getState().isChanging() || bucket.properties.placement == PlacementType::Line || angleOffset != 0 || fontScale != 1 || sdf);
+
+ std::array<float, 2> texsize = {{
+ float(spriteAtlas.getWidth()),
+ float(spriteAtlas.getHeight())
+ }};
+
+ if (sdf) {
+ renderSDF(bucket,
+ id,
+ matrix,
+ bucket.properties.icon,
+ properties.icon,
+ 1.0f,
+ texsize,
+ *sdfIconShader,
+ &SymbolBucket::drawIcons);
+ } else {
+ mat4 vtxMatrix = translatedMatrix(matrix, properties.icon.translate, id, properties.icon.translate_anchor);
+
+ mat4 exMatrix;
+ matrix::copy(exMatrix, projMatrix);
+
+ if (angleOffset) {
+ matrix::rotate_z(exMatrix, exMatrix, angleOffset);
+ }
- // Convert the -pi..pi to an int8 range.
- const float angle = std::round((map.getState().getAngle()) / M_PI * 128);
+ matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f);
- // adjust min/max zooms for variable font sies
- float zoomAdjust = log(fontSize / bucket.properties.icon.max_size) / log(2);
+ useProgram(iconShader->program);
+ iconShader->u_matrix = vtxMatrix;
+ iconShader->u_exmatrix = exMatrix;
+ iconShader->u_texsize = texsize;
- iconShader->setAngle((int32_t)(angle + 256) % 256);
- iconShader->setFlip(bucket.properties.placement == PlacementType::Line ? 1 : 0);
- iconShader->setZoom((map.getState().getNormalizedZoom() - zoomAdjust) *
- 10); // current zoom level
+ // Convert the -pi..pi to an int8 range.
+ const float angle = std::round(map.getState().getAngle() / M_PI * 128);
- iconShader->setFadeDist(0 * 10);
- iconShader->setMinFadeZoom(map.getState().getNormalizedZoom() * 10);
- iconShader->setMaxFadeZoom(map.getState().getNormalizedZoom() * 10);
- iconShader->setFadeZoom(map.getState().getNormalizedZoom() * 10);
- iconShader->setOpacity(properties.icon.opacity);
+ // adjust min/max zooms for variable font sies
+ float zoomAdjust = std::log(fontSize / bucket.properties.icon.max_size) / std::log(2);
- depthRange(strata, 1.0f);
- bucket.drawIcons(*iconShader);
+ iconShader->u_angle = (int32_t)(angle + 256) % 256;
+ iconShader->u_flip = bucket.properties.placement == PlacementType::Line ? 1 : 0;
+ iconShader->u_zoom = (map.getState().getNormalizedZoom() - zoomAdjust) * 10; // current zoom level
+
+ iconShader->u_fadedist = 0 * 10;
+ iconShader->u_minfadezoom = map.getState().getNormalizedZoom() * 10;
+ iconShader->u_maxfadezoom = map.getState().getNormalizedZoom() * 10;
+ iconShader->u_fadezoom = map.getState().getNormalizedZoom() * 10;
+ iconShader->u_opacity = properties.icon.opacity;
+
+ depthRange(strata, 1.0f);
+ bucket.drawIcons(*iconShader);
+ }
}
glEnable(GL_STENCIL_TEST);
}
-}
diff --git a/src/renderer/prerendered_texture.cpp b/src/renderer/prerendered_texture.cpp
index 52f7edc50b..0a47816323 100644
--- a/src/renderer/prerendered_texture.cpp
+++ b/src/renderer/prerendered_texture.cpp
@@ -110,8 +110,8 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) {
painter.useProgram(painter.gaussianShader->program);
- painter.gaussianShader->setMatrix(painter.flipMatrix);
- painter.gaussianShader->setImage(0);
+ painter.gaussianShader->u_matrix = painter.flipMatrix;
+ painter.gaussianShader->u_image = 0;
glActiveTexture(GL_TEXTURE0);
for (int i = 0; i < passes; i++) {
@@ -123,7 +123,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) {
#endif
glClear(GL_COLOR_BUFFER_BIT);
- painter.gaussianShader->setOffset({{ 1.0f / float(properties.size), 0 }});
+ painter.gaussianShader->u_offset = {{ 1.0f / float(properties.size), 0 }};
glBindTexture(GL_TEXTURE_2D, original_texture);
painter.coveringGaussianArray.bind(*painter.gaussianShader, painter.tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)painter.tileStencilBuffer.index());
@@ -137,7 +137,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) {
#endif
glClear(GL_COLOR_BUFFER_BIT);
- painter.gaussianShader->setOffset({{ 0, 1.0f / float(properties.size) }});
+ painter.gaussianShader->u_offset = {{ 0, 1.0f / float(properties.size) }};
glBindTexture(GL_TEXTURE_2D, secondary_texture);
painter.coveringGaussianArray.bind(*painter.gaussianShader, painter.tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)painter.tileStencilBuffer.index());
diff --git a/src/renderer/raster_bucket.cpp b/src/renderer/raster_bucket.cpp
index 10dadc03fc..492eea980d 100644
--- a/src/renderer/raster_bucket.cpp
+++ b/src/renderer/raster_bucket.cpp
@@ -19,14 +19,14 @@ bool RasterBucket::setImage(const std::string &data) {
void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array) {
raster.bind(true);
- shader.setImage(0);
+ shader.u_image = 0;
array.bind(shader, vertices, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index());
}
void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, GLuint texture) {
raster.bind(texture);
- shader.setImage(0);
+ shader.u_image = 0;
array.bind(shader, vertices, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index());
}
diff --git a/src/renderer/symbol_bucket.cpp b/src/renderer/symbol_bucket.cpp
index fd89315096..374ea2dc26 100644
--- a/src/renderer/symbol_bucket.cpp
+++ b/src/renderer/symbol_bucket.cpp
@@ -158,6 +158,10 @@ void SymbolBucket::addFeatures(const VectorTileLayer &layer, const FilterExpress
// if feature has icon, get sprite atlas position
if (feature.sprite.length()) {
image = spriteAtlas.waitForImage(feature.sprite, sprite);
+
+ if (sprite.getSpritePosition(feature.sprite).sdf) {
+ sdfIcons = true;
+ }
}
// if either shaping or icon position is present, add the feature
@@ -351,7 +355,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.
- TextElementGroup &triangleGroup = buffer.groups.back();
+ auto &triangleGroup = buffer.groups.back();
uint32_t triangleIndex = triangleGroup.vertex_length;
// coordinates (2 triangles)
@@ -373,7 +377,7 @@ void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float
}
}
-void SymbolBucket::drawGlyphs(TextShader &shader) {
+void SymbolBucket::drawGlyphs(SDFShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
for (TextElementGroup &group : text.groups) {
@@ -384,7 +388,7 @@ void SymbolBucket::drawGlyphs(TextShader &shader) {
}
}
-void SymbolBucket::drawIcons(IconShader &shader) {
+void SymbolBucket::drawIcons(SDFShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
for (IconElementGroup &group : icon.groups) {
@@ -394,4 +398,15 @@ void SymbolBucket::drawIcons(IconShader &shader) {
elements_index += group.elements_length * icon.triangles.itemSize;
}
}
+
+void SymbolBucket::drawIcons(IconShader &shader) {
+ char *vertex_index = BUFFER_OFFSET(0);
+ char *elements_index = BUFFER_OFFSET(0);
+ for (IconElementGroup &group : icon.groups) {
+ group.array[1].bind(shader, icon.vertices, icon.triangles, vertex_index);
+ glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index);
+ vertex_index += group.vertex_length * icon.vertices.itemSize;
+ elements_index += group.elements_length * icon.triangles.itemSize;
+ }
+}
}
diff --git a/src/shader/dot.fragment.glsl b/src/shader/dot.fragment.glsl
index 3f1d5a234a..6d998b5611 100644
--- a/src/shader/dot.fragment.glsl
+++ b/src/shader/dot.fragment.glsl
@@ -2,8 +2,8 @@ uniform vec4 u_color;
uniform float u_blur;
void main() {
- float dist = length(gl_PointCoord - 0.5);
- float t = smoothstep(0.5, 0.5 - u_blur, dist);
+ float dist = length(gl_PointCoord - 0.5);
+ float t = smoothstep(0.5, 0.5 - u_blur, dist);
gl_FragColor = u_color * t;
}
diff --git a/src/shader/dot.vertex.glsl b/src/shader/dot.vertex.glsl
index a0d64c33b1..5310ae745e 100644
--- a/src/shader/dot.vertex.glsl
+++ b/src/shader/dot.vertex.glsl
@@ -1,8 +1,8 @@
-attribute vec2 a_pos;
-
uniform mat4 u_matrix;
uniform float u_size;
+attribute vec2 a_pos;
+
void main(void) {
gl_Position = u_matrix * vec4(a_pos, 0, 1);
gl_PointSize = u_size;
diff --git a/src/shader/dot_shader.cpp b/src/shader/dot_shader.cpp
index 54163d6982..a897f410a7 100644
--- a/src/shader/dot_shader.cpp
+++ b/src/shader/dot_shader.cpp
@@ -18,41 +18,9 @@ DotShader::DotShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_color = glGetUniformLocation(program, "u_color");
- u_size = glGetUniformLocation(program, "u_size");
- u_blur = glGetUniformLocation(program, "u_blur");
-
- // fprintf(stderr, "DotShader:\n");
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_color: %d\n", u_color);
- // fprintf(stderr, " - u_size: %d\n", u_size);
- // fprintf(stderr, " - u_blur: %d\n", u_blur);
}
void DotShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
}
-
-void DotShader::setColor(const std::array<float, 4>& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void DotShader::setSize(float new_size) {
- if (size != new_size) {
- glUniform1f(u_size, new_size);
- size = new_size;
- }
-}
-
-void DotShader::setBlur(float new_blur) {
- if (blur != new_blur) {
- glUniform1f(u_blur, new_blur);
- blur = new_blur;
- }
-}
diff --git a/src/shader/gaussian.fragment.glsl b/src/shader/gaussian.fragment.glsl
index e29afc0a82..ee8406e9e1 100644
--- a/src/shader/gaussian.fragment.glsl
+++ b/src/shader/gaussian.fragment.glsl
@@ -2,11 +2,10 @@ uniform sampler2D u_image;
varying vec2 v_coords[3];
-void main()
-{
+void main() {
vec4 sum = vec4(0.0);
sum += texture2D(u_image, v_coords[0]) * 0.40261994689424746;
sum += texture2D(u_image, v_coords[1]) * 0.2986900265528763;
sum += texture2D(u_image, v_coords[2]) * 0.2986900265528763;
gl_FragColor = sum;
-} \ No newline at end of file
+}
diff --git a/src/shader/gaussian.vertex.glsl b/src/shader/gaussian.vertex.glsl
index 320d48f23d..26a8394204 100644
--- a/src/shader/gaussian.vertex.glsl
+++ b/src/shader/gaussian.vertex.glsl
@@ -8,7 +8,7 @@ varying vec2 v_coords[3];
void main() {
gl_Position = u_matrix * vec4(a_pos, 0, 1);
- vec2 tex = (gl_Position.xy + 1.0) / 2.0;
+ vec2 tex = gl_Position.xy / 2.0 + 0.5;
v_coords[0] = tex;
v_coords[1] = tex + u_offset * 1.1824255238063563;
v_coords[2] = tex - u_offset * 1.1824255238063563;
diff --git a/src/shader/gaussian_shader.cpp b/src/shader/gaussian_shader.cpp
index d22006020c..9060f0ee71 100644
--- a/src/shader/gaussian_shader.cpp
+++ b/src/shader/gaussian_shader.cpp
@@ -20,32 +20,9 @@ GaussianShader::GaussianShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_image = glGetUniformLocation(program, "u_image");
- u_offset = glGetUniformLocation(program, "u_offset");
-
- // fprintf(stderr, "GaussianShader:\n");
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_image: %d\n", u_image);
- // fprintf(stderr, " - u_gaussian: %f\n", u_gaussian);
}
void GaussianShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
-
-void GaussianShader::setImage(int32_t new_image) {
- if (image != new_image) {
- glUniform1i(u_image, new_image);
- image = new_image;
- }
-}
-
-void GaussianShader::setOffset(const std::array<float, 2>& new_offset) {
- if (offset != new_offset) {
- glUniform2fv(u_offset, 1, new_offset.data());
- offset = new_offset;
- }
-}
diff --git a/src/shader/icon.fragment.glsl b/src/shader/icon.fragment.glsl
index 6e8130ef1e..45b56793eb 100644
--- a/src/shader/icon.fragment.glsl
+++ b/src/shader/icon.fragment.glsl
@@ -4,7 +4,5 @@ varying vec2 v_tex;
varying float v_alpha;
void main() {
- // Note: We don't need to premultiply here as the image we use is already
- // premultiplied in the sprite atlas.
gl_FragColor = texture2D(u_texture, v_tex) * v_alpha;
}
diff --git a/src/shader/icon.vertex.glsl b/src/shader/icon.vertex.glsl
index f8d94a2639..8c69c40410 100644
--- a/src/shader/icon.vertex.glsl
+++ b/src/shader/icon.vertex.glsl
@@ -9,7 +9,7 @@ attribute float a_rangestart;
attribute float a_labelminzoom;
-// posmatrix is for the vertex position, exmatrix is for rotating and projecting
+// matrix is for the vertex position, exmatrix is for rotating and projecting
// the extrusion vector.
uniform mat4 u_matrix;
uniform mat4 u_exmatrix;
diff --git a/src/shader/icon_shader.cpp b/src/shader/icon_shader.cpp
index 4973dc4119..5c54177eb6 100644
--- a/src/shader/icon_shader.cpp
+++ b/src/shader/icon_shader.cpp
@@ -26,30 +26,6 @@ IconShader::IconShader()
a_rangeend = glGetAttribLocation(program, "a_rangeend");
a_rangestart = glGetAttribLocation(program, "a_rangestart");
a_labelminzoom = glGetAttribLocation(program, "a_labelminzoom");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
- u_angle = glGetUniformLocation(program, "u_angle");
- u_zoom = glGetUniformLocation(program, "u_zoom");
- u_flip = glGetUniformLocation(program, "u_flip");
- u_fadedist = glGetUniformLocation(program, "u_fadedist");
- u_minfadezoom = glGetUniformLocation(program, "u_minfadezoom");
- u_maxfadezoom = glGetUniformLocation(program, "u_maxfadezoom");
- u_fadezoom = glGetUniformLocation(program, "u_fadezoom");
- u_opacity = glGetUniformLocation(program, "u_opacity");
- u_texsize = glGetUniformLocation(program, "u_texsize");
-
- // fprintf(stderr, "IconShader:\n");
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_exmatrix: %d\n", u_exmatrix);
- // fprintf(stderr, " - u_angle: %d\n", u_angle);
- // fprintf(stderr, " - u_zoom: %d\n", u_zoom);
- // fprintf(stderr, " - u_flip: %d\n", u_flip);
- // fprintf(stderr, " - u_fadedist: %d\n", u_fadedist);
- // fprintf(stderr, " - u_minfadezoom: %d\n", u_minfadezoom);
- // fprintf(stderr, " - u_maxfadezoom: %d\n", u_maxfadezoom);
- // fprintf(stderr, " - u_fadezoom: %d\n", u_fadezoom);
- // fprintf(stderr, " - u_opacity: %d\n", u_opacity);
}
void IconShader::bind(char *offset) {
@@ -82,74 +58,3 @@ void IconShader::bind(char *offset) {
glEnableVertexAttribArray(a_tex);
glVertexAttribPointer(a_tex, 2, GL_SHORT, false, stride, offset + 16);
}
-
-void IconShader::setExtrudeMatrix(const std::array<float, 16>& new_exmatrix) {
- if (exmatrix != new_exmatrix) {
- glUniformMatrix4fv(u_exmatrix, 1, GL_FALSE, new_exmatrix.data());
- exmatrix = new_exmatrix;
- }
-}
-
-void IconShader::setAngle(float new_angle) {
- if (angle != new_angle) {
- glUniform1f(u_angle, new_angle);
- angle = new_angle;
- }
-}
-
-void IconShader::setZoom(float new_zoom) {
- if (zoom != new_zoom) {
- glUniform1f(u_zoom, new_zoom);
- zoom = new_zoom;
- }
-}
-
-void IconShader::setFlip(float new_flip) {
- if (flip != new_flip) {
- glUniform1f(u_flip, new_flip);
- flip = new_flip;
- }
-}
-
-void IconShader::setFadeDist(float new_fadedist) {
- if (fadedist != new_fadedist) {
- glUniform1f(u_fadedist, new_fadedist);
- fadedist = new_fadedist;
- }
-}
-
-void IconShader::setMinFadeZoom(float new_minfadezoom) {
- if (minfadezoom != new_minfadezoom) {
- glUniform1f(u_minfadezoom, new_minfadezoom);
- minfadezoom = new_minfadezoom;
- }
-}
-
-void IconShader::setMaxFadeZoom(float new_maxfadezoom) {
- if (maxfadezoom != new_maxfadezoom) {
- glUniform1f(u_maxfadezoom, new_maxfadezoom);
- maxfadezoom = new_maxfadezoom;
- }
-}
-
-void IconShader::setFadeZoom(float new_fadezoom) {
- if (fadezoom != new_fadezoom) {
- glUniform1f(u_fadezoom, new_fadezoom);
- fadezoom = new_fadezoom;
- }
-}
-
-void IconShader::setOpacity(float new_opacity) {
- if (opacity != new_opacity) {
- glUniform1f(u_opacity, new_opacity);
- opacity = new_opacity;
- }
-}
-
-void IconShader::setTextureSize(const std::array<float, 2> &new_texsize) {
- if (texsize != new_texsize) {
- glUniform2fv(u_texsize, 1, new_texsize.data());
- texsize = new_texsize;
- }
-}
-
diff --git a/src/shader/line.vertex.glsl b/src/shader/line.vertex.glsl
index 14be3c4ebb..1d8e687c95 100644
--- a/src/shader/line.vertex.glsl
+++ b/src/shader/line.vertex.glsl
@@ -10,7 +10,7 @@ attribute vec2 a_pos;
attribute vec2 a_extrude;
attribute float a_linesofar;
-// posmatrix is for the vertex position, exmatrix is for rotating and projecting
+// matrix is for the vertex position, exmatrix is for rotating and projecting
// the extrusion vector.
uniform mat4 u_matrix;
uniform mat4 u_exmatrix;
@@ -42,4 +42,4 @@ void main() {
// tile's zoom level.
gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0.0, 1.0) + u_exmatrix * dist;
v_linesofar = a_linesofar * u_ratio;
-} \ No newline at end of file
+}
diff --git a/src/shader/line_shader.cpp b/src/shader/line_shader.cpp
index 1b0527366e..8353f4c6ca 100644
--- a/src/shader/line_shader.cpp
+++ b/src/shader/line_shader.cpp
@@ -20,22 +20,6 @@ LineShader::LineShader()
a_pos = glGetAttribLocation(program, "a_pos");
a_extrude = glGetAttribLocation(program, "a_extrude");
a_linesofar = glGetAttribLocation(program, "a_linesofar");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
- u_linewidth = glGetUniformLocation(program, "u_linewidth");
- u_color = glGetUniformLocation(program, "u_color");
- u_ratio = glGetUniformLocation(program, "u_ratio");
- u_dasharray = glGetUniformLocation(program, "u_dasharray");
- u_blur = glGetUniformLocation(program, "u_blur");
-
- // fprintf(stderr, "LineShader:\n");
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_exmatrix: %d\n", u_exmatrix);
- // fprintf(stderr, " - u_linewidth: %d\n", u_linewidth);
- // fprintf(stderr, " - u_color: %d\n", u_color);
- // fprintf(stderr, " - u_ratio: %d\n", u_ratio);
- // fprintf(stderr, " - u_dasharray: %d\n", u_dasharray);
}
void LineShader::bind(char *offset) {
@@ -48,45 +32,3 @@ void LineShader::bind(char *offset) {
glEnableVertexAttribArray(a_linesofar);
glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 6);
}
-
-void LineShader::setExtrudeMatrix(const std::array<float, 16>& new_exmatrix) {
- if (exmatrix != new_exmatrix) {
- glUniformMatrix4fv(u_exmatrix, 1, GL_FALSE, new_exmatrix.data());
- exmatrix = new_exmatrix;
- }
-}
-
-void LineShader::setColor(const std::array<float, 4>& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void LineShader::setLineWidth(const std::array<float, 2>& new_linewidth) {
- if (linewidth != new_linewidth) {
- glUniform2fv(u_linewidth, 1, new_linewidth.data());
- linewidth = new_linewidth;
- }
-}
-
-void LineShader::setRatio(float new_ratio) {
- if (ratio != new_ratio) {
- glUniform1f(u_ratio, new_ratio);
- ratio = new_ratio;
- }
-}
-
-void LineShader::setDashArray(const std::array<float, 2>& new_dasharray) {
- if (dasharray != new_dasharray) {
- glUniform2fv(u_dasharray, 1, new_dasharray.data());
- dasharray = new_dasharray;
- }
-}
-
-void LineShader::setBlur(float new_blur) {
- if (blur != new_blur) {
- glUniform1f(u_blur, new_blur);
- blur = new_blur;
- }
-}
diff --git a/src/shader/linejoin_shader.cpp b/src/shader/linejoin_shader.cpp
index e8ec306ed9..050e180e00 100644
--- a/src/shader/linejoin_shader.cpp
+++ b/src/shader/linejoin_shader.cpp
@@ -18,19 +18,6 @@ LinejoinShader::LinejoinShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_world = glGetUniformLocation(program, "u_world");
- u_linewidth = glGetUniformLocation(program, "u_linewidth");
- u_color = glGetUniformLocation(program, "u_color");
- u_size = glGetUniformLocation(program, "u_size");
-
- // fprintf(stderr, "LinejoinShader:\n");
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_world: %d\n", u_world);
- // fprintf(stderr, " - u_linewidth: %d\n", u_linewidth);
- // fprintf(stderr, " - u_color: %d\n", u_color);
- // fprintf(stderr, " - u_size: %d\n", u_size);
}
void LinejoinShader::bind(char *offset) {
@@ -38,31 +25,3 @@ void LinejoinShader::bind(char *offset) {
// Note: We're referring to the vertices in a line array, which are 8 bytes long!
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
}
-
-void LinejoinShader::setColor(const std::array<float, 4>& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void LinejoinShader::setWorld(const std::array<float, 2>& new_world) {
- if (world != new_world) {
- glUniform2fv(u_world, 1, new_world.data());
- world = new_world;
- }
-}
-
-void LinejoinShader::setLineWidth(const std::array<float, 2>& new_linewidth) {
- if (linewidth != new_linewidth) {
- glUniform2fv(u_linewidth, 1, new_linewidth.data());
- linewidth = new_linewidth;
- }
-}
-
-void LinejoinShader::setSize(float new_size) {
- if (size != new_size) {
- glUniform1f(u_size, new_size);
- size = new_size;
- }
-}
diff --git a/src/shader/linepattern.fragment.glsl b/src/shader/linepattern.fragment.glsl
new file mode 100644
index 0000000000..52ca823a3b
--- /dev/null
+++ b/src/shader/linepattern.fragment.glsl
@@ -0,0 +1,37 @@
+uniform vec2 u_linewidth;
+uniform float u_point;
+uniform float u_blur;
+
+uniform vec2 u_pattern_size;
+uniform vec2 u_pattern_tl;
+uniform vec2 u_pattern_br;
+uniform float u_fade;
+
+uniform sampler2D u_image;
+
+varying vec2 v_normal;
+varying float v_linesofar;
+
+void main() {
+ // Calculate the distance of the pixel from the line in pixels.
+ float dist = length(v_normal) * (1.0 - u_point) + u_point * length(gl_PointCoord * 2.0 - 1.0);
+
+ dist *= u_linewidth.s;
+
+ // Calculate the antialiasing fade factor. This is either when fading in
+ // the line in case of an offset line (v_linewidth.t) or when fading out
+ // (v_linewidth.s)
+ float alpha = clamp(min(dist - (u_linewidth.t - u_blur), u_linewidth.s - dist) / u_blur, 0.0, 1.0);
+
+ float x = mod(v_linesofar / u_pattern_size.x, 1.0);
+ float y = 0.5 + (v_normal.y * u_linewidth.s / u_pattern_size.y);
+ vec2 pos = mix(u_pattern_tl, u_pattern_br, vec2(x, y));
+ float x2 = mod(x * 2.0, 1.0);
+ vec2 pos2 = mix(u_pattern_tl, u_pattern_br, vec2(x2, y));
+
+ vec4 color = texture2D(u_image, pos) * (1.0 - u_fade) + u_fade * texture2D(u_image, pos2);
+
+ color.rgb *= color.a; // premultiply
+
+ gl_FragColor = color * alpha;
+}
diff --git a/src/shader/linepattern.vertex.glsl b/src/shader/linepattern.vertex.glsl
new file mode 100644
index 0000000000..4600ebf65b
--- /dev/null
+++ b/src/shader/linepattern.vertex.glsl
@@ -0,0 +1,57 @@
+// floor(127 / 2) == 63.0
+// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
+// stored in a byte (-128..127). we scale regular normals up to length 63, but
+// there are also "special" normals that have a bigger length (of up to 126 in
+// this case).
+#define scale 63.0
+
+attribute vec2 a_pos;
+attribute vec2 a_extrude;
+attribute float a_linesofar;
+
+// matrix is for the vertex position, exmatrix is for rotating and projecting
+// the extrusion vector.
+uniform mat4 u_matrix;
+uniform mat4 u_exmatrix;
+
+// shared
+uniform float u_ratio;
+uniform vec2 u_linewidth;
+uniform vec4 u_color;
+uniform float u_point;
+
+varying vec2 v_normal;
+varying float v_linesofar;
+
+void main() {
+ // We store the texture normals in the most insignificant bit
+ // transform y so that 0 => -1 and 1 => 1
+ // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap
+ // y is 1 if the normal points up, and -1 if it points down
+ vec2 normal = mod(a_pos, 2.0);
+ normal.y = sign(normal.y - 0.5);
+ v_normal = normal;
+
+ // Scale the extrusion vector down to a normal and then up by the line width
+ // of this vertex.
+ vec2 extrude = a_extrude / scale;
+ vec2 dist = u_linewidth.s * extrude * (1.0 - u_point);
+
+ // If the x coordinate is the maximum integer, we move the z coordinates out
+ // of the view plane so that the triangle gets clipped. This makes it easier
+ // for us to create degenerate triangle strips.
+ float z = step(32767.0, a_pos.x);
+
+ // When drawing points, skip every other vertex
+ z += u_point * step(1.0, v_normal.y);
+
+ // Remove the texture normal bit of the position before scaling it with the
+ // model/view matrix. Add the extrusion vector *after* the model/view matrix
+ // because we're extruding the line in pixel space, regardless of the current
+ // tile's zoom level.
+ gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0) + u_exmatrix * vec4(dist, z, 0.0);
+ v_linesofar = a_linesofar;// * u_ratio;
+
+
+ gl_PointSize = 2.0 * u_linewidth.s - 1.0;
+}
diff --git a/src/shader/linepattern_shader.cpp b/src/shader/linepattern_shader.cpp
new file mode 100644
index 0000000000..954dbd2b3f
--- /dev/null
+++ b/src/shader/linepattern_shader.cpp
@@ -0,0 +1,35 @@
+#include <mbgl/shader/linepattern_shader.hpp>
+#include <mbgl/shader/shaders.hpp>
+#include <mbgl/platform/gl.hpp>
+#include <iostream>
+
+#include <cstdio>
+
+using namespace mbgl;
+
+LinepatternShader::LinepatternShader()
+ : Shader(
+ "linepattern",
+ shaders[LINEPATTERN_SHADER].vertex,
+ shaders[LINEPATTERN_SHADER].fragment
+ ) {
+ if (!valid) {
+ fprintf(stderr, "invalid line pattern shader\n");
+ return;
+ }
+
+ a_pos = glGetAttribLocation(program, "a_pos");
+ a_extrude = glGetAttribLocation(program, "a_extrude");
+ a_linesofar = glGetAttribLocation(program, "a_linesofar");
+}
+
+void LinepatternShader::bind(char *offset) {
+ glEnableVertexAttribArray(a_pos);
+ glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0);
+
+ glEnableVertexAttribArray(a_extrude);
+ glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 4);
+
+ glEnableVertexAttribArray(a_linesofar);
+ glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 6);
+}
diff --git a/src/shader/outline_shader.cpp b/src/shader/outline_shader.cpp
index d9c19fa805..ddabfa5d0d 100644
--- a/src/shader/outline_shader.cpp
+++ b/src/shader/outline_shader.cpp
@@ -18,32 +18,9 @@ OutlineShader::OutlineShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_color = glGetUniformLocation(program, "u_color");
- u_world = glGetUniformLocation(program, "u_world");
-
- // fprintf(stderr, "OutlineShader:\n");
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_color: %d\n", u_color);
- // fprintf(stderr, " - u_world: %d\n", u_world);
}
void OutlineShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
-
-void OutlineShader::setColor(const std::array<float, 4>& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void OutlineShader::setWorld(const std::array<float, 2>& new_world) {
- if (world != new_world) {
- glUniform2fv(u_world, 1, new_world.data());
- world = new_world;
- }
-}
diff --git a/src/shader/pattern_shader.cpp b/src/shader/pattern_shader.cpp
index 8fe6a34e93..31374bc3e8 100644
--- a/src/shader/pattern_shader.cpp
+++ b/src/shader/pattern_shader.cpp
@@ -18,69 +18,9 @@ PatternShader::PatternShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- 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_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) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
-
-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());
- pattern_tl = new_pattern_tl;
- }
-}
-
-void PatternShader::setPatternBottomRight(const std::array<float, 2>& new_pattern_br) {
- if (pattern_br != new_pattern_br) {
- glUniform2fv(u_pattern_br, 1, new_pattern_br.data());
- pattern_br = new_pattern_br;
- }
-}
-
-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);
- mix = new_mix;
- }
-}
-
-void PatternShader::setPatternMatrix(const std::array<float, 9>& new_patternmatrix) {
- if (patternmatrix != new_patternmatrix) {
- glUniformMatrix3fv(u_patternmatrix, 1, GL_FALSE, new_patternmatrix.data());
- patternmatrix = new_patternmatrix;
- }
-}
-
diff --git a/src/shader/plain_shader.cpp b/src/shader/plain_shader.cpp
index bb0c228992..8a37837b30 100644
--- a/src/shader/plain_shader.cpp
+++ b/src/shader/plain_shader.cpp
@@ -18,28 +18,9 @@ PlainShader::PlainShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_color = glGetUniformLocation(program, "u_color");
-
- // fprintf(stderr, "PlainShader:\n");
- // fprintf(stderr, " - a_pos: %d\n", a_pos);
- // fprintf(stderr, " - u_matrix: %d\n", u_matrix);
- // fprintf(stderr, " - u_color: %d\n", u_color);
}
void PlainShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
-
-void PlainShader::setColor(const std::array<float, 4>& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void PlainShader::setColor(float r, float g, float b, float a) {
- setColor({{ r, g, b, a }});
-}
diff --git a/src/shader/raster.fragment.glsl b/src/shader/raster.fragment.glsl
index d56a5b5901..333de76dc1 100644
--- a/src/shader/raster.fragment.glsl
+++ b/src/shader/raster.fragment.glsl
@@ -17,9 +17,9 @@ void main() {
// spin
rgb = vec3(
- dot(rgb, u_spin_weights.xyz),
- dot(rgb, u_spin_weights.zxy),
- dot(rgb, u_spin_weights.yzx));
+ dot(rgb, u_spin_weights.xyz),
+ dot(rgb, u_spin_weights.zxy),
+ dot(rgb, u_spin_weights.yzx));
// saturation
float average = (color.r + color.g + color.b) / 3.0;
diff --git a/src/shader/raster_shader.cpp b/src/shader/raster_shader.cpp
index 60d81c61bd..7351f7d0c4 100644
--- a/src/shader/raster_shader.cpp
+++ b/src/shader/raster_shader.cpp
@@ -20,88 +20,9 @@ RasterShader::RasterShader()
}
a_pos = glGetAttribLocation(program, "a_pos");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_image = glGetUniformLocation(program, "u_image");
- u_opacity = glGetUniformLocation(program, "u_opacity");
- u_buffer = glGetUniformLocation(program, "u_buffer");
- u_brightness_low = glGetUniformLocation(program, "u_brightness_low");
- u_brightness_high = glGetUniformLocation(program, "u_brightness_high");
- u_saturation_factor = glGetUniformLocation(program, "u_saturation_factor");
- u_contrast_factor = glGetUniformLocation(program, "u_contrast_factor");
- u_spin_weights = glGetUniformLocation(program, "u_spin_weights");
-
- // fprintf(stderr, "RasterShader:\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);
- // fprintf(stderr, " - u_buffer: %f\n", u_buffer);
}
void RasterShader::bind(char *offset) {
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
}
-
-void RasterShader::setImage(int32_t new_image) {
- if (image != new_image) {
- glUniform1i(u_image, new_image);
- image = new_image;
- }
-}
-
-void RasterShader::setOpacity(float new_opacity) {
- if (opacity != new_opacity) {
- glUniform1f(u_opacity, new_opacity);
- opacity = new_opacity;
- }
-}
-
-void RasterShader::setBuffer(float new_buffer) {
- if (buffer != new_buffer) {
- glUniform1f(u_buffer, new_buffer);
- buffer = new_buffer;
- }
-}
-
-void RasterShader::setBrightness(float new_brightness_low, float new_brightness_high) {
- if (brightness_low != new_brightness_low) {
- glUniform1f(u_brightness_low, new_brightness_low);
- brightness_low = new_brightness_low;
- }
- if (brightness_high != new_brightness_high) {
- glUniform1f(u_brightness_high, new_brightness_high);
- brightness_high = new_brightness_high;
- }
-}
-
-void RasterShader::setSaturation(float new_saturation_factor) {
- if (saturation_factor != new_saturation_factor) {
- if (new_saturation_factor > 0) {
- new_saturation_factor = 1 - 1 / (1.001 - new_saturation_factor);
- } else {
- new_saturation_factor = -new_saturation_factor;
- }
- glUniform1f(u_saturation_factor, new_saturation_factor);
- saturation_factor = new_saturation_factor;
- }
-}
-
-void RasterShader::setContrast(float new_contrast_factor) {
- if (contrast_factor != new_contrast_factor) {
- if (new_contrast_factor > 0) {
- new_contrast_factor = 1 / (1 - new_contrast_factor);
- } else {
- new_contrast_factor = 1 + new_contrast_factor;
- }
- glUniform1f(u_contrast_factor, new_contrast_factor);
- contrast_factor = new_contrast_factor;
- }
-}
-
-void RasterShader::setSpin(std::array<float, 3> new_spin_weights) {
- if (spin_weights != new_spin_weights) {
- glUniform3fv(u_spin_weights, 1, new_spin_weights.data());
- spin_weights = new_spin_weights;
- }
-} \ No newline at end of file
diff --git a/src/shader/text.fragment.glsl b/src/shader/sdf.fragment.glsl
index d72d61dab1..d72d61dab1 100644
--- a/src/shader/text.fragment.glsl
+++ b/src/shader/sdf.fragment.glsl
diff --git a/src/shader/text.vertex.glsl b/src/shader/sdf.vertex.glsl
index 86cbec98ed..c5166ae46f 100644
--- a/src/shader/text.vertex.glsl
+++ b/src/shader/sdf.vertex.glsl
@@ -1,10 +1,15 @@
attribute vec2 a_pos;
attribute vec2 a_offset;
-attribute vec4 a_data1;
-attribute vec4 a_data2;
+attribute vec2 a_tex;
+attribute float a_angle;
+attribute float a_minzoom;
+attribute float a_maxzoom;
+attribute float a_rangeend;
+attribute float a_rangestart;
+attribute float a_labelminzoom;
-// posmatrix is for the vertex position, exmatrix is for rotating and projecting
+// matrix is for the vertex position, exmatrix is for rotating and projecting
// the extrusion vector.
uniform mat4 u_matrix;
uniform mat4 u_exmatrix;
@@ -22,11 +27,6 @@ varying vec2 v_tex;
varying float v_alpha;
void main() {
- vec2 a_tex = a_data1.xy;
- float a_labelminzoom = a_data1[2];
- float a_angle = a_data1[3];
- vec2 a_zoom = a_data2.st;
- vec2 a_range = a_data2.pq;
float rev = 0.0;
@@ -40,7 +40,7 @@ void main() {
// of the view plane so that the triangle gets clipped. This makes it easier
// for us to create degenerate triangle strips.
// u_zoom is the current zoom level adjusted for the change in font size
- float z = 2.0 - step(a_zoom[0], u_zoom) - (1.0 - step(a_zoom[1], u_zoom)) + rev;
+ float z = 2.0 - step(a_minzoom, u_zoom) - (1.0 - step(a_maxzoom, u_zoom)) + rev;
// fade out labels
float alpha = clamp((u_fadezoom - a_labelminzoom) / u_fadedist, 0.0, 1.0);
@@ -62,8 +62,8 @@ void main() {
// all the angles are 0..256 representing 0..2PI
// hide if (angle >= a_rangeend && angle < rangestart)
- z += step(a_range[0], u_angle) * (1.0 - step(a_range[1], u_angle));
+ z += step(a_rangeend, u_angle) * (1.0 - step(a_rangestart, u_angle));
gl_Position = u_matrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0);
- v_tex = a_tex * 4.0 / u_texsize;
+ v_tex = a_tex / u_texsize;
}
diff --git a/src/shader/sdf_shader.cpp b/src/shader/sdf_shader.cpp
new file mode 100644
index 0000000000..b86733c0e4
--- /dev/null
+++ b/src/shader/sdf_shader.cpp
@@ -0,0 +1,91 @@
+#include <mbgl/shader/sdf_shader.hpp>
+#include <mbgl/shader/shaders.hpp>
+#include <mbgl/platform/gl.hpp>
+
+#include <cstdio>
+
+using namespace mbgl;
+
+SDFShader::SDFShader()
+ : Shader(
+ "sdf",
+ shaders[SDF_SHADER].vertex,
+ shaders[SDF_SHADER].fragment
+ ) {
+ if (!valid) {
+ fprintf(stderr, "invalid sdf shader\n");
+ return;
+ }
+
+ a_pos = glGetAttribLocation(program, "a_pos");
+ a_offset = glGetAttribLocation(program, "a_offset");
+ a_tex = glGetAttribLocation(program, "a_tex");
+ a_angle = glGetAttribLocation(program, "a_angle");
+ a_minzoom = glGetAttribLocation(program, "a_minzoom");
+ a_maxzoom = glGetAttribLocation(program, "a_maxzoom");
+ a_rangeend = glGetAttribLocation(program, "a_rangeend");
+ a_rangestart = glGetAttribLocation(program, "a_rangestart");
+ a_labelminzoom = glGetAttribLocation(program, "a_labelminzoom");
+}
+
+void SDFGlyphShader::bind(char *offset) {
+ const int stride = 16;
+
+ glEnableVertexAttribArray(a_pos);
+ glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0);
+
+ glEnableVertexAttribArray(a_offset);
+ glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4);
+
+ glEnableVertexAttribArray(a_labelminzoom);
+ glVertexAttribPointer(a_labelminzoom, 1, GL_UNSIGNED_BYTE, false, stride, offset + 8);
+
+ glEnableVertexAttribArray(a_minzoom);
+ glVertexAttribPointer(a_minzoom, 1, GL_UNSIGNED_BYTE, false, stride, offset + 9);
+
+ glEnableVertexAttribArray(a_maxzoom);
+ glVertexAttribPointer(a_maxzoom, 1, GL_UNSIGNED_BYTE, false, stride, offset + 10);
+
+ glEnableVertexAttribArray(a_angle);
+ glVertexAttribPointer(a_angle, 1, GL_UNSIGNED_BYTE, false, stride, offset + 11);
+
+ glEnableVertexAttribArray(a_rangeend);
+ glVertexAttribPointer(a_rangeend, 1, GL_UNSIGNED_BYTE, false, stride, offset + 12);
+
+ glEnableVertexAttribArray(a_rangestart);
+ glVertexAttribPointer(a_rangestart, 1, GL_UNSIGNED_BYTE, false, stride, offset + 13);
+
+ glEnableVertexAttribArray(a_tex);
+ glVertexAttribPointer(a_tex, 2, GL_UNSIGNED_BYTE, false, stride, offset + 14);
+}
+
+void SDFIconShader::bind(char *offset) {
+ const int stride = 20;
+
+ glEnableVertexAttribArray(a_pos);
+ glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0);
+
+ glEnableVertexAttribArray(a_offset);
+ glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4);
+
+ glEnableVertexAttribArray(a_labelminzoom);
+ glVertexAttribPointer(a_labelminzoom, 1, GL_UNSIGNED_BYTE, false, stride, offset + 8);
+
+ glEnableVertexAttribArray(a_minzoom);
+ glVertexAttribPointer(a_minzoom, 1, GL_UNSIGNED_BYTE, false, stride, offset + 9);
+
+ glEnableVertexAttribArray(a_maxzoom);
+ glVertexAttribPointer(a_maxzoom, 1, GL_UNSIGNED_BYTE, false, stride, offset + 10);
+
+ glEnableVertexAttribArray(a_angle);
+ glVertexAttribPointer(a_angle, 1, GL_UNSIGNED_BYTE, false, stride, offset + 11);
+
+ glEnableVertexAttribArray(a_rangeend);
+ glVertexAttribPointer(a_rangeend, 1, GL_UNSIGNED_BYTE, false, stride, offset + 12);
+
+ glEnableVertexAttribArray(a_rangestart);
+ glVertexAttribPointer(a_rangestart, 1, GL_UNSIGNED_BYTE, false, stride, offset + 13);
+
+ glEnableVertexAttribArray(a_tex);
+ glVertexAttribPointer(a_tex, 2, GL_SHORT, false, stride, offset + 16);
+}
diff --git a/src/shader/shader.cpp b/src/shader/shader.cpp
index 171ce9b7c1..91c9b58c89 100644
--- a/src/shader/shader.cpp
+++ b/src/shader/shader.cpp
@@ -124,15 +124,6 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
return true;
}
-
-void Shader::setMatrix(const std::array<float, 16>& newMatrix) {
- if (matrix != newMatrix) {
- glUniformMatrix4fv(u_matrix, 1, GL_FALSE, newMatrix.data());
- matrix = newMatrix;
- }
-}
-
-
Shader::~Shader() {
if (program) {
glDeleteProgram(program);
diff --git a/src/shader/text_shader.cpp b/src/shader/text_shader.cpp
deleted file mode 100644
index f6de934e2f..0000000000
--- a/src/shader/text_shader.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-#include <mbgl/shader/text_shader.hpp>
-#include <mbgl/shader/shaders.hpp>
-#include <mbgl/platform/gl.hpp>
-
-#include <cstdio>
-
-using namespace mbgl;
-
-TextShader::TextShader()
- : Shader(
- "text",
- shaders[TEXT_SHADER].vertex,
- shaders[TEXT_SHADER].fragment
- ) {
- if (!valid) {
- fprintf(stderr, "invalid text shader\n");
- return;
- }
-
- a_pos = glGetAttribLocation(program, "a_pos");
- a_offset = glGetAttribLocation(program, "a_offset");
- a_data1 = glGetAttribLocation(program, "a_data1");
- a_data2 = glGetAttribLocation(program, "a_data2");
-
- u_matrix = glGetUniformLocation(program, "u_matrix");
- u_color = glGetUniformLocation(program, "u_color");
- u_buffer = glGetUniformLocation(program, "u_buffer");
- u_gamma = glGetUniformLocation(program, "u_gamma");
- u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
- u_angle = glGetUniformLocation(program, "u_angle");
- u_zoom = glGetUniformLocation(program, "u_zoom");
- u_flip = glGetUniformLocation(program, "u_flip");
- u_fadedist = glGetUniformLocation(program, "u_fadedist");
- u_minfadezoom = glGetUniformLocation(program, "u_minfadezoom");
- u_maxfadezoom = glGetUniformLocation(program, "u_maxfadezoom");
- u_fadezoom = glGetUniformLocation(program, "u_fadezoom");
- u_texsize = glGetUniformLocation(program, "u_texsize");
-
- // fprintf(stderr, "TextShader:\n");
- // fprintf(stderr, " - a_pos: %d\n", a_pos);
- // fprintf(stderr, " - a_offset: %d\n", a_offset);
- // fprintf(stderr, " - a_data1: %d\n", a_tex);
- // fprintf(stderr, " - a_data2: %d\n", a_tex);
- // fprintf(stderr, " - u_color: %d\n", u_color);
- // fprintf(stderr, " - u_buffer: %d\n", u_buffer);
- // fprintf(stderr, " - u_gamma: %d\n", u_gamma);
- // fprintf(stderr, " - u_exmatrix: %d\n", u_exmatrix);
- // fprintf(stderr, " - u_angle: %d\n", u_angle);
- // fprintf(stderr, " - u_zoom: %d\n", u_zoom);
- // fprintf(stderr, " - u_flip: %d\n", u_flip);
- // fprintf(stderr, " - u_fadedist: %d\n", u_fadedist);
- // fprintf(stderr, " - u_minfadezoom: %d\n", u_minfadezoom);
- // fprintf(stderr, " - u_maxfadezoom: %d\n", u_maxfadezoom);
- // fprintf(stderr, " - u_fadezoom: %d\n", u_fadezoom);
- // fprintf(stderr, " - u_texsize: %d\n", u_texsize);
- // fprintf(stderr, " - u_opacity: %d\n", u_opacity);
-}
-
-void TextShader::bind(char *offset) {
- glEnableVertexAttribArray(a_pos);
- glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 16, offset + 0);
-
- glEnableVertexAttribArray(a_offset);
- glVertexAttribPointer(a_offset, 2, GL_SHORT, false, 16, offset + 4);
-
- glEnableVertexAttribArray(a_data1);
- glVertexAttribPointer(a_data1, 4, GL_UNSIGNED_BYTE, false, 16, offset + 8);
-
- glEnableVertexAttribArray(a_data2);
- glVertexAttribPointer(a_data2, 4, GL_UNSIGNED_BYTE, false, 16, offset + 12);
-}
-
-void TextShader::setColor(const std::array<float, 4>& new_color) {
- if (color != new_color) {
- glUniform4fv(u_color, 1, new_color.data());
- color = new_color;
- }
-}
-
-void TextShader::setColor(float r, float g, float b, float a) {
- setColor({{ r, g, b, a }});
-}
-
-void TextShader::setBuffer(float new_buffer) {
- if (buffer != new_buffer) {
- glUniform1f(u_buffer, new_buffer);
- buffer = new_buffer;
- }
-}
-
-void TextShader::setGamma(float new_gamma) {
- if (gamma != new_gamma) {
- glUniform1f(u_gamma, new_gamma);
- gamma = new_gamma;
- }
-}
-
-void TextShader::setExtrudeMatrix(const std::array<float, 16> &new_exmatrix) {
- if (exmatrix != new_exmatrix) {
- glUniformMatrix4fv(u_exmatrix, 1, GL_FALSE, new_exmatrix.data());
- exmatrix = new_exmatrix;
- }
-}
-
-void TextShader::setAngle(float new_angle) {
- if (angle != new_angle) {
- glUniform1f(u_angle, new_angle);
- angle = new_angle;
- }
-}
-
-void TextShader::setZoom(float new_zoom) {
- if (zoom != new_zoom) {
- glUniform1f(u_zoom, new_zoom);
- zoom = new_zoom;
- }
-}
-
-void TextShader::setFlip(float new_flip) {
- if (flip != new_flip) {
- glUniform1f(u_flip, new_flip);
- flip = new_flip;
- }
-}
-
-void TextShader::setFadeDist(float new_fadedist) {
- if (fadedist != new_fadedist) {
- glUniform1f(u_fadedist, new_fadedist);
- fadedist = new_fadedist;
- }
-}
-
-void TextShader::setMinFadeZoom(float new_minfadezoom) {
- if (minfadezoom != new_minfadezoom) {
- glUniform1f(u_minfadezoom, new_minfadezoom);
- minfadezoom = new_minfadezoom;
- }
-}
-
-void TextShader::setMaxFadeZoom(float new_maxfadezoom) {
- if (maxfadezoom != new_maxfadezoom) {
- glUniform1f(u_maxfadezoom, new_maxfadezoom);
- maxfadezoom = new_maxfadezoom;
- }
-}
-
-void TextShader::setFadeZoom(float new_fadezoom) {
- if (fadezoom != new_fadezoom) {
- glUniform1f(u_fadezoom, new_fadezoom);
- fadezoom = new_fadezoom;
- }
-}
-
-void TextShader::setTextureSize(const std::array<float, 2> &new_texsize) {
- if (texsize != new_texsize) {
- glUniform2fv(u_texsize, 1, new_texsize.data());
- texsize = new_texsize;
- }
-}
diff --git a/src/shader/uniform.cpp b/src/shader/uniform.cpp
new file mode 100644
index 0000000000..24f179baf1
--- /dev/null
+++ b/src/shader/uniform.cpp
@@ -0,0 +1,47 @@
+#include <mbgl/shader/uniform.hpp>
+
+namespace mbgl {
+
+template <>
+void Uniform<float>::bind(const float& t) {
+ glUniform1f(location, t);
+}
+
+template <>
+void Uniform<int32_t>::bind(const int32_t& t) {
+ glUniform1i(location, t);
+}
+
+template <>
+void Uniform<std::array<float, 2>>::bind(const std::array<float, 2>& t) {
+ glUniform2fv(location, 1, t.data());
+}
+
+template <>
+void Uniform<std::array<float, 3>>::bind(const std::array<float, 3>& t) {
+ glUniform3fv(location, 1, t.data());
+}
+
+template <>
+void Uniform<std::array<float, 4>>::bind(const std::array<float, 4>& t) {
+ glUniform4fv(location, 1, t.data());
+}
+
+template <>
+void UniformMatrix<2>::bind(const std::array<float, 4>& t) {
+ glUniformMatrix2fv(location, 1, GL_FALSE, t.data());
+}
+
+template <>
+void UniformMatrix<3>::bind(const std::array<float, 9>& t) {
+ glUniformMatrix3fv(location, 1, GL_FALSE, t.data());
+}
+
+template <>
+void UniformMatrix<4>::bind(const std::array<float, 16>& t) {
+ glUniformMatrix4fv(location, 1, GL_FALSE, t.data());
+}
+
+// Add more as needed.
+
+}
diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp
index 3d51a2ebeb..f0d6992318 100644
--- a/src/style/style_parser.cpp
+++ b/src/style/style_parser.cpp
@@ -607,6 +607,7 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) {
parseOptionalProperty<PropertyTransition>("transition-icon-halo-blur", Key::IconHaloBlur, klass, value);
parseOptionalProperty<Function<float>>("icon-translate", { Key::IconTranslateX, Key::IconTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("transition-icon-translate", Key::IconTranslate, klass, value);
+ parseOptionalProperty<TranslateAnchorType>("icon-translate-anchor", Key::IconTranslateAnchor, klass, value);
parseOptionalProperty<Function<float>>("text-opacity", Key::TextOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("transition-text-opacity", Key::TextOpacity, klass, value);
@@ -622,6 +623,7 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) {
parseOptionalProperty<PropertyTransition>("transition-text-halo-blur", Key::TextHaloBlur, klass, value);
parseOptionalProperty<Function<float>>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("transition-text-translate", Key::TextTranslate, klass, value);
+ parseOptionalProperty<TranslateAnchorType>("text-translate-anchor", Key::TextTranslateAnchor, klass, value);
parseOptionalProperty<Function<float>>("raster-opacity", Key::RasterOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-opacity", Key::RasterOpacity, klass, value);
@@ -867,7 +869,6 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer) {
parseRenderProperty(value, render.icon.padding, "icon-padding");
parseRenderProperty(value, render.icon.keep_upright, "icon-keep-upright");
parseRenderProperty(value, render.icon.offset, "icon-offset");
- parseRenderProperty<TranslateAnchorTypeClass>(value, render.icon.translate_anchor, "icon-translate-anchor");
parseRenderProperty<RotationAlignmentTypeClass>(value, render.text.rotation_alignment, "text-rotation-alignment");
@@ -893,7 +894,6 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer) {
parseRenderProperty(value, render.text.keep_upright, "text-keep-upright");
parseRenderProperty<TextTransformTypeClass>(value, render.text.transform, "text-transform");
parseRenderProperty(value, render.text.offset, "text-offset");
- parseRenderProperty<TranslateAnchorTypeClass>(value, render.text.translate_anchor, "text-translate-anchor");
parseRenderProperty(value, render.text.allow_overlap, "text-allow-overlap");
parseRenderProperty(value, render.text.ignore_placement, "text-ignore-placement");
parseRenderProperty(value, render.text.optional, "text-optional");