Add SpriteAtlas::getPosition()
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user