diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-06-21 17:22:51 -0700 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-07-01 19:47:35 +0300 |
commit | a17b0bcd82ebe8628b69588d19773d26596b86da (patch) | |
tree | 06e53bf42b059b28780e995020733aaaeb6487b1 /src/mbgl/renderer | |
parent | eb7cfea7eacad8a179fb3167b88508f8f1f7fdd2 (diff) | |
download | qtlocation-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.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/renderer/fill_bucket.hpp | 12 | ||||
-rw-r--r-- | src/mbgl/renderer/line_bucket.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/renderer/line_bucket.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 23 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_background.cpp | 47 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_circle.cpp | 20 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_fill.cpp | 113 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_line.cpp | 120 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_raster.cpp | 24 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_symbol.cpp | 35 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.hpp | 10 |
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&); |