Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Port background-image from JS #394

Merged
merged 1 commit into from
Oct 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion include/mbgl/map/transform_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ class TransformState {
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
Expand Down
3 changes: 2 additions & 1 deletion include/mbgl/style/property_key.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ enum class PropertyKey {
RasterFade,

BackgroundOpacity,
BackgroundColor
BackgroundColor,
BackgroundImage
};

}
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/style_properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down
2 changes: 2 additions & 0 deletions include/mbgl/util/mat3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}
Expand Down
30 changes: 27 additions & 3 deletions src/map/transform_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,48 @@ 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

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 {
Expand Down
67 changes: 56 additions & 11 deletions src/renderer/painter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();

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;

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) {
Expand Down
1 change: 1 addition & 0 deletions src/style/style_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions src/style/style_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
46 changes: 45 additions & 1 deletion src/util/mat3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down