summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2017-06-16 10:42:33 -0400
committerAnsis Brammanis <brammanis@gmail.com>2017-07-11 09:10:24 -0700
commite514138b691615be24f484986c40f486223df82a (patch)
tree4cab221d92f66feefd132818a700c47cc67ef245 /src/mbgl/renderer
parent77734cfe1b9e77a0058fa3e0db79e3c20a264165 (diff)
downloadqtlocation-mapboxgl-e514138b691615be24f484986c40f486223df82a.tar.gz
[core] improve legibility of labels that follow lines
port https://github.com/mapbox/mapbox-gl-js/pull/4781 This improves legibility of labels that follow lines in pitched views. The previous approach used the limited information in the shader to calculate put the glyph in approximatelyright place. The new approach does this more accurately by doing it on the cpu where we have access to the entire line geometry.
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp4
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp24
-rw-r--r--src/mbgl/renderer/frame_history.cpp4
-rw-r--r--src/mbgl/renderer/frame_history.hpp1
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp2
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.hpp1
-rw-r--r--src/mbgl/renderer/painters/painter_symbol.cpp29
-rw-r--r--src/mbgl/renderer/render_tile.cpp27
-rw-r--r--src/mbgl/renderer/render_tile.hpp4
9 files changed, 75 insertions, 21 deletions
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index 28e6a47250..194a5d6bd8 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -38,14 +38,14 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo
void SymbolBucket::upload(gl::Context& context) {
if (hasTextData()) {
text.vertexBuffer = context.createVertexBuffer(std::move(text.vertices));
+ text.dynamicVertexBuffer = context.createVertexBuffer(std::move(text.dynamicVertices), gl::BufferUsageType::StreamDraw);
text.indexBuffer = context.createIndexBuffer(std::move(text.triangles));
- textSizeBinder->upload(context);
}
if (hasIconData()) {
icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices));
+ icon.dynamicVertexBuffer = context.createVertexBuffer(std::move(icon.dynamicVertices), gl::BufferUsageType::StreamDraw);
icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles));
- iconSizeBinder->upload(context);
}
if (!collisionBox.vertices.empty()) {
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index 002b6e28b3..ffa22e9021 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -15,6 +15,23 @@
namespace mbgl {
+class PlacedSymbol {
+public:
+ PlacedSymbol(Point<float> anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_,
+ std::array<float, 2> lineOffset_, float placementZoom_, bool useVerticalMode_, GeometryCoordinates line_) :
+ anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_),
+ lineOffset(lineOffset_), placementZoom(placementZoom_), useVerticalMode(useVerticalMode_), line(std::move(line_)) {}
+ Point<float> anchorPoint;
+ uint16_t segment;
+ float lowerSize;
+ float upperSize;
+ std::array<float, 2> lineOffset;
+ float placementZoom;
+ bool useVerticalMode;
+ GeometryCoordinates line;
+ std::vector<float> glyphOffsets;
+};
+
class SymbolBucket : public Bucket {
public:
SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated,
@@ -44,10 +61,13 @@ public:
struct TextBuffer {
gl::VertexVector<SymbolLayoutVertex> vertices;
+ gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex> dynamicVertices;
gl::IndexVector<gl::Triangles> triangles;
gl::SegmentVector<SymbolTextAttributes> segments;
+ std::vector<PlacedSymbol> placedSymbols;
optional<gl::VertexBuffer<SymbolLayoutVertex>> vertexBuffer;
+ optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer;
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
} text;
@@ -55,11 +75,14 @@ public:
struct IconBuffer {
gl::VertexVector<SymbolLayoutVertex> vertices;
+ gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex> dynamicVertices;
gl::IndexVector<gl::Triangles> triangles;
gl::SegmentVector<SymbolIconAttributes> segments;
+ std::vector<PlacedSymbol> placedSymbols;
PremultipliedImage atlasImage;
optional<gl::VertexBuffer<SymbolLayoutVertex>> vertexBuffer;
+ optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer;
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
} icon;
@@ -69,6 +92,7 @@ public:
gl::SegmentVector<CollisionBoxAttributes> segments;
optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer;
+ optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer;
optional<gl::IndexBuffer<gl::Lines>> indexBuffer;
} collisionBox;
};
diff --git a/src/mbgl/renderer/frame_history.cpp b/src/mbgl/renderer/frame_history.cpp
index 869222b4eb..de153b6963 100644
--- a/src/mbgl/renderer/frame_history.cpp
+++ b/src/mbgl/renderer/frame_history.cpp
@@ -74,4 +74,8 @@ void FrameHistory::bind(gl::Context& context, uint32_t unit) {
context.bindTexture(*texture, unit);
}
+bool FrameHistory::isVisible(const float zoom) const {
+ return opacities.data[std::floor(zoom * 10)] != 0;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/frame_history.hpp b/src/mbgl/renderer/frame_history.hpp
index f2b11f5f41..75a8b60a71 100644
--- a/src/mbgl/renderer/frame_history.hpp
+++ b/src/mbgl/renderer/frame_history.hpp
@@ -22,6 +22,7 @@ public:
bool needsAnimation(const Duration&) const;
void bind(gl::Context&, uint32_t);
void upload(gl::Context&, uint32_t);
+ bool isVisible(const float zoom) const;
private:
std::array<TimePoint, 256> changeTimes;
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index 573e9db72e..2fe6dd971e 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -84,6 +84,7 @@ style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::S
return style::SymbolPropertyValues {
layout_.get<style::IconRotationAlignment>(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment
layout_.get<style::IconRotationAlignment>(),
+ layout_.get<style::IconKeepUpright>(),
evaluated.get<style::IconTranslate>(),
evaluated.get<style::IconTranslateAnchor>(),
evaluated.get<style::IconHaloColor>().constantOr(Color::black()).a > 0 &&
@@ -109,6 +110,7 @@ style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::S
return style::SymbolPropertyValues {
layout_.get<style::TextPitchAlignment>(),
layout_.get<style::TextRotationAlignment>(),
+ layout_.get<style::TextKeepUpright>(),
evaluated.get<style::TextTranslate>(),
evaluated.get<style::TextTranslateAnchor>(),
evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0 &&
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp
index e788336cbd..a201b6298f 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp
@@ -40,6 +40,7 @@ public:
// Layout
AlignmentType pitchAlignment;
AlignmentType rotationAlignment;
+ bool keepUpright;
// Paint
std::array<float, 2> translate;
diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp
index dc80f096f4..51c3967ae7 100644
--- a/src/mbgl/renderer/painters/painter_symbol.cpp
+++ b/src/mbgl/renderer/painters/painter_symbol.cpp
@@ -10,6 +10,7 @@
#include <mbgl/programs/collision_box_program.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/tile/geometry_tile.hpp>
+#include <mbgl/layout/symbol_projection.hpp>
#include <cmath>
@@ -52,6 +53,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
colorModeForRenderPass(),
std::move(uniformValues),
*buffers.vertexBuffer,
+ *buffers.dynamicVertexBuffer,
*symbolSizeBinder,
*buffers.indexBuffer,
buffers.segments,
@@ -64,10 +66,19 @@ void Painter::renderSymbol(PaintParameters& parameters,
assert(dynamic_cast<GeometryTile*>(&tile.tile));
GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile);
+
if (bucket.hasIconData()) {
auto values = layer.iconPropertyValues(layout);
auto paintPropertyValues = layer.iconPaintProperties();
+ const bool alongLine = bucket.layout.get<SymbolPlacement>() == SymbolPlacementType::Line &&
+ bucket.layout.get<IconRotationAlignment>() == AlignmentType::Map;
+
+ if (alongLine) {
+ reprojectLineLabels(bucket.icon.dynamicVertices, bucket.icon.placedSymbols, tile.matrix, values, tile, *(bucket.iconSizeBinder), state, frameHistory);
+ context.updateVertexBuffer(*bucket.icon.dynamicVertexBuffer, std::move(bucket.icon.dynamicVertices));
+ }
+
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear;
const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || state.getPitch() != 0;
@@ -80,7 +91,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
if (bucket.sdfIcons) {
if (values.hasHalo) {
draw(parameters.programs.symbolIconSDF,
- SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Halo),
+ SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Halo),
bucket.icon,
bucket.iconSizeBinder,
values,
@@ -90,7 +101,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
if (values.hasFill) {
draw(parameters.programs.symbolIconSDF,
- SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Fill),
+ SymbolSDFIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Fill),
bucket.icon,
bucket.iconSizeBinder,
values,
@@ -99,7 +110,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
}
} else {
draw(parameters.programs.symbolIcon,
- SymbolIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, tile, state),
+ SymbolIconProgram::uniformValues(false, values, texsize, pixelsToGLUnits, alongLine, tile, state),
bucket.icon,
bucket.iconSizeBinder,
values,
@@ -114,11 +125,19 @@ void Painter::renderSymbol(PaintParameters& parameters,
auto values = layer.textPropertyValues(layout);
auto paintPropertyValues = layer.textPaintProperties();
+ const bool alongLine = bucket.layout.get<SymbolPlacement>() == SymbolPlacementType::Line &&
+ bucket.layout.get<TextRotationAlignment>() == AlignmentType::Map;
+
+ if (alongLine) {
+ reprojectLineLabels(bucket.text.dynamicVertices, bucket.text.placedSymbols, tile.matrix, values, tile, *(bucket.textSizeBinder), state, frameHistory);
+ context.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices));
+ }
+
const Size texsize = geometryTile.glyphAtlasTexture->size;
if (values.hasHalo) {
draw(parameters.programs.symbolGlyph,
- SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Halo),
+ SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Halo),
bucket.text,
bucket.textSizeBinder,
values,
@@ -128,7 +147,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
if (values.hasFill) {
draw(parameters.programs.symbolGlyph,
- SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, tile, state, SymbolSDFPart::Fill),
+ SymbolSDFTextProgram::uniformValues(true, values, texsize, pixelsToGLUnits, alongLine, tile, state, SymbolSDFPart::Fill),
bucket.text,
bucket.textSizeBinder,
values,
diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp
index 59c3ea076b..7e7e3e6d23 100644
--- a/src/mbgl/renderer/render_tile.cpp
+++ b/src/mbgl/renderer/render_tile.cpp
@@ -2,6 +2,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/tile/tile.hpp>
+#include <mbgl/util/math.hpp>
namespace mbgl {
@@ -10,24 +11,26 @@ using namespace style;
mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix,
const std::array<float, 2>& translation,
TranslateAnchorType anchor,
- const TransformState& state) const {
+ const TransformState& state,
+ const bool inViewportPixelUnits) const {
if (translation[0] == 0 && translation[1] == 0) {
return tileMatrix;
}
mat4 vtxMatrix;
- if (anchor == TranslateAnchorType::Viewport) {
- const double sin_a = std::sin(-state.getAngle());
- const double cos_a = std::cos(-state.getAngle());
- matrix::translate(vtxMatrix, tileMatrix,
- id.pixelsToTileUnits(translation[0] * cos_a - translation[1] * sin_a, state.getZoom()),
- id.pixelsToTileUnits(translation[0] * sin_a + translation[1] * cos_a, state.getZoom()),
- 0);
+ const float angle = inViewportPixelUnits ?
+ (anchor == TranslateAnchorType::Map ? state.getAngle() : 0) :
+ (anchor == TranslateAnchorType::Viewport ? -state.getAngle() : 0);
+
+ Point<float> translate = util::rotate(Point<float>{ translation[0], translation[1] }, angle);
+
+ if (inViewportPixelUnits) {
+ matrix::translate(vtxMatrix, tileMatrix, translate.x, translate.y, 0);
} else {
matrix::translate(vtxMatrix, tileMatrix,
- id.pixelsToTileUnits(translation[0], state.getZoom()),
- id.pixelsToTileUnits(translation[1], state.getZoom()),
+ id.pixelsToTileUnits(translate.x, state.getZoom()),
+ id.pixelsToTileUnits(translate.y, state.getZoom()),
0);
}
@@ -37,13 +40,13 @@ mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix,
mat4 RenderTile::translatedMatrix(const std::array<float, 2>& translation,
TranslateAnchorType anchor,
const TransformState& state) const {
- return translateVtxMatrix(matrix, translation, anchor, state);
+ return translateVtxMatrix(matrix, translation, anchor, state, false);
}
mat4 RenderTile::translatedClipMatrix(const std::array<float, 2>& translation,
TranslateAnchorType anchor,
const TransformState& state) const {
- return translateVtxMatrix(nearClippedMatrix, translation, anchor, state);
+ return translateVtxMatrix(nearClippedMatrix, translation, anchor, state, false);
}
void RenderTile::startRender(Painter& painter) {
diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp
index 07e2d699f7..6d374c29cb 100644
--- a/src/mbgl/renderer/render_tile.hpp
+++ b/src/mbgl/renderer/render_tile.hpp
@@ -38,11 +38,11 @@ public:
void startRender(Painter&);
-private:
mat4 translateVtxMatrix(const mat4& tileMatrix,
const std::array<float, 2>& translation,
style::TranslateAnchorType anchor,
- const TransformState& state) const;
+ const TransformState& state,
+ const bool inViewportPixelUnits) const;
};
} // namespace mbgl