summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-06-21 17:22:51 -0700
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-07-01 19:47:35 +0300
commita17b0bcd82ebe8628b69588d19773d26596b86da (patch)
tree06e53bf42b059b28780e995020733aaaeb6487b1 /src/mbgl/renderer
parenteb7cfea7eacad8a179fb3167b88508f8f1f7fdd2 (diff)
downloadqtlocation-mapboxgl-a17b0bcd82ebe8628b69588d19773d26596b86da.tar.gz
[core] Fix overdraw mode on Linux
- Use glBindAttribLocation for GLSL attributes. - Create a separate shader for each shader that supports overdraw. Needed because each uniform location must be known for every program. - Create a separate VAO for each shader inside buckets. Needed because we can only bind a VAO to a specific shader. Fixes #5435.
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp16
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp12
-rw-r--r--src/mbgl/renderer/line_bucket.cpp12
-rw-r--r--src/mbgl/renderer/line_bucket.hpp8
-rw-r--r--src/mbgl/renderer/painter.cpp18
-rw-r--r--src/mbgl/renderer/painter.hpp23
-rw-r--r--src/mbgl/renderer/painter_background.cpp47
-rw-r--r--src/mbgl/renderer/painter_circle.cpp20
-rw-r--r--src/mbgl/renderer/painter_fill.cpp113
-rw-r--r--src/mbgl/renderer/painter_line.cpp120
-rw-r--r--src/mbgl/renderer/painter_raster.cpp24
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp35
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp12
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp10
14 files changed, 259 insertions, 211 deletions
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index cd69f43375..c927071850 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -119,48 +119,48 @@ bool FillBucket::needsClipping() const {
return true;
}
-void FillBucket::drawElements(PlainShader& shader, gl::ObjectStore& store) {
+void FillBucket::drawElements(PlainShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
assert(group);
- group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
+ group->array[overdraw ? 1 : 0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
-void FillBucket::drawElements(PatternShader& shader, gl::ObjectStore& store) {
+void FillBucket::drawElements(PatternShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
assert(group);
- group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
+ group->array[overdraw ? 3 : 2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
-void FillBucket::drawVertices(OutlineShader& shader, gl::ObjectStore& store) {
+void FillBucket::drawVertices(OutlineShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
assert(group);
- group->array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, store);
+ group->array[overdraw ? 1 : 0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * lineElementsBuffer.itemSize;
}
}
-void FillBucket::drawVertices(OutlinePatternShader& shader, gl::ObjectStore& store) {
+void FillBucket::drawVertices(OutlinePatternShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
assert(group);
- group->array[1].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, store);
+ group->array[overdraw? 3 : 2].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * lineElementsBuffer.itemSize;
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index 3387ab3746..7508445579 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -27,18 +27,18 @@ public:
void addGeometry(const GeometryCollection&);
- void drawElements(PlainShader&, gl::ObjectStore&);
- void drawElements(PatternShader&, gl::ObjectStore&);
- void drawVertices(OutlineShader&, gl::ObjectStore&);
- void drawVertices(OutlinePatternShader&, gl::ObjectStore&);
+ void drawElements(PlainShader&, gl::ObjectStore&, bool overdraw);
+ void drawElements(PatternShader&, gl::ObjectStore&, bool overdraw);
+ void drawVertices(OutlineShader&, gl::ObjectStore&, bool overdraw);
+ void drawVertices(OutlinePatternShader&, gl::ObjectStore&, bool overdraw);
private:
FillVertexBuffer vertexBuffer;
TriangleElementsBuffer triangleElementsBuffer;
LineElementsBuffer lineElementsBuffer;
- typedef ElementGroup<2> TriangleGroup;
- typedef ElementGroup<2> LineGroup;
+ typedef ElementGroup<4> TriangleGroup;
+ typedef ElementGroup<4> LineGroup;
std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
std::vector<std::unique_ptr<LineGroup>> lineGroups;
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 611c2d685d..e9a8e78618 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -460,7 +460,7 @@ bool LineBucket::needsClipping() const {
return true;
}
-void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store) {
+void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
@@ -468,7 +468,7 @@ void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store) {
if (!group->elements_length) {
continue;
}
- group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
+ group->array[overdraw ? 1 : 0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
@@ -476,7 +476,7 @@ void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store) {
}
}
-void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store) {
+void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
@@ -484,7 +484,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store) {
if (!group->elements_length) {
continue;
}
- group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
+ group->array[overdraw ? 3 : 2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
@@ -492,7 +492,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store) {
}
}
-void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::ObjectStore& store) {
+void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
@@ -500,7 +500,7 @@ void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::ObjectStore& st
if (!group->elements_length) {
continue;
}
- group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
+ group->array[overdraw ? 5 : 4].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index db5e74cd3b..5ece05b03b 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -18,7 +18,7 @@ class LineSDFShader;
class LinepatternShader;
class LineBucket : public Bucket {
- using TriangleGroup = ElementGroup<3>;
+ using TriangleGroup = ElementGroup<6>;
public:
LineBucket(uint32_t overscaling);
@@ -32,9 +32,9 @@ public:
void addGeometry(const GeometryCollection&);
void addGeometry(const GeometryCoordinates& line);
- void drawLines(LineShader&, gl::ObjectStore&);
- void drawLineSDF(LineSDFShader&, gl::ObjectStore&);
- void drawLinePatterns(LinepatternShader&, gl::ObjectStore&);
+ void drawLines(LineShader&, gl::ObjectStore&, bool overdraw);
+ void drawLineSDF(LineSDFShader&, gl::ObjectStore&, bool overdraw);
+ void drawLinePatterns(LinepatternShader&, gl::ObjectStore&, bool overdraw);
private:
struct TriangleElement {
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index bfe0174137..7661d80e9c 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -64,11 +64,25 @@ Painter::Painter(const TransformState& state_,
patternShader = std::make_unique<PatternShader>(store);
iconShader = std::make_unique<IconShader>(store);
rasterShader = std::make_unique<RasterShader>(store);
- sdfGlyphShader = std::make_unique<SDFGlyphShader>(store);
- sdfIconShader = std::make_unique<SDFIconShader>(store);
+ sdfGlyphShader = std::make_unique<SDFShader>(store);
+ sdfIconShader = std::make_unique<SDFShader>(store);
collisionBoxShader = std::make_unique<CollisionBoxShader>(store);
circleShader = std::make_unique<CircleShader>(store);
+ bool overdraw = true;
+ plainOverdrawShader = std::make_unique<PlainShader>(store, overdraw);
+ outlineOverdrawShader = std::make_unique<OutlineShader>(store, overdraw);
+ outlinePatternOverdrawShader = std::make_unique<OutlinePatternShader>(store, overdraw);
+ lineOverdrawShader = std::make_unique<LineShader>(store, overdraw);
+ linesdfOverdrawShader = std::make_unique<LineSDFShader>(store, overdraw);
+ linepatternOverdrawShader = std::make_unique<LinepatternShader>(store, overdraw);
+ patternOverdrawShader = std::make_unique<PatternShader>(store, overdraw);
+ iconOverdrawShader = std::make_unique<IconShader>(store, overdraw);
+ rasterOverdrawShader = std::make_unique<RasterShader>(store, overdraw);
+ sdfGlyphOverdrawShader = std::make_unique<SDFShader>(store, overdraw);
+ sdfIconOverdrawShader = std::make_unique<SDFShader>(store, overdraw);
+ circleOverdrawShader = std::make_unique<CircleShader>(store, overdraw);
+
// Reset GL values
config.reset();
}
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 1f511467d0..197466e94c 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -53,8 +53,6 @@ class CircleShader;
class PatternShader;
class IconShader;
class RasterShader;
-class SDFGlyphShader;
-class SDFIconShader;
class CollisionBoxShader;
struct ClipID;
@@ -137,7 +135,7 @@ private:
float scaleDivisor,
std::array<float, 2> texsize,
SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&),
+ void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, bool),
// Layout
style::AlignmentType rotationAlignment,
@@ -208,11 +206,24 @@ private:
std::unique_ptr<PatternShader> patternShader;
std::unique_ptr<IconShader> iconShader;
std::unique_ptr<RasterShader> rasterShader;
- std::unique_ptr<SDFGlyphShader> sdfGlyphShader;
- std::unique_ptr<SDFIconShader> sdfIconShader;
+ std::unique_ptr<SDFShader> sdfGlyphShader;
+ std::unique_ptr<SDFShader> sdfIconShader;
std::unique_ptr<CollisionBoxShader> collisionBoxShader;
std::unique_ptr<CircleShader> circleShader;
+ std::unique_ptr<PlainShader> plainOverdrawShader;
+ std::unique_ptr<OutlineShader> outlineOverdrawShader;
+ std::unique_ptr<OutlinePatternShader> outlinePatternOverdrawShader;
+ std::unique_ptr<LineShader> lineOverdrawShader;
+ std::unique_ptr<LineSDFShader> linesdfOverdrawShader;
+ std::unique_ptr<LinepatternShader> linepatternOverdrawShader;
+ std::unique_ptr<PatternShader> patternOverdrawShader;
+ std::unique_ptr<IconShader> iconOverdrawShader;
+ std::unique_ptr<RasterShader> rasterOverdrawShader;
+ std::unique_ptr<SDFShader> sdfGlyphOverdrawShader;
+ std::unique_ptr<SDFShader> sdfIconOverdrawShader;
+ std::unique_ptr<CircleShader> circleOverdrawShader;
+
// Set up the stencil quad we're using to generate the stencil mask.
StaticVertexBuffer tileStencilBuffer = {
// top left triangle
@@ -241,6 +252,8 @@ private:
};
VertexArrayObject tileBorderArray;
+
+ VertexArrayObject coveringRasterOverdrawArray;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index 7ced6a5c4f..507d5f0f22 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -21,6 +21,9 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
optional<SpriteAtlasPosition> imagePosA;
optional<SpriteAtlasPosition> imagePosB;
+ const auto& shaderPattern = isOverdraw() ? patternOverdrawShader : patternShader;
+ const auto& shaderPlain = isOverdraw() ? plainOverdrawShader : plainShader;
+
if (isPatterned) {
imagePosA = spriteAtlas->getPosition(properties.backgroundPattern.value.from, true);
imagePosB = spriteAtlas->getPosition(properties.backgroundPattern.value.to, true);
@@ -28,24 +31,24 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
if (!imagePosA || !imagePosB)
return;
- config.program = isOverdraw() ? patternShader->getOverdrawID() : patternShader->getID();
- patternShader->u_matrix = identityMatrix;
- patternShader->u_pattern_tl_a = imagePosA->tl;
- patternShader->u_pattern_br_a = imagePosA->br;
- patternShader->u_pattern_tl_b = imagePosB->tl;
- patternShader->u_pattern_br_b = imagePosB->br;
- patternShader->u_mix = properties.backgroundPattern.value.t;
- patternShader->u_opacity = properties.backgroundOpacity;
+ config.program = shaderPattern->getID();
+ shaderPattern->u_matrix = identityMatrix;
+ shaderPattern->u_pattern_tl_a = imagePosA->tl;
+ shaderPattern->u_pattern_br_a = imagePosA->br;
+ shaderPattern->u_pattern_tl_b = imagePosB->tl;
+ shaderPattern->u_pattern_br_b = imagePosB->br;
+ shaderPattern->u_mix = properties.backgroundPattern.value.t;
+ shaderPattern->u_opacity = properties.backgroundOpacity;
spriteAtlas->bind(true, store);
- backgroundPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0), store);
+ backgroundPatternArray.bind(*shaderPattern, tileStencilBuffer, BUFFER_OFFSET(0), store);
} else {
- plainShader->u_color = properties.backgroundColor;
- plainShader->u_opacity = properties.backgroundOpacity;
+ config.program = shaderPlain->getID();
+ shaderPlain->u_color = properties.backgroundColor;
+ shaderPlain->u_opacity = properties.backgroundOpacity;
- config.program = isOverdraw() ? plainShader->getOverdrawID() : plainShader->getID();
- backgroundArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0), store);
+ backgroundArray.bind(*shaderPlain, tileStencilBuffer, BUFFER_OFFSET(0), store);
}
config.stencilTest = GL_FALSE;
@@ -60,20 +63,20 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
matrix::multiply(vertexMatrix, projMatrix, vertexMatrix);
if (isPatterned) {
- patternShader->u_matrix = vertexMatrix;
- patternShader->u_pattern_size_a = imagePosA->size;
- patternShader->u_pattern_size_b = imagePosB->size;
- patternShader->u_scale_a = properties.backgroundPattern.value.fromScale;
- patternShader->u_scale_b = properties.backgroundPattern.value.toScale;
- patternShader->u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
+ shaderPattern->u_matrix = vertexMatrix;
+ shaderPattern->u_pattern_size_a = imagePosA->size;
+ shaderPattern->u_pattern_size_b = imagePosB->size;
+ shaderPattern->u_scale_a = properties.backgroundPattern.value.fromScale;
+ shaderPattern->u_scale_b = properties.backgroundPattern.value.toScale;
+ shaderPattern->u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
GLint tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z);
GLint pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z));
GLint pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
- patternShader->u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
- patternShader->u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
+ shaderPattern->u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
+ shaderPattern->u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
} else {
- plainShader->u_matrix = vertexMatrix;
+ shaderPlain->u_matrix = vertexMatrix;
}
MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)tileStencilBuffer.index()));
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index e72f8a994f..2dc25e32b5 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -27,17 +27,19 @@ void Painter::renderCircle(CircleBucket& bucket,
mat4 vtxMatrix = translatedMatrix(matrix, properties.circleTranslate, tileID,
properties.circleTranslateAnchor);
- config.program = isOverdraw() ? circleShader->getOverdrawID() : circleShader->getID();
+ const auto& shader = isOverdraw() ? circleOverdrawShader : circleShader;
- circleShader->u_matrix = vtxMatrix;
- circleShader->u_extrude_scale = extrudeScale;
- circleShader->u_devicepixelratio = frame.pixelRatio;
- circleShader->u_color = properties.circleColor;
- circleShader->u_radius = properties.circleRadius;
- circleShader->u_blur = properties.circleBlur;
- circleShader->u_opacity = properties.circleOpacity;
+ config.program = shader->getID();
- bucket.drawCircles(*circleShader, store);
+ shader->u_matrix = vtxMatrix;
+ shader->u_extrude_scale = extrudeScale;
+ shader->u_devicepixelratio = frame.pixelRatio;
+ shader->u_color = properties.circleColor;
+ shader->u_radius = properties.circleRadius;
+ shader->u_blur = properties.circleBlur;
+ shader->u_opacity = properties.circleOpacity;
+
+ bucket.drawCircles(*shader, store);
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 44cdbe7411..290b81cb06 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -43,17 +43,24 @@ void Painter::renderFill(FillBucket& bucket,
config.depthMask = GL_TRUE;
config.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio!
+ const bool overdraw = isOverdraw();
+ const auto& shaderOutline = overdraw ? outlineOverdrawShader : outlineShader;
+ const auto& shaderPattern = overdraw ? patternOverdrawShader : patternShader;
+ const auto& shaderOutlinePattern = overdraw ? outlinePatternOverdrawShader : outlinePatternShader;
+ const auto& shaderPlain = overdraw ? plainOverdrawShader : plainShader;
+
// Because we're drawing top-to-bottom, and we update the stencil mask
// befrom, we have to draw the outline first (!)
if (outline && pass == RenderPass::Translucent) {
- config.program = isOverdraw() ? outlineShader->getOverdrawID() : outlineShader->getID();
- outlineShader->u_matrix = vertexMatrix;
- outlineShader->u_outline_color = strokeColor;
- outlineShader->u_opacity = opacity;
+ config.program = shaderOutline->getID();
+ shaderOutline->u_matrix = vertexMatrix;
+
+ shaderOutline->u_outline_color = strokeColor;
+ shaderOutline->u_opacity = opacity;
// Draw the entire line
- outlineShader->u_world = worldSize;
+ shaderOutline->u_world = worldSize;
if (isOutlineColorDefined) {
// If we defined a different color for the fill outline, we are
// going to ignore the bits in 0x07 and just care about the global
@@ -67,7 +74,7 @@ void Painter::renderFill(FillBucket& bucket,
// the (non-antialiased) fill.
setDepthSublayer(0); // OK
}
- bucket.drawVertices(*outlineShader, store);
+ bucket.drawVertices(*shaderOutline, store, overdraw);
}
if (pattern) {
@@ -76,61 +83,61 @@ void Painter::renderFill(FillBucket& bucket,
// Image fill.
if (pass == RenderPass::Translucent && imagePosA && imagePosB) {
- config.program = isOverdraw() ? patternShader->getOverdrawID() : patternShader->getID();
- patternShader->u_matrix = vertexMatrix;
- patternShader->u_pattern_tl_a = imagePosA->tl;
- patternShader->u_pattern_br_a = imagePosA->br;
- patternShader->u_pattern_tl_b = imagePosB->tl;
- patternShader->u_pattern_br_b = imagePosB->br;
- patternShader->u_opacity = properties.fillOpacity;
- patternShader->u_image = 0;
- patternShader->u_mix = properties.fillPattern.value.t;
- patternShader->u_pattern_size_a = imagePosA->size;
- patternShader->u_pattern_size_b = imagePosB->size;
- patternShader->u_scale_a = properties.fillPattern.value.fromScale;
- patternShader->u_scale_b = properties.fillPattern.value.toScale;
- patternShader->u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
+ config.program = shaderPattern->getID();
+ shaderPattern->u_matrix = vertexMatrix;
+ shaderPattern->u_pattern_tl_a = imagePosA->tl;
+ shaderPattern->u_pattern_br_a = imagePosA->br;
+ shaderPattern->u_pattern_tl_b = imagePosB->tl;
+ shaderPattern->u_pattern_br_b = imagePosB->br;
+ shaderPattern->u_opacity = properties.fillOpacity;
+ shaderPattern->u_image = 0;
+ shaderPattern->u_mix = properties.fillPattern.value.t;
+ shaderPattern->u_pattern_size_a = imagePosA->size;
+ shaderPattern->u_pattern_size_b = imagePosB->size;
+ shaderPattern->u_scale_a = properties.fillPattern.value.fromScale;
+ shaderPattern->u_scale_b = properties.fillPattern.value.toScale;
+ shaderPattern->u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
GLint tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z);
GLint pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z));
GLint pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
- patternShader->u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
- patternShader->u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
+ shaderPattern->u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
+ shaderPattern->u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
config.activeTexture = GL_TEXTURE0;
spriteAtlas->bind(true, store);
// Draw the actual triangles into the color & stencil buffer.
setDepthSublayer(0);
- bucket.drawElements(*patternShader, store);
+ bucket.drawElements(*shaderPattern, store, overdraw);
if (properties.fillAntialias && !isOutlineColorDefined) {
- config.program = isOverdraw() ? outlinePatternShader->getOverdrawID() : outlinePatternShader->getID();
- outlinePatternShader->u_matrix = vertexMatrix;
+ config.program = shaderOutlinePattern->getID();
+ shaderOutlinePattern->u_matrix = vertexMatrix;
// Draw the entire line
- outlineShader->u_world = worldSize;
-
- outlinePatternShader->u_pattern_tl_a = imagePosA->tl;
- outlinePatternShader->u_pattern_br_a = imagePosA->br;
- outlinePatternShader->u_pattern_tl_b = imagePosB->tl;
- outlinePatternShader->u_pattern_br_b = imagePosB->br;
- outlinePatternShader->u_opacity = properties.fillOpacity;
- outlinePatternShader->u_image = 0;
- outlinePatternShader->u_mix = properties.fillPattern.value.t;
- outlinePatternShader->u_pattern_size_a = imagePosA->size;
- outlinePatternShader->u_pattern_size_b = imagePosB->size;
- outlinePatternShader->u_scale_a = properties.fillPattern.value.fromScale;
- outlinePatternShader->u_scale_b = properties.fillPattern.value.toScale;
- outlinePatternShader->u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
- outlinePatternShader->u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
- outlinePatternShader->u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
+ shaderOutline->u_world = worldSize;
+
+ shaderOutlinePattern->u_pattern_tl_a = imagePosA->tl;
+ shaderOutlinePattern->u_pattern_br_a = imagePosA->br;
+ shaderOutlinePattern->u_pattern_tl_b = imagePosB->tl;
+ shaderOutlinePattern->u_pattern_br_b = imagePosB->br;
+ shaderOutlinePattern->u_opacity = properties.fillOpacity;
+ shaderOutlinePattern->u_image = 0;
+ shaderOutlinePattern->u_mix = properties.fillPattern.value.t;
+ shaderOutlinePattern->u_pattern_size_a = imagePosA->size;
+ shaderOutlinePattern->u_pattern_size_b = imagePosB->size;
+ shaderOutlinePattern->u_scale_a = properties.fillPattern.value.fromScale;
+ shaderOutlinePattern->u_scale_b = properties.fillPattern.value.toScale;
+ shaderOutlinePattern->u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
+ shaderOutlinePattern->u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
+ shaderOutlinePattern->u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
config.activeTexture = GL_TEXTURE0;
spriteAtlas->bind(true, store);
setDepthSublayer(2);
- bucket.drawVertices(*outlinePatternShader, store);
+ bucket.drawVertices(*shaderOutlinePattern, store, overdraw);
}
}
} else {
@@ -140,31 +147,31 @@ void Painter::renderFill(FillBucket& bucket,
// fragments or when it's translucent and we're drawing translucent
// fragments
// Draw filling rectangle.
- config.program = isOverdraw() ? plainShader->getOverdrawID() : plainShader->getID();
- plainShader->u_matrix = vertexMatrix;
- plainShader->u_color = fillColor;
- plainShader->u_opacity = opacity;
+ config.program = shaderPlain->getID();
+ shaderPlain->u_matrix = vertexMatrix;
+ shaderPlain->u_color = fillColor;
+ shaderPlain->u_opacity = opacity;
// Draw the actual triangles into the color & stencil buffer.
setDepthSublayer(1);
- bucket.drawElements(*plainShader, store);
+ bucket.drawElements(*shaderPlain, store, overdraw);
}
}
// Because we're drawing top-to-bottom, and we update the stencil mask
// below, we have to draw the outline first (!)
if (fringeline && pass == RenderPass::Translucent) {
- config.program = isOverdraw() ? outlineShader->getOverdrawID() : outlineShader->getID();
- outlineShader->u_matrix = vertexMatrix;
+ config.program = shaderOutline->getID();
+ shaderOutline->u_matrix = vertexMatrix;
- outlineShader->u_outline_color = fillColor;
- outlineShader->u_opacity = opacity;
+ shaderOutline->u_outline_color = fillColor;
+ shaderOutline->u_opacity = opacity;
// Draw the entire line
- outlineShader->u_world = worldSize;
+ shaderOutline->u_world = worldSize;
setDepthSublayer(2);
- bucket.drawVertices(*outlineShader, store);
+ bucket.drawVertices(*shaderOutline, store, overdraw);
}
}
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index 638d0b6f82..84468674dd 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -55,18 +55,22 @@ void Painter::renderLine(LineBucket& bucket,
setDepthSublayer(0);
- if (!properties.lineDasharray.value.from.empty()) {
+ const bool overdraw = isOverdraw();
+ const auto& shaderLineSDF = overdraw ? linesdfOverdrawShader : linesdfShader;
+ const auto& shaderLinePattern = overdraw ? linepatternOverdrawShader : linepatternShader;
+ const auto& shaderLine = overdraw ? lineOverdrawShader : lineShader;
- config.program = isOverdraw() ? linesdfShader->getOverdrawID() : linesdfShader->getID();
+ if (!properties.lineDasharray.value.from.empty()) {
+ config.program = shaderLineSDF->getID();
- linesdfShader->u_matrix = vtxMatrix;
- linesdfShader->u_linewidth = properties.lineWidth / 2;
- linesdfShader->u_gapwidth = properties.lineGapWidth / 2;
- linesdfShader->u_antialiasing = antialiasing / 2;
- linesdfShader->u_ratio = ratio;
- linesdfShader->u_blur = blur;
- linesdfShader->u_color = color;
- linesdfShader->u_opacity = opacity;
+ shaderLineSDF->u_matrix = vtxMatrix;
+ shaderLineSDF->u_linewidth = properties.lineWidth / 2;
+ shaderLineSDF->u_gapwidth = properties.lineGapWidth / 2;
+ shaderLineSDF->u_antialiasing = antialiasing / 2;
+ shaderLineSDF->u_ratio = ratio;
+ shaderLineSDF->u_blur = blur;
+ shaderLineSDF->u_color = color;
+ shaderLineSDF->u_opacity = opacity;
LinePatternPos posA = lineAtlas->getDashPosition(properties.lineDasharray.value.from, layout.lineCap == LineCapType::Round, store);
LinePatternPos posB = lineAtlas->getDashPosition(properties.lineDasharray.value.to, layout.lineCap == LineCapType::Round, store);
@@ -79,21 +83,21 @@ void Painter::renderLine(LineBucket& bucket,
float scaleXB = 1.0 / tileID.pixelsToTileUnits(widthB, state.getIntegerZoom());
float scaleYB = -posB.height / 2.0;
- linesdfShader->u_patternscale_a = {{ scaleXA, scaleYA }};
- linesdfShader->u_tex_y_a = posA.y;
- linesdfShader->u_patternscale_b = {{ scaleXB, scaleYB }};
- linesdfShader->u_tex_y_b = posB.y;
- linesdfShader->u_sdfgamma = lineAtlas->width / (std::min(widthA, widthB) * 256.0 * frame.pixelRatio) / 2;
- linesdfShader->u_mix = properties.lineDasharray.value.t;
- linesdfShader->u_extra = extra;
- linesdfShader->u_offset = -properties.lineOffset;
- linesdfShader->u_antialiasingmatrix = antialiasingMatrix;
-
- linesdfShader->u_image = 0;
+ shaderLineSDF->u_patternscale_a = {{ scaleXA, scaleYA }};
+ shaderLineSDF->u_tex_y_a = posA.y;
+ shaderLineSDF->u_patternscale_b = {{ scaleXB, scaleYB }};
+ shaderLineSDF->u_tex_y_b = posB.y;
+ shaderLineSDF->u_sdfgamma = lineAtlas->width / (std::min(widthA, widthB) * 256.0 * frame.pixelRatio) / 2;
+ shaderLineSDF->u_mix = properties.lineDasharray.value.t;
+ shaderLineSDF->u_extra = extra;
+ shaderLineSDF->u_offset = -properties.lineOffset;
+ shaderLineSDF->u_antialiasingmatrix = antialiasingMatrix;
+
+ shaderLineSDF->u_image = 0;
config.activeTexture = GL_TEXTURE0;
lineAtlas->bind(store);
- bucket.drawLineSDF(*linesdfShader, store);
+ bucket.drawLineSDF(*shaderLineSDF, store, overdraw);
} else if (!properties.linePattern.value.from.empty()) {
optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(properties.linePattern.value.from, true);
@@ -102,58 +106,58 @@ void Painter::renderLine(LineBucket& bucket,
if (!imagePosA || !imagePosB)
return;
- config.program = isOverdraw() ? linepatternShader->getOverdrawID() : linepatternShader->getID();
+ config.program = shaderLinePattern->getID();
- linepatternShader->u_matrix = vtxMatrix;
- linepatternShader->u_linewidth = properties.lineWidth / 2;
- linepatternShader->u_gapwidth = properties.lineGapWidth / 2;
- linepatternShader->u_antialiasing = antialiasing / 2;
- linepatternShader->u_ratio = ratio;
- linepatternShader->u_blur = blur;
+ shaderLinePattern->u_matrix = vtxMatrix;
+ shaderLinePattern->u_linewidth = properties.lineWidth / 2;
+ shaderLinePattern->u_gapwidth = properties.lineGapWidth / 2;
+ shaderLinePattern->u_antialiasing = antialiasing / 2;
+ shaderLinePattern->u_ratio = ratio;
+ shaderLinePattern->u_blur = blur;
- linepatternShader->u_pattern_size_a = {{
+ shaderLinePattern->u_pattern_size_a = {{
tileID.pixelsToTileUnits((*imagePosA).size[0] * properties.linePattern.value.fromScale, state.getIntegerZoom()),
(*imagePosA).size[1]
}};
- linepatternShader->u_pattern_tl_a = (*imagePosA).tl;
- linepatternShader->u_pattern_br_a = (*imagePosA).br;
+ shaderLinePattern->u_pattern_tl_a = (*imagePosA).tl;
+ shaderLinePattern->u_pattern_br_a = (*imagePosA).br;
- linepatternShader->u_pattern_size_b = {{
+ shaderLinePattern->u_pattern_size_b = {{
tileID.pixelsToTileUnits((*imagePosB).size[0] * properties.linePattern.value.toScale, state.getIntegerZoom()),
(*imagePosB).size[1]
}};
- linepatternShader->u_pattern_tl_b = (*imagePosB).tl;
- linepatternShader->u_pattern_br_b = (*imagePosB).br;
+ shaderLinePattern->u_pattern_tl_b = (*imagePosB).tl;
+ shaderLinePattern->u_pattern_br_b = (*imagePosB).br;
- linepatternShader->u_fade = properties.linePattern.value.t;
- linepatternShader->u_opacity = properties.lineOpacity;
- linepatternShader->u_extra = extra;
- linepatternShader->u_offset = -properties.lineOffset;
- linepatternShader->u_antialiasingmatrix = antialiasingMatrix;
+ shaderLinePattern->u_fade = properties.linePattern.value.t;
+ shaderLinePattern->u_opacity = properties.lineOpacity;
+ shaderLinePattern->u_extra = extra;
+ shaderLinePattern->u_offset = -properties.lineOffset;
+ shaderLinePattern->u_antialiasingmatrix = antialiasingMatrix;
- linepatternShader->u_image = 0;
+ shaderLinePattern->u_image = 0;
config.activeTexture = GL_TEXTURE0;
spriteAtlas->bind(true, store);
- bucket.drawLinePatterns(*linepatternShader, store);
+ bucket.drawLinePatterns(*shaderLinePattern, store, overdraw);
} else {
- config.program = isOverdraw() ? lineShader->getOverdrawID() : lineShader->getID();
-
- lineShader->u_matrix = vtxMatrix;
- lineShader->u_linewidth = properties.lineWidth / 2;
- lineShader->u_gapwidth = properties.lineGapWidth / 2;
- lineShader->u_antialiasing = antialiasing / 2;
- lineShader->u_ratio = ratio;
- lineShader->u_blur = blur;
- lineShader->u_extra = extra;
- lineShader->u_offset = -properties.lineOffset;
- lineShader->u_antialiasingmatrix = antialiasingMatrix;
-
- lineShader->u_color = color;
- lineShader->u_opacity = opacity;
-
- bucket.drawLines(*lineShader, store);
+ config.program = shaderLine->getID();
+
+ shaderLine->u_matrix = vtxMatrix;
+ shaderLine->u_linewidth = properties.lineWidth / 2;
+ shaderLine->u_gapwidth = properties.lineGapWidth / 2;
+ shaderLine->u_antialiasing = antialiasing / 2;
+ shaderLine->u_ratio = ratio;
+ shaderLine->u_blur = blur;
+ shaderLine->u_extra = extra;
+ shaderLine->u_offset = -properties.lineOffset;
+ shaderLine->u_antialiasingmatrix = antialiasingMatrix;
+
+ shaderLine->u_color = color;
+ shaderLine->u_opacity = opacity;
+
+ bucket.drawLines(*shaderLine, store, overdraw);
}
}
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index 783879892e..c137caf2f6 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -18,26 +18,28 @@ void Painter::renderRaster(RasterBucket& bucket,
const RasterPaintProperties& properties = layer.impl->paint;
if (bucket.hasData()) {
- config.program = isOverdraw() ? rasterShader->getOverdrawID() : rasterShader->getID();
- rasterShader->u_matrix = matrix;
- rasterShader->u_buffer = 0;
- rasterShader->u_opacity = properties.rasterOpacity;
- rasterShader->u_brightness_low = properties.rasterBrightnessMin;
- rasterShader->u_brightness_high = properties.rasterBrightnessMax;
- rasterShader->u_saturation_factor = saturationFactor(properties.rasterSaturation);
- rasterShader->u_contrast_factor = contrastFactor(properties.rasterContrast);
- rasterShader->u_spin_weights = spinWeights(properties.rasterHueRotate);
+ const auto& shaderRaster = isOverdraw() ? rasterOverdrawShader : rasterShader;
+ auto& vaoRaster = isOverdraw() ? coveringRasterOverdrawArray : coveringRasterArray;
+ config.program = shaderRaster->getID();
+ shaderRaster->u_matrix = matrix;
+ shaderRaster->u_buffer = 0;
+ shaderRaster->u_opacity = properties.rasterOpacity;
+ shaderRaster->u_brightness_low = properties.rasterBrightnessMin;
+ shaderRaster->u_brightness_high = properties.rasterBrightnessMax;
+ shaderRaster->u_saturation_factor = saturationFactor(properties.rasterSaturation);
+ shaderRaster->u_contrast_factor = contrastFactor(properties.rasterContrast);
+ shaderRaster->u_spin_weights = spinWeights(properties.rasterHueRotate);
config.stencilTest = GL_FALSE;
- rasterShader->u_image = 0;
+ shaderRaster->u_image = 0;
config.activeTexture = GL_TEXTURE0;
config.depthFunc.reset();
config.depthTest = GL_TRUE;
config.depthMask = GL_FALSE;
setDepthSublayer(0);
- bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray, store);
+ bucket.drawRaster(*shaderRaster, tileStencilBuffer, vaoRaster, store);
}
}
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 7eb4e6fce9..b80f289274 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -21,7 +21,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
float sdfFontSize,
std::array<float, 2> texsize,
SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&),
+ void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, bool),
// Layout
AlignmentType rotationAlignment,
@@ -58,7 +58,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
exScale = {{ exScale[0] * scale, exScale[1] * scale }};
}
- config.program = isOverdraw() ? sdfShader.getOverdrawID() : sdfShader.getID();
+ config.program = sdfShader.getID();
sdfShader.u_matrix = vtxMatrix;
sdfShader.u_extrude_scale = exScale;
sdfShader.u_texsize = texsize;
@@ -95,7 +95,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
sdfShader.u_buffer = (haloOffset - haloWidth / fontScale) / sdfPx;
setDepthSublayer(0);
- (bucket.*drawSDF)(sdfShader, store);
+ (bucket.*drawSDF)(sdfShader, store, isOverdraw());
}
// Then, we draw the text/icon over the halo
@@ -106,7 +106,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f;
setDepthSublayer(1);
- (bucket.*drawSDF)(sdfShader, store);
+ (bucket.*drawSDF)(sdfShader, store, isOverdraw());
}
}
@@ -170,7 +170,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
matrix,
1.0f,
{{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }},
- *sdfIconShader,
+ isOverdraw() ? *sdfIconOverdrawShader : *sdfIconShader,
&SymbolBucket::drawIcons,
layout.iconRotationAlignment,
// icon-pitch-alignment is not yet implemented
@@ -199,24 +199,27 @@ void Painter::renderSymbol(SymbolBucket& bucket,
exScale = {{ exScale[0] * scale, exScale[1] * scale }};
}
- config.program = isOverdraw() ? iconShader->getOverdrawID() : iconShader->getID();
- iconShader->u_matrix = vtxMatrix;
- iconShader->u_extrude_scale = exScale;
- iconShader->u_texsize = {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }};
- iconShader->u_rotate_with_map = alignedWithMap;
- iconShader->u_texture = 0;
+ const bool overdraw = isOverdraw();
+ const auto& shaderIcon = overdraw ? iconOverdrawShader : iconShader;
+
+ config.program = shaderIcon->getID();
+ shaderIcon->u_matrix = vtxMatrix;
+ shaderIcon->u_extrude_scale = exScale;
+ shaderIcon->u_texsize = {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }};
+ shaderIcon->u_rotate_with_map = alignedWithMap;
+ shaderIcon->u_texture = 0;
// adjust min/max zooms for variable font sies
float zoomAdjust = std::log(fontSize / layout.iconSize) / std::log(2);
- iconShader->u_zoom = (state.getZoom() - zoomAdjust) * 10; // current zoom level
- iconShader->u_opacity = paint.iconOpacity;
+ shaderIcon->u_zoom = (state.getZoom() - zoomAdjust) * 10; // current zoom level
+ shaderIcon->u_opacity = paint.iconOpacity;
config.activeTexture = GL_TEXTURE1;
frameHistory.bind(store);
- iconShader->u_fadetexture = 1;
+ shaderIcon->u_fadetexture = 1;
setDepthSublayer(0);
- bucket.drawIcons(*iconShader, store);
+ bucket.drawIcons(*shaderIcon, store, overdraw);
}
}
@@ -236,7 +239,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
matrix,
24.0f,
{{ float(glyphAtlas->width) / 4, float(glyphAtlas->height) / 4 }},
- *sdfGlyphShader,
+ isOverdraw() ? *sdfGlyphOverdrawShader : *sdfGlyphShader,
&SymbolBucket::drawGlyphs,
layout.textRotationAlignment,
layout.textPitchAlignment,
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index c198ac8a38..66d2f04700 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -601,39 +601,39 @@ void SymbolBucket::swapRenderData() {
}
}
-void SymbolBucket::drawGlyphs(SDFShader& shader, gl::ObjectStore& store) {
+void SymbolBucket::drawGlyphs(SDFShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
GLbyte *elements_index = BUFFER_OFFSET_0;
auto& text = renderData->text;
for (auto &group : text.groups) {
assert(group);
- group->array[0].bind(shader, text.vertices, text.triangles, vertex_index, store);
+ group->array[overdraw ? 1 : 0].bind(shader, text.vertices, text.triangles, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * text.vertices.itemSize;
elements_index += group->elements_length * text.triangles.itemSize;
}
}
-void SymbolBucket::drawIcons(SDFShader& shader, gl::ObjectStore& store) {
+void SymbolBucket::drawIcons(SDFShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
GLbyte *elements_index = BUFFER_OFFSET_0;
auto& icon = renderData->icon;
for (auto &group : icon.groups) {
assert(group);
- group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index, store);
+ group->array[overdraw ? 1 : 0].bind(shader, icon.vertices, icon.triangles, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * icon.vertices.itemSize;
elements_index += group->elements_length * icon.triangles.itemSize;
}
}
-void SymbolBucket::drawIcons(IconShader& shader, gl::ObjectStore& store) {
+void SymbolBucket::drawIcons(IconShader& shader, gl::ObjectStore& store, bool overdraw) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
GLbyte *elements_index = BUFFER_OFFSET_0;
auto& icon = renderData->icon;
for (auto &group : icon.groups) {
assert(group);
- group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index, store);
+ group->array[overdraw ? 3 : 2].bind(shader, icon.vertices, icon.triangles, vertex_index, store);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * icon.vertices.itemSize;
elements_index += group->elements_length * icon.triangles.itemSize;
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 6f16cccf34..b899d52767 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -61,8 +61,8 @@ class SymbolInstance {
};
class SymbolBucket : public Bucket {
- typedef ElementGroup<1> TextElementGroup;
- typedef ElementGroup<2> IconElementGroup;
+ typedef ElementGroup<2> TextElementGroup;
+ typedef ElementGroup<4> IconElementGroup;
typedef ElementGroup<1> CollisionBoxElementGroup;
public:
@@ -82,9 +82,9 @@ public:
GlyphAtlas&,
GlyphStore&);
- void drawGlyphs(SDFShader&, gl::ObjectStore&);
- void drawIcons(SDFShader&, gl::ObjectStore&);
- void drawIcons(IconShader&, gl::ObjectStore&);
+ void drawGlyphs(SDFShader&, gl::ObjectStore&, bool overdraw);
+ void drawIcons(SDFShader&, gl::ObjectStore&, bool overdraw);
+ void drawIcons(IconShader&, gl::ObjectStore&, bool overdraw);
void drawCollisionBoxes(CollisionBoxShader&, gl::ObjectStore&);
void parseFeatures(const GeometryTileLayer&, const style::Filter&);