[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.
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
shaderOutline->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) }};
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,18 +55,22 @@ void Painter::renderLine(LineBucket& bucket,
|
||||
|
||||
setDepthSublayer(0);
|
||||
|
||||
const bool overdraw = isOverdraw();
|
||||
const auto& shaderLineSDF = overdraw ? linesdfOverdrawShader : linesdfShader;
|
||||
const auto& shaderLinePattern = overdraw ? linepatternOverdrawShader : linepatternShader;
|
||||
const auto& shaderLine = overdraw ? lineOverdrawShader : lineShader;
|
||||
|
||||
if (!properties.lineDasharray.value.from.empty()) {
|
||||
config.program = shaderLineSDF->getID();
|
||||
|
||||
config.program = isOverdraw() ? linesdfShader->getOverdrawID() : linesdfShader->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;
|
||||
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;
|
||||
|
||||
linesdfShader->u_image = 0;
|
||||
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();
|
||||
config.program = shaderLine->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;
|
||||
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;
|
||||
|
||||
lineShader->u_color = color;
|
||||
lineShader->u_opacity = opacity;
|
||||
shaderLine->u_color = color;
|
||||
shaderLine->u_opacity = opacity;
|
||||
|
||||
bucket.drawLines(*lineShader, store);
|
||||
bucket.drawLines(*shaderLine, store, overdraw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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&);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
// 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"));
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user