summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-06-21 17:22:51 -0700
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-07-01 19:47:35 +0300
commita17b0bcd82ebe8628b69588d19773d26596b86da (patch)
tree06e53bf42b059b28780e995020733aaaeb6487b1
parenteb7cfea7eacad8a179fb3167b88508f8f1f7fdd2 (diff)
downloadqtlocation-mapboxgl-a17b0bcd82ebe8628b69588d19773d26596b86da.tar.gz
[core] Fix overdraw mode on Linux
- Use glBindAttribLocation for GLSL attributes. - Create a separate shader for each shader that supports overdraw. Needed because each uniform location must be known for every program. - Create a separate VAO for each shader inside buckets. Needed because we can only bind a VAO to a specific shader. Fixes #5435.
-rw-r--r--package.json2
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp16
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp12
-rw-r--r--src/mbgl/renderer/line_bucket.cpp12
-rw-r--r--src/mbgl/renderer/line_bucket.hpp8
-rw-r--r--src/mbgl/renderer/painter.cpp18
-rw-r--r--src/mbgl/renderer/painter.hpp23
-rw-r--r--src/mbgl/renderer/painter_background.cpp47
-rw-r--r--src/mbgl/renderer/painter_circle.cpp20
-rw-r--r--src/mbgl/renderer/painter_fill.cpp113
-rw-r--r--src/mbgl/renderer/painter_line.cpp120
-rw-r--r--src/mbgl/renderer/painter_raster.cpp24
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp35
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp12
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp10
-rw-r--r--src/mbgl/shader/circle_shader.cpp7
-rw-r--r--src/mbgl/shader/circle_shader.hpp2
-rw-r--r--src/mbgl/shader/collision_box_shader.cpp5
-rw-r--r--src/mbgl/shader/collision_box_shader.hpp4
-rw-r--r--src/mbgl/shader/icon_shader.cpp10
-rw-r--r--src/mbgl/shader/icon_shader.hpp7
-rw-r--r--src/mbgl/shader/line_shader.cpp8
-rw-r--r--src/mbgl/shader/line_shader.hpp5
-rw-r--r--src/mbgl/shader/linepattern_shader.cpp5
-rw-r--r--src/mbgl/shader/linepattern_shader.hpp6
-rw-r--r--src/mbgl/shader/linesdf_shader.cpp5
-rw-r--r--src/mbgl/shader/linesdf_shader.hpp5
-rw-r--r--src/mbgl/shader/outline_shader.cpp7
-rw-r--r--src/mbgl/shader/outline_shader.hpp2
-rw-r--r--src/mbgl/shader/outlinepattern_shader.cpp4
-rw-r--r--src/mbgl/shader/outlinepattern_shader.hpp2
-rw-r--r--src/mbgl/shader/pattern_shader.cpp7
-rw-r--r--src/mbgl/shader/pattern_shader.hpp2
-rw-r--r--src/mbgl/shader/plain_shader.cpp7
-rw-r--r--src/mbgl/shader/plain_shader.hpp2
-rw-r--r--src/mbgl/shader/raster_shader.cpp7
-rw-r--r--src/mbgl/shader/raster_shader.hpp2
-rw-r--r--src/mbgl/shader/sdf_shader.cpp28
-rw-r--r--src/mbgl/shader/sdf_shader.hpp17
-rw-r--r--src/mbgl/shader/shader.cpp51
-rw-r--r--src/mbgl/shader/shader.hpp18
41 files changed, 348 insertions, 349 deletions
diff --git a/package.json b/package.json
index 4ca0cd119a..9c067f8bbb 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"express": "^4.11.1",
"mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#59e998295d548f208ee3ec10cdd21ff2630e2079",
"mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#194fc55b6a7dd54c1e2cf2dd9048fbb5e836716d",
- "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#cb733d358a95d46344c2212f1546ed94022718f7",
+ "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#2e5addbbd6b3eafaa2984bfd863fd28071f2e481",
"node-gyp": "^3.3.1",
"request": "^2.72.0",
"tape": "^4.5.1"
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