summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp193
-rw-r--r--src/mbgl/renderer/layers/render_heatmap_layer.cpp4
-rw-r--r--src/mbgl/renderer/paint_parameters.cpp24
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp5
-rw-r--r--src/mbgl/renderer/render_static_data.cpp16
-rw-r--r--src/mbgl/renderer/render_static_data.hpp6
6 files changed, 123 insertions, 125 deletions
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
index c8fa8765de..6c2d049948 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
@@ -56,86 +56,83 @@ bool RenderFillExtrusionLayer::hasCrossfade() const {
}
void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*) {
- if (parameters.pass == RenderPass::Opaque) {
+ if (parameters.pass != RenderPass::Translucent) {
return;
}
- if (parameters.pass == RenderPass::Pass3D) {
- const auto& size = parameters.staticData.backendSize;
- if (!renderTexture || renderTexture->getSize() != size) {
- renderTexture.reset();
- renderTexture = parameters.context.createOffscreenTexture(size, *parameters.staticData.depthRenderbuffer);
- }
+ const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
+ const auto& crossfade = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).crossfade;
+ if (evaluated.get<FillExtrusionOpacity>() == 0) {
+ return;
+ }
- optional<float> depthClearValue = {};
- if (parameters.staticData.depthRenderbuffer->needsClearing()) depthClearValue = 1.0;
- // Flag the depth buffer as no longer needing to be cleared for the remainder of this pass.
- parameters.staticData.depthRenderbuffer->setShouldClear(false);
-
- auto renderPass = parameters.encoder->createRenderPass(
- "fill extrusion",
- { *renderTexture, Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {} });
-
- auto draw = [&](auto& programInstance,
- const auto& evaluated_,
- const auto& crossfade_,
- const auto& tileBucket,
- auto&& uniformValues,
- const optional<ImagePosition>& patternPositionA,
- const optional<ImagePosition>& patternPositionB,
- auto&& textureBindings) {
- const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
- paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- std::move(uniformValues),
- paintPropertyBinders,
- evaluated_,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *tileBucket.vertexBuffer,
- paintPropertyBinders,
- evaluated_
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *renderPass,
- gfx::Triangles(),
- parameters.depthModeFor3D(gfx::DepthMaskType::ReadWrite),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::backCCW(),
- *tileBucket.indexBuffer,
- tileBucket.triangleSegments,
- allUniformValues,
- allAttributeBindings,
- std::move(textureBindings),
- getID());
- };
+ const auto depthMode = parameters.depthModeFor3D();
+
+ auto draw = [&](auto& programInstance,
+ const auto& evaluated_,
+ const auto& crossfade_,
+ const gfx::StencilMode& stencilMode,
+ const gfx::ColorMode& colorMode,
+ const auto& tileBucket,
+ const auto& uniformValues,
+ const optional<ImagePosition>& patternPositionA,
+ const optional<ImagePosition>& patternPositionB,
+ const auto& textureBindings) {
+ const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
+ paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ uniformValues,
+ paintPropertyBinders,
+ evaluated_,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *tileBucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated_
+ );
- if (unevaluated.get<FillExtrusionPattern>().isUndefined()) {
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ depthMode,
+ stencilMode,
+ colorMode,
+ gfx::CullFaceMode::backCCW(),
+ *tileBucket.indexBuffer,
+ tileBucket.triangleSegments,
+ allUniformValues,
+ allAttributeBindings,
+ textureBindings,
+ getID());
+ };
+
+ if (unevaluated.get<FillExtrusionPattern>().isUndefined()) {
+ // Draw solid color extrusions
+ auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_) {
for (const RenderTile& tile : renderTiles) {
const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
}
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
- const auto& evaluated = getEvaluated<FillExtrusionLayerProperties>(renderData->layerProperties);
- const auto& crossfade = getCrossfade<FillExtrusionLayerProperties>(renderData->layerProperties);
draw(
parameters.programs.getFillExtrusionLayerPrograms().fillExtrusion,
evaluated,
crossfade,
+ stencilMode_,
+ colorMode_,
bucket,
FillExtrusionProgram::layoutUniformValues(
tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
evaluated.get<FillExtrusionTranslateAnchor>(),
parameters.state),
parameters.state,
+ evaluated.get<FillExtrusionOpacity>(),
parameters.evaluatedLight
),
{},
@@ -143,17 +140,32 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
FillExtrusionProgram::TextureBindings{}
);
}
+ };
+
+ if (evaluated.get<FillExtrusionOpacity>() == 1) {
+ // Draw opaque extrusions
+ drawTiles(gfx::StencilMode::disabled(), parameters.colorModeForRenderPass());
} else {
+ // Draw transparent buildings in two passes so that only the closest surface is drawn.
+ // First draw all the extrusions into only the depth buffer. No colors are drawn.
+ drawTiles(gfx::StencilMode::disabled(), gfx::ColorMode::disabled());
+
+ // Then draw all the extrusions a second time, only coloring fragments if they have the
+ // same depth value as the closest fragment in the previous pass. Use the stencil buffer
+ // to prevent the second draw in cases where we have coincident polygons.
+ drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass());
+ }
+ } else {
+ // Draw textured extrusions
+ const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<std::basic_string<char> >{"", ""});
+ auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_) {
for (const RenderTile& tile : renderTiles) {
const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
}
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
- const auto& evaluated = getEvaluated<FillExtrusionLayerProperties>(renderData->layerProperties);
- const auto& crossfade = getCrossfade<FillExtrusionLayerProperties>(renderData->layerProperties);
- const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<std::basic_string<char> >{"", ""});
auto& geometryTile = static_cast<GeometryTile&>(tile.tile);
optional<ImagePosition> patternPosA = geometryTile.getPattern(fillPatternValue.from);
optional<ImagePosition> patternPosB = geometryTile.getPattern(fillPatternValue.to);
@@ -162,6 +174,8 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
parameters.programs.getFillExtrusionLayerPrograms().fillExtrusionPattern,
evaluated,
crossfade,
+ stencilMode_,
+ colorMode_,
bucket,
FillExtrusionPatternProgram::layoutUniformValues(
tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
@@ -171,6 +185,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
crossfade,
tile.id,
parameters.state,
+ evaluated.get<FillExtrusionOpacity>(),
-std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f,
parameters.pixelRatio,
parameters.evaluatedLight
@@ -182,54 +197,16 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
}
);
}
- }
-
- } else if (parameters.pass == RenderPass::Translucent) {
- const auto& size = parameters.staticData.backendSize;
- const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
-
- mat4 viewportMat;
- matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
-
- const Properties<>::PossiblyEvaluated properties;
- const ExtrusionTextureProgram::Binders paintAttributeData{ properties, 0 };
-
- auto& programInstance = parameters.programs.getFillExtrusionLayerPrograms().extrusionTexture;
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- ExtrusionTextureProgram::LayoutUniformValues{
- uniforms::matrix::Value( viewportMat ),
- uniforms::world::Value( size ),
- uniforms::opacity::Value( evaluated.get<FillExtrusionOpacity>() )
- },
- paintAttributeData,
- properties,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- parameters.staticData.extrusionTextureVertexBuffer,
- paintAttributeData,
- properties
- );
+ };
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+ // Draw transparent buildings in two passes so that only the closest surface is drawn.
+ // First draw all the extrusions into only the depth buffer. No colors are drawn.
+ drawTiles(gfx::StencilMode::disabled(), gfx::ColorMode::disabled());
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- gfx::DepthMode::disabled(),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.extrusionTextureSegments,
- allUniformValues,
- allAttributeBindings,
- ExtrusionTextureProgram::TextureBindings{
- textures::image::Value{ renderTexture->getTexture().getResource() },
- },
- getID());
+ // Then draw all the extrusions a second time, only coloring fragments if they have the
+ // same depth value as the closest fragment in the previous pass. Use the stencil buffer
+ // to prevent the second draw in cases where we have coincident polygons.
+ drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass());
}
}
diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
index 48249002ea..f1cce31ea4 100644
--- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp
+++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
@@ -159,7 +159,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) {
parameters.state.getZoom()
);
const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- parameters.staticData.extrusionTextureVertexBuffer,
+ parameters.staticData.heatmapTextureVertexBuffer,
paintAttributeData,
properties
);
@@ -175,7 +175,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) {
parameters.colorModeForRenderPass(),
gfx::CullFaceMode::disabled(),
parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.extrusionTextureSegments,
+ parameters.staticData.heatmapTextureSegments,
allUniformValues,
allAttributeBindings,
HeatmapTextureProgram::TextureBindings{
diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp
index e9f42d2579..33a741865e 100644
--- a/src/mbgl/renderer/paint_parameters.cpp
+++ b/src/mbgl/renderer/paint_parameters.cpp
@@ -72,8 +72,10 @@ gfx::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gfx::DepthMaskTy
return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { nearDepth, farDepth } };
}
-gfx::DepthMode PaintParameters::depthModeFor3D(gfx::DepthMaskType mask) const {
- return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { 0.0, 1.0 } };
+gfx::DepthMode PaintParameters::depthModeFor3D() const {
+ return gfx::DepthMode{ gfx::DepthFunctionType::LessEqual,
+ gfx::DepthMaskType::ReadWrite,
+ { 0.0, depthRangeSize } };
}
void PaintParameters::clearStencil() {
@@ -166,6 +168,24 @@ gfx::StencilMode PaintParameters::stencilModeForClipping(const UnwrappedTileID&
gfx::StencilOpType::Replace };
}
+gfx::StencilMode PaintParameters::stencilModeFor3D() {
+ if (nextStencilID + 1 > 256) {
+ clearStencil();
+ }
+
+ // We're potentially destroying the stencil clipping mask in this pass. That means we'll have
+ // to recreate it for the next source if any.
+ tileClippingMaskIDs.clear();
+
+ const int32_t id = nextStencilID++;
+ return gfx::StencilMode{ gfx::StencilMode::NotEqual{ 0b11111111 },
+ id,
+ 0b11111111,
+ gfx::StencilOpType::Keep,
+ gfx::StencilOpType::Keep,
+ gfx::StencilOpType::Replace };
+}
+
gfx::ColorMode PaintParameters::colorModeForRenderPass() const {
if (debugOptions & MapDebugOptions::Overdraw) {
const float overdraw = 1.0f / 8.0f;
diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp
index 1a576b6c9c..28db87ed4f 100644
--- a/src/mbgl/renderer/paint_parameters.hpp
+++ b/src/mbgl/renderer/paint_parameters.hpp
@@ -69,7 +69,7 @@ public:
Programs& programs;
gfx::DepthMode depthModeForSublayer(uint8_t n, gfx::DepthMaskType) const;
- gfx::DepthMode depthModeFor3D(gfx::DepthMaskType) const;
+ gfx::DepthMode depthModeFor3D() const;
gfx::ColorMode colorModeForRenderPass() const;
mat4 matrixForTile(const UnwrappedTileID&, bool aligned = false) const;
@@ -82,6 +82,7 @@ public:
public:
void renderTileClippingMasks(const std::vector<std::reference_wrapper<RenderTile>>&);
gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const;
+ gfx::StencilMode stencilModeFor3D();
private:
void clearStencil();
@@ -96,7 +97,7 @@ public:
float depthRangeSize;
const float depthEpsilon = 1.0f / (1 << 16);
-
+
float symbolFadeChange;
};
diff --git a/src/mbgl/renderer/render_static_data.cpp b/src/mbgl/renderer/render_static_data.cpp
index 24eed0326c..0814d6341b 100644
--- a/src/mbgl/renderer/render_static_data.cpp
+++ b/src/mbgl/renderer/render_static_data.cpp
@@ -39,19 +39,19 @@ static gfx::VertexVector<RasterLayoutVertex> rasterVertices() {
return result;
}
-static gfx::VertexVector<ExtrusionTextureLayoutVertex> extrusionTextureVertices() {
- gfx::VertexVector<ExtrusionTextureLayoutVertex> result;
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 0, 0 }));
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 1, 0 }));
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 0, 1 }));
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 1, 1 }));
+static gfx::VertexVector<HeatmapTextureLayoutVertex> heatmapTextureVertices() {
+ gfx::VertexVector<HeatmapTextureLayoutVertex> result;
+ result.emplace_back(HeatmapTextureProgram::layoutVertex({ 0, 0 }));
+ result.emplace_back(HeatmapTextureProgram::layoutVertex({ 1, 0 }));
+ result.emplace_back(HeatmapTextureProgram::layoutVertex({ 0, 1 }));
+ result.emplace_back(HeatmapTextureProgram::layoutVertex({ 1, 1 }));
return result;
}
RenderStaticData::RenderStaticData(gfx::Context& context, float pixelRatio, const optional<std::string>& programCacheDir)
: tileVertexBuffer(context.createVertexBuffer(tileVertices())),
rasterVertexBuffer(context.createVertexBuffer(rasterVertices())),
- extrusionTextureVertexBuffer(context.createVertexBuffer(extrusionTextureVertices())),
+ heatmapTextureVertexBuffer(context.createVertexBuffer(heatmapTextureVertices())),
quadTriangleIndexBuffer(context.createIndexBuffer(quadTriangleIndices())),
tileBorderIndexBuffer(context.createIndexBuffer(tileLineStripIndices())),
programs(context, ProgramParameters { pixelRatio, false, programCacheDir })
@@ -62,7 +62,7 @@ RenderStaticData::RenderStaticData(gfx::Context& context, float pixelRatio, cons
tileTriangleSegments.emplace_back(0, 0, 4, 6);
tileBorderSegments.emplace_back(0, 0, 4, 5);
rasterSegments.emplace_back(0, 0, 4, 6);
- extrusionTextureSegments.emplace_back(0, 0, 4, 6);
+ heatmapTextureSegments.emplace_back(0, 0, 4, 6);
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_static_data.hpp b/src/mbgl/renderer/render_static_data.hpp
index f6c40163ee..ddf52f83f6 100644
--- a/src/mbgl/renderer/render_static_data.hpp
+++ b/src/mbgl/renderer/render_static_data.hpp
@@ -4,7 +4,7 @@
#include <mbgl/gfx/index_buffer.hpp>
#include <mbgl/gfx/renderbuffer.hpp>
#include <mbgl/programs/background_program.hpp>
-#include <mbgl/programs/extrusion_texture_program.hpp>
+#include <mbgl/programs/heatmap_texture_program.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/raster_program.hpp>
#include <mbgl/util/optional.hpp>
@@ -22,7 +22,7 @@ public:
gfx::VertexBuffer<gfx::Vertex<PositionOnlyLayoutAttributes>> tileVertexBuffer;
gfx::VertexBuffer<RasterLayoutVertex> rasterVertexBuffer;
- gfx::VertexBuffer<ExtrusionTextureLayoutVertex> extrusionTextureVertexBuffer;
+ gfx::VertexBuffer<HeatmapTextureLayoutVertex> heatmapTextureVertexBuffer;
gfx::IndexBuffer quadTriangleIndexBuffer;
gfx::IndexBuffer tileBorderIndexBuffer;
@@ -30,7 +30,7 @@ public:
SegmentVector<BackgroundAttributes> tileTriangleSegments;
SegmentVector<DebugAttributes> tileBorderSegments;
SegmentVector<RasterAttributes> rasterSegments;
- SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments;
+ SegmentVector<HeatmapTextureAttributes> heatmapTextureSegments;
optional<gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>> depthRenderbuffer;
bool has3D = false;