background-image support

This commit is contained in:
John Firebaugh
2014-08-26 15:24:16 -07:00
parent 48a3104066
commit 4603ca037c
9 changed files with 142 additions and 17 deletions

View File

@@ -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

View File

@@ -61,7 +61,8 @@ enum class PropertyKey {
RasterFade,
BackgroundOpacity,
BackgroundColor
BackgroundColor,
BackgroundImage
};
}

View File

@@ -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<

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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];