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 | |
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')
40 files changed, 347 insertions, 348 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&); diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp index 9df5b01271..834574dc9e 100644 --- a/src/mbgl/shader/circle_shader.cpp +++ b/src/mbgl/shader/circle_shader.cpp @@ -5,8 +5,11 @@ namespace mbgl { -CircleShader::CircleShader(gl::ObjectStore& store) - : Shader(shaders::circle::name, shaders::circle::vertex, shaders::circle::fragment, store) { +CircleShader::CircleShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::circle::name, + shaders::circle::vertex, + shaders::circle::fragment, + store, overdraw) { } void CircleShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp index 70faad9b78..9ec45777e8 100644 --- a/src/mbgl/shader/circle_shader.hpp +++ b/src/mbgl/shader/circle_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class CircleShader : public Shader { public: - CircleShader(gl::ObjectStore&); + CircleShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/collision_box_shader.cpp b/src/mbgl/shader/collision_box_shader.cpp index 81f44b44e6..bfee89fac2 100644 --- a/src/mbgl/shader/collision_box_shader.cpp +++ b/src/mbgl/shader/collision_box_shader.cpp @@ -9,9 +9,7 @@ CollisionBoxShader::CollisionBoxShader(gl::ObjectStore& store) : Shader(shaders::collisionbox::name, shaders::collisionbox::vertex, shaders::collisionbox::fragment, - store), - a_extrude(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_extrude"))), - a_data(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"))) { + store) { } void CollisionBoxShader::bind(GLbyte *offset) { @@ -25,7 +23,6 @@ void CollisionBoxShader::bind(GLbyte *offset) { MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data)); MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 2, GL_UNSIGNED_BYTE, false, stride, offset + 8)); - } } // namespace mbgl diff --git a/src/mbgl/shader/collision_box_shader.hpp b/src/mbgl/shader/collision_box_shader.hpp index a9b38a9849..bbd2611ce8 100644 --- a/src/mbgl/shader/collision_box_shader.hpp +++ b/src/mbgl/shader/collision_box_shader.hpp @@ -16,10 +16,6 @@ public: Uniform<GLfloat> u_scale = {"u_scale", *this}; Uniform<GLfloat> u_zoom = {"u_zoom", *this}; Uniform<GLfloat> u_maxzoom = {"u_maxzoom", *this}; - -protected: - GLint a_extrude = -1; - GLint a_data = -1; }; } // namespace mbgl diff --git a/src/mbgl/shader/icon_shader.cpp b/src/mbgl/shader/icon_shader.cpp index a6099a00cf..3ab6ef1534 100644 --- a/src/mbgl/shader/icon_shader.cpp +++ b/src/mbgl/shader/icon_shader.cpp @@ -5,11 +5,11 @@ namespace mbgl { -IconShader::IconShader(gl::ObjectStore& store) - : Shader(shaders::icon::name, shaders::icon::vertex, shaders::icon::fragment, store), - a_offset(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_offset"))), - a_data1(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data1"))), - a_data2(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data2"))) { +IconShader::IconShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::icon::name, + shaders::icon::vertex, + shaders::icon::fragment, + store, overdraw) { } void IconShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/icon_shader.hpp b/src/mbgl/shader/icon_shader.hpp index ed1861d1bb..209295e5e2 100644 --- a/src/mbgl/shader/icon_shader.hpp +++ b/src/mbgl/shader/icon_shader.hpp @@ -7,7 +7,7 @@ namespace mbgl { class IconShader : public Shader { public: - IconShader(gl::ObjectStore&); + IconShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; @@ -19,11 +19,6 @@ public: Uniform<GLint> u_rotate_with_map = {"u_rotate_with_map", *this}; Uniform<GLint> u_texture = {"u_texture", *this}; Uniform<GLint> u_fadetexture = {"u_fadetexture", *this}; - -protected: - GLint a_offset = -1; - GLint a_data1 = -1; - GLint a_data2 = -1; }; } // namespace mbgl diff --git a/src/mbgl/shader/line_shader.cpp b/src/mbgl/shader/line_shader.cpp index 300dc9f598..cde638b99a 100644 --- a/src/mbgl/shader/line_shader.cpp +++ b/src/mbgl/shader/line_shader.cpp @@ -5,9 +5,11 @@ namespace mbgl { -LineShader::LineShader(gl::ObjectStore& store) - : Shader(shaders::line::name, shaders::line::vertex, shaders::line::fragment, store), - a_data(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"))) { +LineShader::LineShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::line::name, + shaders::line::vertex, + shaders::line::fragment, + store, overdraw) { } void LineShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp index 1265e768f2..e716ea211c 100644 --- a/src/mbgl/shader/line_shader.hpp +++ b/src/mbgl/shader/line_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class LineShader : public Shader { public: - LineShader(gl::ObjectStore&); + LineShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; @@ -23,9 +23,6 @@ public: Uniform<GLfloat> u_extra = {"u_extra", *this}; Uniform<GLfloat> u_offset = {"u_offset", *this}; UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this}; - -private: - GLint a_data = -1; }; diff --git a/src/mbgl/shader/linepattern_shader.cpp b/src/mbgl/shader/linepattern_shader.cpp index 2f3d93c03e..730cdfc6fa 100644 --- a/src/mbgl/shader/linepattern_shader.cpp +++ b/src/mbgl/shader/linepattern_shader.cpp @@ -5,12 +5,11 @@ namespace mbgl { -LinepatternShader::LinepatternShader(gl::ObjectStore& store) +LinepatternShader::LinepatternShader(gl::ObjectStore& store, bool overdraw) : Shader(shaders::linepattern::name, shaders::linepattern::vertex, shaders::linepattern::fragment, - store), - a_data(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"))) { + store, overdraw) { } void LinepatternShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp index c34c1a5292..f71d2d2f67 100644 --- a/src/mbgl/shader/linepattern_shader.hpp +++ b/src/mbgl/shader/linepattern_shader.hpp @@ -7,7 +7,7 @@ namespace mbgl { class LinepatternShader : public Shader { public: - LinepatternShader(gl::ObjectStore&); + LinepatternShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; @@ -30,8 +30,6 @@ public: Uniform<GLfloat> u_offset = {"u_offset", *this}; Uniform<GLint> u_image = {"u_image", *this}; UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this}; - -private: - GLint a_data = -1; }; + } // namespace mbgl diff --git a/src/mbgl/shader/linesdf_shader.cpp b/src/mbgl/shader/linesdf_shader.cpp index 8b6e2e1900..27d4f9c601 100644 --- a/src/mbgl/shader/linesdf_shader.cpp +++ b/src/mbgl/shader/linesdf_shader.cpp @@ -5,12 +5,11 @@ namespace mbgl { -LineSDFShader::LineSDFShader(gl::ObjectStore& store) +LineSDFShader::LineSDFShader(gl::ObjectStore& store, bool overdraw) : Shader(shaders::linesdfpattern::name, shaders::linesdfpattern::vertex, shaders::linesdfpattern::fragment, - store), - a_data(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"))) { + store, overdraw) { } void LineSDFShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp index 98bbc2b8f8..be63add59a 100644 --- a/src/mbgl/shader/linesdf_shader.hpp +++ b/src/mbgl/shader/linesdf_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class LineSDFShader : public Shader { public: - LineSDFShader(gl::ObjectStore&); + LineSDFShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; @@ -30,9 +30,6 @@ public: Uniform<GLfloat> u_extra = {"u_extra", *this}; Uniform<GLfloat> u_offset = {"u_offset", *this}; UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this}; - -private: - GLint a_data = -1; }; diff --git a/src/mbgl/shader/outline_shader.cpp b/src/mbgl/shader/outline_shader.cpp index aadbc08ada..f9db2d6b8a 100644 --- a/src/mbgl/shader/outline_shader.cpp +++ b/src/mbgl/shader/outline_shader.cpp @@ -5,8 +5,11 @@ namespace mbgl { -OutlineShader::OutlineShader(gl::ObjectStore& store) - : Shader(shaders::outline::name, shaders::outline::vertex, shaders::outline::fragment, store) { +OutlineShader::OutlineShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::outline::name, + shaders::outline::vertex, + shaders::outline::fragment, + store, overdraw) { } void OutlineShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/outline_shader.hpp b/src/mbgl/shader/outline_shader.hpp index 5ec2c68e7f..3eb500d944 100644 --- a/src/mbgl/shader/outline_shader.hpp +++ b/src/mbgl/shader/outline_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class OutlineShader : public Shader { public: - OutlineShader(gl::ObjectStore&); + OutlineShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/outlinepattern_shader.cpp b/src/mbgl/shader/outlinepattern_shader.cpp index 8fde8dee74..52572ec05f 100644 --- a/src/mbgl/shader/outlinepattern_shader.cpp +++ b/src/mbgl/shader/outlinepattern_shader.cpp @@ -5,11 +5,11 @@ namespace mbgl { -OutlinePatternShader::OutlinePatternShader(gl::ObjectStore& store) +OutlinePatternShader::OutlinePatternShader(gl::ObjectStore& store, bool overdraw) : Shader(shaders::outlinepattern::name, shaders::outlinepattern::vertex, shaders::outlinepattern::fragment, - store) { + store, overdraw) { } void OutlinePatternShader::bind(GLbyte *offset) { diff --git a/src/mbgl/shader/outlinepattern_shader.hpp b/src/mbgl/shader/outlinepattern_shader.hpp index 1eb805ffae..4fc458b5fc 100644 --- a/src/mbgl/shader/outlinepattern_shader.hpp +++ b/src/mbgl/shader/outlinepattern_shader.hpp @@ -7,7 +7,7 @@ namespace mbgl { class OutlinePatternShader : public Shader { public: - OutlinePatternShader(gl::ObjectStore&); + OutlinePatternShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/pattern_shader.cpp b/src/mbgl/shader/pattern_shader.cpp index f3027514f9..ff78810234 100644 --- a/src/mbgl/shader/pattern_shader.cpp +++ b/src/mbgl/shader/pattern_shader.cpp @@ -5,8 +5,11 @@ namespace mbgl { -PatternShader::PatternShader(gl::ObjectStore& store) - : Shader(shaders::pattern::name, shaders::pattern::vertex, shaders::pattern::fragment, store) { +PatternShader::PatternShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::pattern::name, + shaders::pattern::vertex, + shaders::pattern::fragment, + store, overdraw) { } void PatternShader::bind(GLbyte *offset) { diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp index 2a6eb45ddb..34f0396879 100644 --- a/src/mbgl/shader/pattern_shader.hpp +++ b/src/mbgl/shader/pattern_shader.hpp @@ -7,7 +7,7 @@ namespace mbgl { class PatternShader : public Shader { public: - PatternShader(gl::ObjectStore&); + PatternShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/plain_shader.cpp b/src/mbgl/shader/plain_shader.cpp index 120481c272..08ddd35790 100644 --- a/src/mbgl/shader/plain_shader.cpp +++ b/src/mbgl/shader/plain_shader.cpp @@ -5,8 +5,11 @@ namespace mbgl { -PlainShader::PlainShader(gl::ObjectStore& store) - : Shader(shaders::fill::name, shaders::fill::vertex, shaders::fill::fragment, store) { +PlainShader::PlainShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::fill::name, + shaders::fill::vertex, + shaders::fill::fragment, + store, overdraw) { } void PlainShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/plain_shader.hpp b/src/mbgl/shader/plain_shader.hpp index 8eec69147e..319fc3bd80 100644 --- a/src/mbgl/shader/plain_shader.hpp +++ b/src/mbgl/shader/plain_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class PlainShader : public Shader { public: - PlainShader(gl::ObjectStore&); + PlainShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp index 109c6e0d29..17953ab903 100644 --- a/src/mbgl/shader/raster_shader.cpp +++ b/src/mbgl/shader/raster_shader.cpp @@ -5,8 +5,11 @@ namespace mbgl { -RasterShader::RasterShader(gl::ObjectStore& store) - : Shader(shaders::raster::name, shaders::raster::vertex, shaders::raster::fragment, store) { +RasterShader::RasterShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::raster::name, + shaders::raster::vertex, + shaders::raster::fragment, + store, overdraw) { } void RasterShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp index ee53385a0b..9c658c8d54 100644 --- a/src/mbgl/shader/raster_shader.hpp +++ b/src/mbgl/shader/raster_shader.hpp @@ -7,7 +7,7 @@ namespace mbgl { class RasterShader : public Shader { public: - RasterShader(gl::ObjectStore&); + RasterShader(gl::ObjectStore&, bool overdraw = false); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/sdf_shader.cpp b/src/mbgl/shader/sdf_shader.cpp index faee224373..b390df5e42 100644 --- a/src/mbgl/shader/sdf_shader.cpp +++ b/src/mbgl/shader/sdf_shader.cpp @@ -5,30 +5,14 @@ namespace mbgl { -SDFShader::SDFShader(gl::ObjectStore& store) - : Shader(shaders::sdf::name, shaders::sdf::vertex, shaders::sdf::fragment, store), - a_offset(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_offset"))), - a_data1(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data1"))), - a_data2(MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data2"))) { +SDFShader::SDFShader(gl::ObjectStore& store, bool overdraw) + : Shader(shaders::sdf::name, + shaders::sdf::vertex, + shaders::sdf::fragment, + store, overdraw) { } -void SDFGlyphShader::bind(GLbyte* offset) { - const int stride = 16; - - MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos)); - MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0)); - - MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_offset)); - MBGL_CHECK_ERROR(glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4)); - - MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data1)); - MBGL_CHECK_ERROR(glVertexAttribPointer(a_data1, 4, GL_UNSIGNED_BYTE, false, stride, offset + 8)); - - MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data2)); - MBGL_CHECK_ERROR(glVertexAttribPointer(a_data2, 4, GL_UNSIGNED_BYTE, false, stride, offset + 12)); -} - -void SDFIconShader::bind(GLbyte* offset) { +void SDFShader::bind(GLbyte* offset) { const int stride = 16; MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos)); diff --git a/src/mbgl/shader/sdf_shader.hpp b/src/mbgl/shader/sdf_shader.hpp index 88f671b543..7ce7be49a7 100644 --- a/src/mbgl/shader/sdf_shader.hpp +++ b/src/mbgl/shader/sdf_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class SDFShader : public Shader { public: - SDFShader(gl::ObjectStore&); + SDFShader(gl::ObjectStore&, bool overdraw = false); UniformMatrix<4> u_matrix = {"u_matrix", *this}; Uniform<std::array<GLfloat, 2>> u_extrude_scale = {"u_extrude_scale", *this}; @@ -26,21 +26,6 @@ public: Uniform<GLint> u_texture = {"u_texture", *this}; Uniform<GLint> u_fadetexture = {"u_fadetexture", *this}; -protected: - GLint a_offset = -1; - GLint a_data1 = -1; - GLint a_data2 = -1; -}; - -class SDFGlyphShader : public SDFShader { -public: - SDFGlyphShader(gl::ObjectStore& store) : SDFShader(store) {} - void bind(GLbyte *offset) final; -}; - -class SDFIconShader : public SDFShader { -public: - SDFIconShader(gl::ObjectStore& store) : SDFShader(store) {} void bind(GLbyte *offset) final; }; diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp index 80c4c33efc..c9a6b89ade 100644 --- a/src/mbgl/shader/shader.cpp +++ b/src/mbgl/shader/shader.cpp @@ -11,10 +11,11 @@ #include <string> #include <fstream> #include <cstdio> +#include <cassert> namespace mbgl { -Shader::Shader(const char* name_, const char* vertexSource, const char* fragmentSource, gl::ObjectStore& store) +Shader::Shader(const char* name_, const char* vertexSource, const char* fragmentSource, gl::ObjectStore& store, bool overdraw) : name(name_) , program(store.createProgram()) , vertexShader(store.createShader(GL_VERTEX_SHADER)) @@ -27,7 +28,13 @@ Shader::Shader(const char* name_, const char* vertexSource, const char* fragment throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile"); } - if (!compileShader(fragmentShader, fragmentSource)) { + std::string fragment(fragmentSource); + if (overdraw) { + assert(fragment.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos); + fragment.replace(fragment.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n"); + } + + if (!compileShader(fragmentShader, fragment.c_str())) { Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragmentSource); throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile"); } @@ -36,39 +43,25 @@ Shader::Shader(const char* name_, const char* vertexSource, const char* fragment MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get())); MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get())); - linkProgram(program); - - std::string overdrawSource(fragmentSource); - if (overdrawSource.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos) { - programOverdraw = store.createProgram(); - overdrawShader = store.createShader(GL_FRAGMENT_SHADER); - - overdrawSource.replace(overdrawSource.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n"); - if (!compileShader(*overdrawShader, overdrawSource.c_str())) { - Log::Error(Event::Shader, "Overdraw shader %s failed to compile: %s", name, overdrawSource.c_str()); - throw util::ShaderException(std::string { "Overdraw shader " } + name + " failed to compile"); - } + // Bind attribute variables + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_pos, "a_pos")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_extrude, "a_extrude")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_offset, "a_offset")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data, "a_data")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data1, "a_data1")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data2, "a_data2")); - MBGL_CHECK_ERROR(glAttachShader(*programOverdraw, vertexShader.get())); - MBGL_CHECK_ERROR(glAttachShader(*programOverdraw, *overdrawShader)); - linkProgram(*programOverdraw); - } - - a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), "a_pos")); -} - -void Shader::linkProgram(gl::UniqueProgram& program_) { // Link program GLint status; - MBGL_CHECK_ERROR(glLinkProgram(program_.get())); + MBGL_CHECK_ERROR(glLinkProgram(program.get())); - MBGL_CHECK_ERROR(glGetProgramiv(program_.get(), GL_LINK_STATUS, &status)); + MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_LINK_STATUS, &status)); if (status == 0) { GLint logLength; - MBGL_CHECK_ERROR(glGetProgramiv(program_.get(), GL_INFO_LOG_LENGTH, &logLength)); + MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &logLength)); const auto log = std::make_unique<GLchar[]>(logLength); if (logLength > 0) { - MBGL_CHECK_ERROR(glGetProgramInfoLog(program_.get(), logLength, &logLength, log.get())); + MBGL_CHECK_ERROR(glGetProgramInfoLog(program.get(), logLength, &logLength, log.get())); Log::Error(Event::Shader, "Program failed to link: %s", log.get()); } throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get()); @@ -109,10 +102,6 @@ Shader::~Shader() { MBGL_CHECK_ERROR(glDetachShader(program.get(), vertexShader.get())); MBGL_CHECK_ERROR(glDetachShader(program.get(), fragmentShader.get())); } - if (programOverdraw) { - MBGL_CHECK_ERROR(glDetachShader(*programOverdraw, vertexShader.get())); - MBGL_CHECK_ERROR(glDetachShader(*programOverdraw, *overdrawShader)); - } } } // namespace mbgl diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp index 4289b83a77..81ee024934 100644 --- a/src/mbgl/shader/shader.hpp +++ b/src/mbgl/shader/shader.hpp @@ -16,26 +16,24 @@ public: return program.get(); } - GLuint getOverdrawID() const { - return programOverdraw ? *programOverdraw : 0; - } - virtual void bind(GLbyte *offset) = 0; protected: - Shader(const char* name_, const char* vertex, const char* fragment, gl::ObjectStore&); - GLint a_pos = -1; + Shader(const char* name_, const char* vertex, const char* fragment, gl::ObjectStore&, bool overdraw = false); + + static constexpr GLint a_pos = 0; + static constexpr GLint a_extrude = 1; + static constexpr GLint a_offset = 2; + static constexpr GLint a_data = 3; + static constexpr GLint a_data1 = 4; + static constexpr GLint a_data2 = 5; private: bool compileShader(gl::UniqueShader&, const GLchar *source); - void linkProgram(gl::UniqueProgram&); gl::UniqueProgram program; gl::UniqueShader vertexShader; gl::UniqueShader fragmentShader; - - mbgl::optional<gl::UniqueProgram> programOverdraw; - mbgl::optional<gl::UniqueShader> overdrawShader; }; } // namespace mbgl |