diff --git a/.gitignore b/.gitignore index 740653e6a..23dbb0f8f 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 c8d11b407..d5d713613 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 3fb090f2b..f790d90ce 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 a38c587d6..e8f880b54 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 8df9fd0f7..336c4af28 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 36f0f338e..0946f0fc4 100644 --- a/include/mbgl/geometry/sprite_atlas.hpp +++ b/include/mbgl/geometry/sprite_atlas.hpp @@ -9,12 +9,19 @@ #include #include #include +#include namespace mbgl { class Sprite; class SpritePosition; +struct SpriteAtlasPosition { + std::array size; + std::array tl; + std::array 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 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 7bc666557..6461a5e33 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, private util::noncopyable { diff --git a/include/mbgl/platform/event.hpp b/include/mbgl/platform/event.hpp index 1befd0af3..1676f40d2 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 a5dbe21bc..b1f0bcb59 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 history; diff --git a/include/mbgl/renderer/line_bucket.hpp b/include/mbgl/renderer/line_bucket.hpp index c7e375a0a..8babb734e 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 a8fe62b55..75529d113 100644 --- a/include/mbgl/renderer/painter.hpp +++ b/include/mbgl/renderer/painter.hpp @@ -14,9 +14,10 @@ #include #include #include +#include #include #include -#include +#include #include #include @@ -87,6 +88,8 @@ public: void renderRaster(RasterBucket& bucket, std::shared_ptr layer_desc, const Tile::ID& id, const mat4 &matrix); void renderBackground(std::shared_ptr layer_desc); + float saturationFactor(float saturation); + float contrastFactor(float contrast); std::array 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 &translation, const Tile::ID &id, TranslateAnchorType anchor = TranslateAnchorType::Map); + mat4 translatedMatrix(const mat4& matrix, const std::array &translation, const Tile::ID &id, TranslateAnchorType anchor); void prepareTile(const Tile& tile); + template + void renderSDF(SymbolBucket &bucket, + const Tile::ID &id, + const mat4 &matrixSymbol, + const BucketProperties& bucketProperties, + const StyleProperties& styleProperties, + float scaleDivisor, + std::array 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; std::unique_ptr lineShader; std::unique_ptr linejoinShader; + std::unique_ptr linepatternShader; std::unique_ptr patternShader; std::unique_ptr iconShader; std::unique_ptr rasterShader; - std::unique_ptr textShader; + std::unique_ptr sdfGlyphShader; + std::unique_ptr sdfIconShader; std::unique_ptr dotShader; std::unique_ptr gaussianShader; diff --git a/include/mbgl/renderer/symbol_bucket.hpp b/include/mbgl/renderer/symbol_bucket.hpp index fb1678fc8..c71d27645 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 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 d8d649db9..2c4176f36 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 +#include 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& color); - void setSize(float size); - void setBlur(float blur); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform> u_color = {"u_color", *this}; + Uniform u_size = {"u_size", *this}; + Uniform u_blur = {"u_blur", *this}; - private: - int32_t a_pos = -1; - - std::array 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 a4b9d09f3..0f494f5c7 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 +#include namespace mbgl { @@ -11,17 +12,12 @@ public: void bind(char *offset); - void setImage(int32_t image); - void setOffset(const std::array& offset); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform> u_offset = {"u_offset", *this}; + Uniform u_image = {"u_image", *this}; private: int32_t a_pos = -1; - - int32_t image = 0; - int32_t u_image = -1; - - std::array offset = {{}}; - int32_t u_offset = -1; }; } diff --git a/include/mbgl/shader/icon_shader.hpp b/include/mbgl/shader/icon_shader.hpp index 54869fe48..645d7e21b 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 +#include namespace mbgl { @@ -11,16 +12,17 @@ public: void bind(char *offset); - void setExtrudeMatrix(const std::array& 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 &texsize); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this}; + Uniform u_angle = {"u_angle", *this}; + Uniform u_zoom = {"u_zoom", *this}; + Uniform u_flip = {"u_flip", *this}; + Uniform u_fadedist = {"u_fadedist", *this}; + Uniform u_minfadezoom = {"u_minfadezoom", *this}; + Uniform u_maxfadezoom = {"u_maxfadezoom", *this}; + Uniform u_fadezoom = {"u_fadezoom", *this}; + Uniform u_opacity = {"u_opacity", *this}; + Uniform> 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 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 texsize = {{}}; - int32_t u_texsize = -1; }; } diff --git a/include/mbgl/shader/line_shader.hpp b/include/mbgl/shader/line_shader.hpp index c476b5c4c..b78933088 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 +#include namespace mbgl { @@ -11,36 +12,18 @@ public: void bind(char *offset); - void setExtrudeMatrix(const std::array& exmatrix); - void setColor(const std::array& color); - void setLineWidth(const std::array& linewidth); - void setRatio(float ratio); - void setDashArray(const std::array& dasharray); - void setBlur(float blur); - void setDebug(float debug); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this}; + Uniform> u_color = {"u_color", *this}; + Uniform> u_linewidth = {"u_linewidth", *this}; + Uniform> u_dasharray = {"u_dasharray", *this}; + Uniform u_ratio = {"u_ratio", *this}; + Uniform u_blur = {"u_blur", *this}; private: int32_t a_pos = -1; int32_t a_extrude = -1; int32_t a_linesofar = -1; - - std::array exmatrix = {{}}; - int32_t u_exmatrix = -1; - - std::array color = {{}}; - int32_t u_color = -1; - - std::array linewidth = {{}}; - int32_t u_linewidth = -1; - - float ratio = 0; - int32_t u_ratio = -1; - - std::array 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 5a5c97e92..61406fd45 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 +#include namespace mbgl { @@ -11,25 +12,14 @@ public: void bind(char *offset); - void setColor(const std::array& color); - void setWorld(const std::array& world); - void setLineWidth(const std::array& linewidth); - void setSize(float size); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform> u_color = {"u_color", *this}; + Uniform> u_world = {"u_world", *this}; + Uniform> u_linewidth = {"u_linewidth", *this}; + Uniform u_size = {"u_size", *this}; private: int32_t a_pos = -1; - - std::array color = {{}}; - int32_t u_color = -1; - - std::array world = {{}}; - int32_t u_world = -1; - - std::array 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 000000000..bf85940b8 --- /dev/null +++ b/include/mbgl/shader/linepattern_shader.hpp @@ -0,0 +1,33 @@ +#ifndef MBGL_SHADER_SHADER_LINEPATTERN +#define MBGL_SHADER_SHADER_LINEPATTERN + +#include +#include + +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> u_linewidth = {"u_linewidth", *this}; + Uniform> u_pattern_size = {"u_pattern_size", *this}; + Uniform> u_pattern_tl = {"u_pattern_tl", *this}; + Uniform> u_pattern_br = {"u_pattern_br", *this}; + Uniform u_ratio = {"u_ratio", *this}; + Uniform u_point = {"u_point", *this}; + Uniform u_blur = {"u_blur", *this}; + Uniform 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 551e31ca5..f3e8175fd 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 +#include namespace mbgl { @@ -11,17 +12,12 @@ public: void bind(char *offset); - void setColor(const std::array& color); - void setWorld(const std::array& world); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform> u_color = {"u_color", *this}; + Uniform> u_world = {"u_world", *this}; private: int32_t a_pos = -1; - - std::array color = {{}}; - int32_t u_color = -1; - - std::array world = {{}}; - int32_t u_world = -1; }; } diff --git a/include/mbgl/shader/pattern_shader.hpp b/include/mbgl/shader/pattern_shader.hpp index e574b755d..9fabd8e18 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 +#include namespace mbgl { @@ -11,33 +12,16 @@ public: void bind(char *offset); - void setPatternTopLeft(const std::array& pattern_tl); - void setPatternBottomRight(const std::array& pattern_br); - void setOpacity(float opacity); - void setImage(int image); - void setMix(float mix); - void setPatternMatrix(const std::array &patternmatrix); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform> u_pattern_tl = {"u_pattern_tl", *this}; + Uniform> u_pattern_br = {"u_pattern_br", *this}; + Uniform u_opacity = {"u_opacity", *this}; + Uniform u_mix = {"u_mix", *this}; + Uniform u_image = {"u_image", *this}; + UniformMatrix<3> u_patternmatrix = {"u_patternmatrix", *this}; private: int32_t a_pos = -1; - - std::array pattern_tl = {{}}; - int32_t u_pattern_tl = -1; - - std::array pattern_br = {{}}; - int32_t u_pattern_br = -1; - - float opacity = 0; - int32_t u_opacity = -1; - - int image = 0; - int32_t u_image = -1; - - float mix = 0; - int32_t u_mix = -1; - - std::array patternmatrix = {{}}; - int32_t u_patternmatrix = -1; }; } diff --git a/include/mbgl/shader/plain_shader.hpp b/include/mbgl/shader/plain_shader.hpp index 277788431..051501c3c 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 +#include 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& color); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform> u_color = {"u_color", *this}; private: int32_t a_pos = -1; - - std::array color = {{}}; - int32_t u_color = -1; }; } diff --git a/include/mbgl/shader/raster_shader.hpp b/include/mbgl/shader/raster_shader.hpp index 11765413f..8cf97055a 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 +#include 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 spin_weights); + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + Uniform u_image = {"u_image", *this}; + Uniform u_opacity = {"u_opacity", *this}; + Uniform u_buffer = {"u_buffer", *this}; + Uniform u_brightness_low = {"u_brightness_low", *this}; + Uniform u_brightness_high = {"u_brightness_high", *this}; + Uniform u_saturation_factor = {"u_saturation_factor", *this}; + Uniform u_contrast_factor = {"u_contrast_factor", *this}; + Uniform> 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 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 000000000..0737c25ee --- /dev/null +++ b/include/mbgl/shader/sdf_shader.hpp @@ -0,0 +1,53 @@ +#ifndef MBGL_SHADER_SDF_SHADER +#define MBGL_SHADER_SDF_SHADER + +#include +#include + +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> u_color = {"u_color", *this}; + Uniform> u_texsize = {"u_texsize", *this}; + Uniform u_buffer = {"u_buffer", *this}; + Uniform u_gamma = {"u_gamma", *this}; + Uniform u_angle = {"u_angle", *this}; + Uniform u_zoom = {"u_zoom", *this}; + Uniform u_flip = {"u_flip", *this}; + Uniform u_fadedist = {"u_fadedist", *this}; + Uniform u_minfadezoom = {"u_minfadezoom", *this}; + Uniform u_maxfadezoom = {"u_maxfadezoom", *this}; + Uniform 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 fa2d5a0a8..27e831a51 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& matrix); - inline uint32_t getID() const { return program; } private: bool compileShader(uint32_t *shader, uint32_t type, const char *source); - -protected: - std::array 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 554b890fb..000000000 --- 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 &color); - void setBuffer(float buffer); - void setGamma(float gamma); - void setExtrudeMatrix(const std::array &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 &texsize); - -private: - int32_t a_pos = -1; - int32_t a_offset = -1; - int32_t a_data1 = -1; - int32_t a_data2 = -1; - - std::array 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 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 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 000000000..a87bbd7aa --- /dev/null +++ b/include/mbgl/shader/uniform.hpp @@ -0,0 +1,53 @@ +#ifndef MBGL_SHADER_UNIFORM +#define MBGL_SHADER_UNIFORM + +#include +#include + +namespace mbgl { + +template +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 +class UniformMatrix { +public: + typedef std::array 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 67c314205..c2cde52aa 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 offset = {0, 0}; - TranslateAnchorType translate_anchor = TranslateAnchorType::Map; } icon; struct { @@ -74,7 +73,6 @@ public: bool keep_upright = true; TextTransformType transform = TextTransformType::None; vec2 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 9e74e21b2..76df941d9 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 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 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 730551dbe..7ea9d4ce7 100644 --- a/src/geometry/sprite_atlas.cpp +++ b/src/geometry/sprite_atlas.cpp @@ -132,6 +132,18 @@ Rect 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 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::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 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 lock(mtx); diff --git a/src/geometry/text_buffer.cpp b/src/geometry/text_buffer.cpp index cb3010183..295ff02ef 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(data); - // a_data1 - ubytes[8] = tx / 4; - ubytes[9] = ty / 4; - ubytes[10] = labelminzoom * 10; - ubytes[11] = (int16_t)std::round(angle * angleFactor) % 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; - // 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[14] = tx / 4; + ubytes[15] = ty / 4; return idx; } diff --git a/src/map/map.cpp b/src/map/map.cpp index 5c139f364..1399b97ee 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -545,10 +545,6 @@ void Map::render() { #if defined(DEBUG) std::vector debug; #endif - - glyphAtlas->upload(); - spriteAtlas->upload(); - painter.clear(); painter.resize(); diff --git a/src/map/sprite.cpp b/src/map/sprite.cpp index a8f4f9718..af9413a0e 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::Create(const std::string& base_url, float pixelRatio, const std::shared_ptr &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 6a11f0d4c..8b69162a2 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 e089d7f61..2e89a7c35 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 2a3d45c9e..c1705cd7c 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(); if (!lineShader) lineShader = std::make_unique(); if (!linejoinShader) linejoinShader = std::make_unique(); + if (!linepatternShader) linepatternShader = std::make_unique(); if (!patternShader) patternShader = std::make_unique(); if (!iconShader) iconShader = std::make_unique(); if (!rasterShader) rasterShader = std::make_unique(); - if (!textShader) textShader = std::make_unique(); + if (!sdfGlyphShader) sdfGlyphShader = std::make_unique(); + if (!sdfIconShader) sdfIconShader = std::make_unique(); if (!dotShader) dotShader = std::make_unique(); if (!gaussianShader) gaussianShader = std::make_unique(); } @@ -193,8 +197,8 @@ void Painter::renderBackground(std::shared_ptr 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 d8fa3693b..45b14a2f7 100644 --- a/src/renderer/painter_clipping.cpp +++ b/src/renderer/painter_clipping.cpp @@ -28,7 +28,7 @@ void Painter::drawClippingMasks(const std::set> &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 eae655f1f..f12053383 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 &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 &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 97ca1767f..6d56b9077 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 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(map.getState().getFramebufferWidth()), static_cast(map.getState().getFramebufferHeight()) - }}); + }}; depthRange(strata, 1.0f); bucket.drawVertices(*outlineShader); } @@ -61,40 +61,22 @@ void Painter::renderFill(FillBucket& bucket, std::shared_ptr layer_d Sprite &sprite = *map.getSprite(); if (pass == RenderPass::Translucent && sprite) { SpriteAtlas &spriteAtlas = *map.getSpriteAtlas(); - const Rect pos = spriteAtlas.getImage(properties.image, sprite); - - // `repeating` indicates that the image will be used in a repeating pattern - // repeating pattern images are assumed to have a 1px padding that mirrors the opposite edge - // positions for repeating images are adjusted to exclude the edge - const int repeating = 1; - const std::array size {{ - float(pos.w) / spriteAtlas.getPixelRatio(), - float(pos.h) / spriteAtlas.getPixelRatio(), - }}; - const std::array tl {{ - (float(pos.x + repeating) / spriteAtlas.getWidth()), - (float(pos.y + repeating) / spriteAtlas.getHeight()), - }}; - const std::array br {{ - (float(pos.x + pos.w - 2 * repeating) / spriteAtlas.getWidth()), - (float(pos.y + pos.h - 2 * repeating) / spriteAtlas.getHeight()), - }}; + const 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 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 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(map.getState().getFramebufferWidth()), static_cast(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 ad0778fc0..161abcd6f 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -1,6 +1,9 @@ #include #include +#include #include +#include +#include #include using namespace mbgl; @@ -12,9 +15,9 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr layer_d const LineProperties &properties = layer_desc->getProperties(); + 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 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 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 = map.getSprite(); + if (properties.image.size() && sprite) { + SpriteAtlasPosition imagePos = map.getSpriteAtlas()->getPosition(properties.image, *sprite); - // imageSprite.bind(gl, true); + float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z); + float fade = std::fmod(map.getState().getZoom(), 1.0); - // //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); + useProgram(linepatternShader->program); + + linepatternShader->u_matrix = vtxMatrix; + linepatternShader->u_exmatrix = extrudeMatrix; + linepatternShader->u_linewidth = {{ outset, inset }}; + linepatternShader->u_ratio = ratio; + linepatternShader->u_blur = blur; + + 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; + + 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 14a15effe..f38470530 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 946f6216c..7f7afc3e8 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 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 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 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 e412bc49d..4fce66217 100644 --- a/src/renderer/painter_symbol.cpp +++ b/src/renderer/painter_symbol.cpp @@ -7,7 +7,110 @@ #include #include -namespace mbgl { +using namespace mbgl; + +template +void Painter::renderSDF(SymbolBucket &bucket, + const Tile::ID &id, + const mat4 &matrix, + const BucketProperties& bucketProperties, + const StyleProperties& styleProperties, + float sdfFontSize, + std::array 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 layer_desc, const Tile::ID &id, const mat4 &matrix) { // Abort early. @@ -20,197 +123,87 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr 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(glyphAtlas.width), static_cast(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 &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(spriteAtlas.getWidth()), static_cast(spriteAtlas.getHeight())}}); + spriteAtlas.bind(map.getState().isChanging() || bucket.properties.placement == PlacementType::Line || angleOffset != 0 || fontScale != 1 || sdf); - // Convert the -pi..pi to an int8 range. - const float angle = std::round((map.getState().getAngle()) / M_PI * 128); + std::array texsize = {{ + float(spriteAtlas.getWidth()), + float(spriteAtlas.getHeight()) + }}; - // adjust min/max zooms for variable font sies - float zoomAdjust = log(fontSize / bucket.properties.icon.max_size) / log(2); + 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); - 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 + mat4 exMatrix; + matrix::copy(exMatrix, projMatrix); - 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); + if (angleOffset) { + matrix::rotate_z(exMatrix, exMatrix, angleOffset); + } - depthRange(strata, 1.0f); - bucket.drawIcons(*iconShader); + matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f); + + useProgram(iconShader->program); + iconShader->u_matrix = vtxMatrix; + iconShader->u_exmatrix = exMatrix; + iconShader->u_texsize = texsize; + + // Convert the -pi..pi to an int8 range. + const float angle = std::round(map.getState().getAngle() / M_PI * 128); + + // adjust min/max zooms for variable font sies + float zoomAdjust = std::log(fontSize / bucket.properties.icon.max_size) / std::log(2); + + 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 52f7edc50..0a4781632 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 10dadc03f..492eea980 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 fd8931509..374ea2dc2 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 3f1d5a234..6d998b561 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 a0d64c33b..5310ae745 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 54163d698..a897f410a 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& 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 e29afc0a8..ee8406e9e 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 320d48f23..26a839420 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 d22006020..9060f0ee7 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& 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 6e8130ef1..45b56793e 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 f8d94a263..8c69c4041 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 4973dc411..5c54177eb 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& 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 &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 14be3c4eb..1d8e687c9 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 1b0527366..8353f4c6c 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& new_exmatrix) { - if (exmatrix != new_exmatrix) { - glUniformMatrix4fv(u_exmatrix, 1, GL_FALSE, new_exmatrix.data()); - exmatrix = new_exmatrix; - } -} - -void LineShader::setColor(const std::array& new_color) { - if (color != new_color) { - glUniform4fv(u_color, 1, new_color.data()); - color = new_color; - } -} - -void LineShader::setLineWidth(const std::array& 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& 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 e8ec306ed..050e180e0 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& new_color) { - if (color != new_color) { - glUniform4fv(u_color, 1, new_color.data()); - color = new_color; - } -} - -void LinejoinShader::setWorld(const std::array& new_world) { - if (world != new_world) { - glUniform2fv(u_world, 1, new_world.data()); - world = new_world; - } -} - -void LinejoinShader::setLineWidth(const std::array& 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 000000000..52ca823a3 --- /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 000000000..4600ebf65 --- /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 000000000..954dbd2b3 --- /dev/null +++ b/src/shader/linepattern_shader.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +#include + +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 d9c19fa80..ddabfa5d0 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& new_color) { - if (color != new_color) { - glUniform4fv(u_color, 1, new_color.data()); - color = new_color; - } -} - -void OutlineShader::setWorld(const std::array& 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 8fe6a34e9..31374bc3e 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& 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& 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& 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 bb0c22899..8a37837b3 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& 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 d56a5b590..333de76dc 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 60d81c61b..7351f7d0c 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 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 similarity index 100% rename from src/shader/text.fragment.glsl rename to src/shader/sdf.fragment.glsl diff --git a/src/shader/text.vertex.glsl b/src/shader/sdf.vertex.glsl similarity index 77% rename from src/shader/text.vertex.glsl rename to src/shader/sdf.vertex.glsl index 86cbec98e..c5166ae46 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 000000000..b86733c0e --- /dev/null +++ b/src/shader/sdf_shader.cpp @@ -0,0 +1,91 @@ +#include +#include +#include + +#include + +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 171ce9b7c..91c9b58c8 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& 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 f6de934e2..000000000 --- a/src/shader/text_shader.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include -#include - -#include - -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& 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 &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 &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 000000000..24f179baf --- /dev/null +++ b/src/shader/uniform.cpp @@ -0,0 +1,47 @@ +#include + +namespace mbgl { + +template <> +void Uniform::bind(const float& t) { + glUniform1f(location, t); +} + +template <> +void Uniform::bind(const int32_t& t) { + glUniform1i(location, t); +} + +template <> +void Uniform>::bind(const std::array& t) { + glUniform2fv(location, 1, t.data()); +} + +template <> +void Uniform>::bind(const std::array& t) { + glUniform3fv(location, 1, t.data()); +} + +template <> +void Uniform>::bind(const std::array& t) { + glUniform4fv(location, 1, t.data()); +} + +template <> +void UniformMatrix<2>::bind(const std::array& t) { + glUniformMatrix2fv(location, 1, GL_FALSE, t.data()); +} + +template <> +void UniformMatrix<3>::bind(const std::array& t) { + glUniformMatrix3fv(location, 1, GL_FALSE, t.data()); +} + +template <> +void UniformMatrix<4>::bind(const std::array& 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 3d51a2ebe..f0d699231 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("transition-icon-halo-blur", Key::IconHaloBlur, klass, value); parseOptionalProperty>("icon-translate", { Key::IconTranslateX, Key::IconTranslateY }, klass, value); parseOptionalProperty("transition-icon-translate", Key::IconTranslate, klass, value); + parseOptionalProperty("icon-translate-anchor", Key::IconTranslateAnchor, klass, value); parseOptionalProperty>("text-opacity", Key::TextOpacity, klass, value); parseOptionalProperty("transition-text-opacity", Key::TextOpacity, klass, value); @@ -622,6 +623,7 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) { parseOptionalProperty("transition-text-halo-blur", Key::TextHaloBlur, klass, value); parseOptionalProperty>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value); parseOptionalProperty("transition-text-translate", Key::TextTranslate, klass, value); + parseOptionalProperty("text-translate-anchor", Key::TextTranslateAnchor, klass, value); parseOptionalProperty>("raster-opacity", Key::RasterOpacity, klass, value); parseOptionalProperty("transition-raster-opacity", Key::RasterOpacity, klass, value); @@ -867,7 +869,6 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr &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(value, render.icon.translate_anchor, "icon-translate-anchor"); parseRenderProperty(value, render.text.rotation_alignment, "text-rotation-alignment"); @@ -893,7 +894,6 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr &layer) { parseRenderProperty(value, render.text.keep_upright, "text-keep-upright"); parseRenderProperty(value, render.text.transform, "text-transform"); parseRenderProperty(value, render.text.offset, "text-offset"); - parseRenderProperty(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");