diff options
Diffstat (limited to 'src/mbgl/renderer/layers/render_fill_layer.cpp')
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_layer.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index f1c7e97067..22cb9563c1 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -1,5 +1,11 @@ #include <mbgl/renderer/layers/render_fill_layer.hpp> #include <mbgl/renderer/buckets/fill_bucket.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/renderer/paint_parameters.hpp> +#include <mbgl/renderer/image_manager.hpp> +#include <mbgl/programs/programs.hpp> +#include <mbgl/programs/fill_program.hpp> +#include <mbgl/tile/tile.hpp> #include <mbgl/style/layers/fill_layer_impl.hpp> #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> @@ -7,6 +13,8 @@ namespace mbgl { +using namespace style; + RenderFillLayer::RenderFillLayer(Immutable<style::FillLayer::Impl> _impl) : RenderLayer(style::LayerType::Fill, _impl), unevaluated(impl().paint.untransitioned()) { @@ -50,6 +58,132 @@ bool RenderFillLayer::hasTransition() const { return unevaluated.hasTransition(); } +void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { + if (evaluated.get<FillPattern>().from.empty()) { + for (const RenderTile& tile : renderTiles) { + assert(dynamic_cast<FillBucket*>(tile.tile.getBucket(*baseImpl))); + FillBucket& bucket = *reinterpret_cast<FillBucket*>(tile.tile.getBucket(*baseImpl)); + + auto draw = [&] (auto& program, + const auto& drawMode, + const auto& depthMode, + const auto& indexBuffer, + const auto& segments) { + program.get(evaluated).draw( + parameters.context, + drawMode, + depthMode, + parameters.stencilModeForClipping(tile.clip), + parameters.colorModeForRenderPass(), + FillProgram::UniformValues { + uniforms::u_matrix::Value{ + tile.translatedMatrix(evaluated.get<FillTranslate>(), + evaluated.get<FillTranslateAnchor>(), + parameters.state) + }, + uniforms::u_world::Value{ parameters.context.viewport.getCurrentValue().size }, + }, + *bucket.vertexBuffer, + indexBuffer, + segments, + bucket.paintPropertyBinders.at(getID()), + evaluated, + parameters.state.getZoom(), + getID() + ); + }; + + // Only draw the fill when it's opaque and we're drawing opaque fragments, + // or when it's translucent and we're drawing translucent fragments. + if ((evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f + && evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) { + draw(parameters.programs.fill, + gl::Triangles(), + parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque + ? gl::DepthMode::ReadWrite + : gl::DepthMode::ReadOnly), + *bucket.triangleIndexBuffer, + bucket.triangleSegments); + } + + if (evaluated.get<FillAntialias>() && parameters.pass == RenderPass::Translucent) { + draw(parameters.programs.fillOutline, + gl::Lines{ 2.0f }, + parameters.depthModeForSublayer( + unevaluated.get<FillOutlineColor>().isUndefined() ? 2 : 0, + gl::DepthMode::ReadOnly), + *bucket.lineIndexBuffer, + bucket.lineSegments); + } + } + } else { + if (parameters.pass != RenderPass::Translucent) { + return; + } + + optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<FillPattern>().from); + optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<FillPattern>().to); + + if (!imagePosA || !imagePosB) { + return; + } + + parameters.imageManager.bind(parameters.context, 0); + + for (const RenderTile& tile : renderTiles) { + assert(dynamic_cast<FillBucket*>(tile.tile.getBucket(*baseImpl))); + FillBucket& bucket = *reinterpret_cast<FillBucket*>(tile.tile.getBucket(*baseImpl)); + + auto draw = [&] (auto& program, + const auto& drawMode, + const auto& depthMode, + const auto& indexBuffer, + const auto& segments) { + program.get(evaluated).draw( + parameters.context, + drawMode, + depthMode, + parameters.stencilModeForClipping(tile.clip), + parameters.colorModeForRenderPass(), + FillPatternUniforms::values( + tile.translatedMatrix(evaluated.get<FillTranslate>(), + evaluated.get<FillTranslateAnchor>(), + parameters.state), + parameters.context.viewport.getCurrentValue().size, + parameters.imageManager.getPixelSize(), + *imagePosA, + *imagePosB, + evaluated.get<FillPattern>(), + tile.id, + parameters.state + ), + *bucket.vertexBuffer, + indexBuffer, + segments, + bucket.paintPropertyBinders.at(getID()), + evaluated, + parameters.state.getZoom(), + getID() + ); + }; + + draw(parameters.programs.fillPattern, + gl::Triangles(), + parameters.depthModeForSublayer(1, gl::DepthMode::ReadWrite), + *bucket.triangleIndexBuffer, + bucket.triangleSegments); + + if (evaluated.get<FillAntialias>() && unevaluated.get<FillOutlineColor>().isUndefined()) { + draw(parameters.programs.fillOutlinePattern, + gl::Lines { 2.0f }, + parameters.depthModeForSublayer(2, gl::DepthMode::ReadOnly), + *bucket.lineIndexBuffer, + bucket.lineSegments); + } + } + } +} + bool RenderFillLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, |