diff options
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp | 193 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_heatmap_layer.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_parameters.cpp | 24 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_parameters.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/render_static_data.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/renderer/render_static_data.hpp | 6 |
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; |