summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-10-26 19:36:43 +0300
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-11-18 09:13:53 +0100
commitce14037b552eafa9fa8da50f64bc562d95001309 (patch)
tree1d4ad3e8e7334a1062cd16ce1907d821d8c3954e
parent38fcbe21d48186c4630a3b8a76d1b20e156faadd (diff)
downloadqtlocation-mapboxgl-ce14037b552eafa9fa8da50f64bc562d95001309.tar.gz
[core] Cleanup symbol clipping
-rw-r--r--src/mbgl/layout/symbol_layout.cpp31
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp18
2 files changed, 21 insertions, 28 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 9ea779d47b..b18491bf78 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -262,8 +262,6 @@ void SymbolLayout::addFeature(const GeometryCollection &lines,
const SymbolPlacementType iconPlacement = layout.get<IconRotationAlignment>() != AlignmentType::Map
? SymbolPlacementType::Point
: layout.get<SymbolPlacement>();
- const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
- layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>();
const bool isLine = layout.get<SymbolPlacement>() == SymbolPlacementType::Line;
const float textRepeatDistance = symbolSpacing / 2;
@@ -289,22 +287,25 @@ void SymbolLayout::addFeature(const GeometryCollection &lines,
}
}
- const bool inside = !(anchor.point.x < 0 || anchor.point.x > util::EXTENT || anchor.point.y < 0 || anchor.point.y > util::EXTENT);
+ // https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers
+ // +-------------------+ Symbols with anchors located on tile edges
+ // |(0,0) || are duplicated on neighbor tiles.
+ // | ||
+ // | || In continuous mode, to avoid overdraw we
+ // | || skip symbols located on the extent edges.
+ // | Tile || In still mode, we include the features in
+ // | || the buffers for both tiles and clip them
+ // | || at draw time.
+ // | ||
+ // +-------------------| In this scenario, the inner bounding box
+ // +-------------------+ is called 'withinPlus0', and the outer
+ // (extent,extent) is called 'inside'.
+ const bool withinPlus0 = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT;
+ const bool inside = withinPlus0 || anchor.point.x == util::EXTENT || anchor.point.y == util::EXTENT;
if (avoidEdges && !inside) continue;
- // Normally symbol layers are drawn across tile boundaries. Only symbols
- // with their anchors within the tile boundaries are added to the buffers
- // to prevent symbols from being drawn twice.
- //
- // Symbols in layers with overlap are sorted in the y direction so that
- // symbols lower on the canvas are drawn on top of symbols near the top.
- // To preserve this order across tile boundaries these symbols can't
- // be drawn across tile boundaries. Instead they need to be included in
- // the buffers for both tiles and clipped to tile boundaries at draw time.
- //
- // TODO remove the `&& false` when is #1673 implemented
- const bool addToBuffers = (mode == MapMode::Still) || inside || (mayOverlap && false);
+ const bool addToBuffers = mode == MapMode::Still || withinPlus0;
symbolInstances.emplace_back(anchor, line, shapedText, shapedIcon, layout, addToBuffers, symbolInstances.size(),
textBoxScale, textPadding, textPlacement,
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index d4effe3f9d..39075976a0 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -35,16 +35,8 @@ void Painter::renderSymbol(PaintParameters& parameters,
const auto& buffers,
const SymbolPropertyValues& values_)
{
- // In some cases, we disable the stencil test so that labels aren't clipped
- // to tile boundaries.
- //
- // Layers with features that may be drawn overlapping aren't clipped. These
- // layers are sorted in the y direction, and to draw the correct ordering near
- // tile edges the icons are included in both tiles and clipped when drawing.
- //
- // TODO remove the `true ||` when #1673 is implemented
- const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
- layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>()));
+ // We clip symbols to their tile extent in still mode.
+ const bool needsClipping = frame.mapMode == MapMode::Still;
program.draw(
context,
@@ -52,9 +44,9 @@ void Painter::renderSymbol(PaintParameters& parameters,
values_.pitchAlignment == AlignmentType::Map
? depthModeForSublayer(0, gl::DepthMode::ReadOnly)
: gl::DepthMode::disabled(),
- drawAcrossEdges
- ? gl::StencilMode::disabled()
- : stencilModeForClipping(tile.clip),
+ needsClipping
+ ? stencilModeForClipping(tile.clip)
+ : gl::StencilMode::disabled(),
colorModeForRenderPass(),
std::move(uniformValues),
*buffers.vertexBuffer,