background-image support
This commit is contained in:
@@ -29,10 +29,16 @@ public:
|
||||
const std::array<uint16_t, 2> getFramebufferDimensions() const;
|
||||
float getPixelRatio() const;
|
||||
|
||||
float worldSize() const;
|
||||
float lngX(float lon) const;
|
||||
float latY(float lat) const;
|
||||
std::array<float, 2> locationCoordinate(float lon, float lat) const;
|
||||
|
||||
// Zoom
|
||||
float getNormalizedZoom() const;
|
||||
int32_t getIntegerZoom() const;
|
||||
double getZoom() const;
|
||||
int32_t getIntegerZoom() const;
|
||||
double getZoomFraction() const;
|
||||
double getScale() const;
|
||||
|
||||
// Rotation
|
||||
|
||||
@@ -61,7 +61,8 @@ enum class PropertyKey {
|
||||
RasterFade,
|
||||
|
||||
BackgroundOpacity,
|
||||
BackgroundColor
|
||||
BackgroundColor,
|
||||
BackgroundImage
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ struct BackgroundProperties {
|
||||
inline BackgroundProperties() {}
|
||||
float opacity = 1.0f;
|
||||
Color color = {{ 0, 0, 0, 1 }};
|
||||
std::string image;
|
||||
};
|
||||
|
||||
typedef mapbox::util::variant<
|
||||
|
||||
@@ -32,6 +32,8 @@ typedef std::array<float, 9> mat3;
|
||||
namespace matrix {
|
||||
|
||||
void identity(mat3& out);
|
||||
void translate(mat3& out, const mat3& a, float x, float y);
|
||||
void rotate(mat3& out, const mat3& a, float rad);
|
||||
void scale(mat3& out, const mat3& a, float x, float y);
|
||||
|
||||
}
|
||||
|
||||
@@ -83,11 +83,31 @@ const std::array<uint16_t, 2> TransformState::getFramebufferDimensions() const {
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
|
||||
float TransformState::getPixelRatio() const {
|
||||
return pixelRatio;
|
||||
}
|
||||
|
||||
float TransformState::worldSize() const {
|
||||
return scale * util::tileSize;
|
||||
}
|
||||
|
||||
float TransformState::lngX(float lon) const {
|
||||
return (180 + lon) * worldSize() / 360;
|
||||
}
|
||||
|
||||
float TransformState::latY(float lat) const {
|
||||
float y = 180 / M_PI * std::log(std::tan(M_PI / 4 + lat * M_PI / 360));
|
||||
return (180 - y) * worldSize() / 360;
|
||||
}
|
||||
|
||||
std::array<float, 2> TransformState::locationCoordinate(float lon, float lat) const {
|
||||
float k = std::pow(2, getIntegerZoom()) / worldSize();
|
||||
return {{
|
||||
lngX(lon) * k,
|
||||
latY(lat) * k
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Zoom
|
||||
|
||||
@@ -95,12 +115,16 @@ float TransformState::getNormalizedZoom() const {
|
||||
return std::log(scale * util::tileSize / 512.0f) / M_LN2;
|
||||
}
|
||||
|
||||
double TransformState::getZoom() const {
|
||||
return std::log(scale) / M_LN2;
|
||||
}
|
||||
|
||||
int32_t TransformState::getIntegerZoom() const {
|
||||
return std::floor(getZoom());
|
||||
}
|
||||
|
||||
double TransformState::getZoom() const {
|
||||
return std::log(scale) / M_LN2;
|
||||
double TransformState::getZoomFraction() const {
|
||||
return getZoom() - getIntegerZoom();
|
||||
}
|
||||
|
||||
double TransformState::getScale() const {
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/util/clip_ids.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/mat3.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
|
||||
#if defined(DEBUG)
|
||||
#include <mbgl/util/timer.hpp>
|
||||
#endif
|
||||
@@ -188,24 +191,66 @@ void Painter::renderTileLayer(const Tile& tile, util::ptr<StyleLayer> layer_desc
|
||||
|
||||
void Painter::renderBackground(util::ptr<StyleLayer> layer_desc) {
|
||||
const BackgroundProperties& properties = layer_desc->getProperties<BackgroundProperties>();
|
||||
const std::shared_ptr<Sprite> sprite = map.getSprite();
|
||||
|
||||
Color color = properties.color;
|
||||
color[0] *= properties.opacity;
|
||||
color[1] *= properties.opacity;
|
||||
color[2] *= properties.opacity;
|
||||
color[3] *= properties.opacity;
|
||||
if (properties.image.size() && sprite) {
|
||||
if ((properties.opacity >= 1.0f) != (pass == RenderPass::Opaque))
|
||||
return;
|
||||
|
||||
SpriteAtlas &spriteAtlas = *map.getSpriteAtlas();
|
||||
SpriteAtlasPosition imagePos = spriteAtlas.getPosition(properties.image, *sprite, true);
|
||||
float zoomFraction = map.getState().getZoomFraction();
|
||||
|
||||
useProgram(patternShader->program);
|
||||
patternShader->u_matrix = identityMatrix;
|
||||
patternShader->u_pattern_tl = imagePos.tl;
|
||||
patternShader->u_pattern_br = imagePos.br;
|
||||
patternShader->u_mix = zoomFraction;
|
||||
patternShader->u_opacity = properties.opacity;
|
||||
|
||||
std::array<float, 2> size = imagePos.size;
|
||||
double lon, lat;
|
||||
map.getLonLat(lon, lat);
|
||||
std::array<float, 2> center = map.getState().locationCoordinate(lon, lat);
|
||||
float scale = 1 / std::pow(2, zoomFraction);
|
||||
|
||||
mat3 matrix;
|
||||
matrix::identity(matrix);
|
||||
matrix::scale(matrix, matrix,
|
||||
1.0f / size[0],
|
||||
1.0f / size[1]);
|
||||
matrix::translate(matrix, matrix,
|
||||
std::fmod(center[0] * 512, size[0]),
|
||||
std::fmod(center[1] * 512, size[1]));
|
||||
matrix::rotate(matrix, matrix, -map.getState().getAngle());
|
||||
matrix::scale(matrix, matrix,
|
||||
scale * map.getState().getWidth() / 2,
|
||||
-scale * map.getState().getHeight() / 2);
|
||||
patternShader->u_patternmatrix = matrix;
|
||||
|
||||
backgroundBuffer.bind();
|
||||
patternShader->bind(0);
|
||||
spriteAtlas.bind(true);
|
||||
} else {
|
||||
Color color = properties.color;
|
||||
color[0] *= properties.opacity;
|
||||
color[1] *= properties.opacity;
|
||||
color[2] *= properties.opacity;
|
||||
color[3] *= properties.opacity;
|
||||
|
||||
if ((color[3] >= 1.0f) != (pass == RenderPass::Opaque))
|
||||
return;
|
||||
|
||||
if ((color[3] >= 1.0f) == (pass == RenderPass::Opaque)) {
|
||||
useProgram(plainShader->program);
|
||||
plainShader->u_matrix = identityMatrix;
|
||||
plainShader->u_color = color;
|
||||
backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0));
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
depthRange(strata + strata_epsilon, 1.0f);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
depthRange(strata + strata_epsilon, 1.0f);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
mat4 Painter::translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor) {
|
||||
|
||||
@@ -235,6 +235,7 @@ void StyleLayer::applyStyleProperties<BackgroundProperties>(const float z, const
|
||||
BackgroundProperties &background = properties.get<BackgroundProperties>();
|
||||
applyTransitionedStyleProperty(PropertyKey::BackgroundOpacity, background.opacity, z, now);
|
||||
applyTransitionedStyleProperty(PropertyKey::BackgroundColor, background.color, z, now);
|
||||
applyStyleProperty(PropertyKey::BackgroundImage, background.image, z, now);
|
||||
}
|
||||
|
||||
void StyleLayer::updateProperties(float z, const timestamp now) {
|
||||
|
||||
@@ -640,6 +640,7 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) {
|
||||
|
||||
parseOptionalProperty<Function<float>>("background-opacity", Key::BackgroundOpacity, klass, value);
|
||||
parseOptionalProperty<Function<Color>>("background-color", Key::BackgroundColor, klass, value);
|
||||
parseOptionalProperty<std::string>("background-image", Key::BackgroundImage, klass, value);
|
||||
}
|
||||
|
||||
void StyleParser::parseReference(JSVal value, util::ptr<StyleLayer> &layer) {
|
||||
|
||||
@@ -38,7 +38,51 @@ void matrix::identity(mat3& out) {
|
||||
out[8] = 1.0f;
|
||||
}
|
||||
|
||||
void matrix::scale(mat3& out, const mat3& a, const float x, const float y) {
|
||||
void matrix::translate(mat3& out, const mat3& a, float x, float y) {
|
||||
float a00 = a[0], a01 = a[1], a02 = a[2],
|
||||
a10 = a[3], a11 = a[4], a12 = a[5],
|
||||
a20 = a[6], a21 = a[7], a22 = a[8];
|
||||
|
||||
out[0] = a00;
|
||||
out[1] = a01;
|
||||
out[2] = a02;
|
||||
|
||||
out[3] = a10;
|
||||
out[4] = a11;
|
||||
out[5] = a12;
|
||||
|
||||
out[6] = x * a00 + y * a10 + a20;
|
||||
out[7] = x * a01 + y * a11 + a21;
|
||||
out[8] = x * a02 + y * a12 + a22;
|
||||
}
|
||||
|
||||
void matrix::rotate(mat3& out, const mat3& a, float rad) {
|
||||
float s = std::sin(rad),
|
||||
c = std::cos(rad),
|
||||
a00 = a[0],
|
||||
a01 = a[1],
|
||||
a02 = a[2],
|
||||
a10 = a[3],
|
||||
a11 = a[4],
|
||||
a12 = a[5],
|
||||
a20 = a[6],
|
||||
a21 = a[7],
|
||||
a22 = a[8];
|
||||
|
||||
out[0] = c * a00 + s * a10;
|
||||
out[1] = c * a01 + s * a11;
|
||||
out[2] = c * a02 + s * a12;
|
||||
|
||||
out[3] = c * a10 - s * a00;
|
||||
out[4] = c * a11 - s * a01;
|
||||
out[5] = c * a12 - s * a02;
|
||||
|
||||
out[6] = a20;
|
||||
out[7] = a21;
|
||||
out[8] = a22;
|
||||
};
|
||||
|
||||
void matrix::scale(mat3& out, const mat3& a, float x, float y) {
|
||||
out[0] = x * a[0];
|
||||
out[1] = x * a[1];
|
||||
out[2] = x * a[2];
|
||||
|
||||
Reference in New Issue
Block a user