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