diff options
-rw-r--r-- | include/mbgl/geometry/sprite_atlas.hpp | 9 | ||||
-rw-r--r-- | src/geometry/sprite_atlas.cpp | 12 | ||||
-rw-r--r-- | src/renderer/painter_fill.cpp | 26 | ||||
-rw-r--r-- | src/renderer/painter_line.cpp | 26 |
4 files changed, 32 insertions, 41 deletions
diff --git a/include/mbgl/geometry/sprite_atlas.hpp b/include/mbgl/geometry/sprite_atlas.hpp index 5044e4d3e6..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,6 +49,8 @@ public: // NEVER CALL THIS FUNCTION FROM THE RENDER THREAD! it is blocking. Rect<dimension> waitForImage(const std::string &name, const Sprite &sprite); + SpriteAtlasPosition getPosition(const std::string &name, const Sprite &sprite, bool repeating = false); + // 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); diff --git a/src/geometry/sprite_atlas.cpp b/src/geometry/sprite_atlas.cpp index 43c7da5fef..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(); diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 97ca1767f9..45706cca1b 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -61,36 +61,18 @@ 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->setPatternTopLeft(pos.tl); + patternShader->setPatternBottomRight(pos.br); patternShader->setOpacity(properties.opacity); patternShader->setImage(0); patternShader->setMix(mix); diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 33bf279ca0..b68d46b010 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -66,17 +66,11 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d const std::shared_ptr<Sprite> &sprite = map.getSprite(); if (properties.image.size() && sprite) { - SpriteAtlas &spriteAtlas = *map.getSpriteAtlas(); - Rect<uint16_t> imagePos = spriteAtlas.getImage(properties.image, *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); - std::array<float, 2> imageSize = {{ - imagePos.w * factor, - imagePos.h * factor - }}; - useProgram(linepatternShader->program); linepatternShader->setMatrix(vtxMatrix); @@ -85,20 +79,14 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d linepatternShader->setRatio(ratio); linepatternShader->setBlur(blur); - linepatternShader->setPatternSize(imageSize); - linepatternShader->setPatternTopLeft({{ - float(imagePos.x) / spriteAtlas.getWidth(), - float(imagePos.y) / spriteAtlas.getHeight(), - }}); - linepatternShader->setPatternBottomRight({{ - float(imagePos.x + imagePos.w) / spriteAtlas.getWidth(), - float(imagePos.y + imagePos.h) / spriteAtlas.getHeight(), - }}); + linepatternShader->setPatternSize({{imagePos.size[0] * factor, imagePos.size[1]}}); + linepatternShader->setPatternTopLeft(imagePos.tl); + linepatternShader->setPatternBottomRight(imagePos.br); linepatternShader->setFade(fade); - - spriteAtlas.bind(true); + + map.getSpriteAtlas()->bind(true); glDepthRange(strata + strata_epsilon, 1.0f); // may or may not matter - + bucket.drawLinePatterns(*linepatternShader); } else { |