#include #include #include #include #include #include #include #include #include #include #include namespace mbgl { using namespace style; inline const BackgroundLayer::Impl& impl(const Immutable& impl) { return static_cast(*impl); } RenderBackgroundLayer::RenderBackgroundLayer(Immutable _impl) : RenderLayer(makeMutable(std::move(_impl))), unevaluated(impl(baseImpl).paint.untransitioned()) { } RenderBackgroundLayer::~RenderBackgroundLayer() = default; void RenderBackgroundLayer::transition(const TransitionParameters ¶meters) { unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶meters) { auto properties = makeMutable( staticImmutableCast(baseImpl), parameters.getCrossfadeParameters(), unevaluated.evaluate(parameters)); passes = properties->evaluated.get() > 0 ? RenderPass::Translucent : RenderPass::None; evaluatedProperties = std::move(properties); } bool RenderBackgroundLayer::hasTransition() const { return unevaluated.hasTransition(); } bool RenderBackgroundLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { // Note that for bottommost layers without a pattern, the background color is drawn with // glClear rather than this method. const Properties<>::PossiblyEvaluated properties; const BackgroundProgram::Binders paintAttributeData(properties, 0); auto draw = [&](auto& program, auto&& uniformValues, const auto& textureBindings) { const auto allUniformValues = program.computeAllUniformValues( std::move(uniformValues), paintAttributeData, properties, parameters.state.getZoom() ); const auto allAttributeBindings = program.computeAllAttributeBindings( parameters.staticData.tileVertexBuffer, paintAttributeData, properties ); checkRenderability(parameters, program.activeBindingCount(allAttributeBindings)); program.draw( parameters.context, *parameters.renderPass, gfx::Triangles(), parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.tileTriangleSegments, allUniformValues, allAttributeBindings, textureBindings, getID() ); }; const auto& evaluated = static_cast(*evaluatedProperties).evaluated; const auto& crossfade = static_cast(*evaluatedProperties).crossfade; if (!evaluated.get().to.empty()) { optional imagePosA = parameters.imageManager.getPattern(evaluated.get().from); optional imagePosB = parameters.imageManager.getPattern(evaluated.get().to); if (!imagePosA || !imagePosB) return; for (const auto& tileID : util::tileCover(parameters.state, parameters.state.getIntegerZoom())) { draw( parameters.programs.getBackgroundLayerPrograms().backgroundPattern, BackgroundPatternProgram::layoutUniformValues( parameters.matrixForTile(tileID), evaluated.get(), parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, crossfade, tileID, parameters.state ), BackgroundPatternProgram::TextureBindings{ textures::image::Value{ parameters.imageManager.textureBinding(parameters.context) }, } ); } } else { for (const auto& tileID : util::tileCover(parameters.state, parameters.state.getIntegerZoom())) { draw( parameters.programs.getBackgroundLayerPrograms().background, BackgroundProgram::LayoutUniformValues { uniforms::matrix::Value( parameters.matrixForTile(tileID) ), uniforms::color::Value( evaluated.get() ), uniforms::opacity::Value( evaluated.get() ), }, BackgroundProgram::TextureBindings{} ); } } } optional RenderBackgroundLayer::getSolidBackground() const { const auto& evaluated = static_cast(*evaluatedProperties).evaluated; if (!evaluated.get().from.empty()) { return nullopt; } return { evaluated.get() * evaluated.get() }; } } // namespace mbgl