#include #include #include #include #include #include #include #include #include #include namespace mbgl { using namespace style; void Painter::renderFill(PaintParameters& parameters, FillBucket& bucket, const FillLayer& layer, const RenderTile& tile) { const FillPaintProperties::Evaluated& properties = layer.impl->paint.evaluated; if (!properties.get().from.empty()) { if (pass != RenderPass::Translucent) { return; } optional imagePosA = spriteAtlas->getPosition( properties.get().from, SpritePatternMode::Repeating); optional imagePosB = spriteAtlas->getPosition( properties.get().to, SpritePatternMode::Repeating); if (!imagePosA || !imagePosB) { return; } spriteAtlas->bind(true, context, 0); auto draw = [&] (uint8_t sublayer, auto& program, const auto& drawMode, const auto& vertexBuffer, const auto& indexBuffer, const auto& segments) { program.draw( context, drawMode, depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite), stencilModeForClipping(tile.clip), colorModeForRenderPass(), FillPatternUniforms::values( tile.translatedMatrix(properties.get(), properties.get(), state), properties.get(), context.viewport.getCurrentValue().size, *imagePosA, *imagePosB, properties.get(), tile.id, state ), vertexBuffer, indexBuffer, segments ); }; draw(0, parameters.programs.fillPattern, gl::Triangles(), *bucket.vertexBuffer, *bucket.triangleIndexBuffer, bucket.triangleSegments); if (!properties.get() || !layer.impl->paint.unevaluated.get().isUndefined()) { return; } draw(2, parameters.programs.fillOutlinePattern, gl::Lines { 2.0f }, *bucket.vertexBuffer, *bucket.lineIndexBuffer, bucket.lineSegments); } else { auto draw = [&] (uint8_t sublayer, auto& program, Color outlineColor, const auto& drawMode, const auto& vertexBuffer, const auto& indexBuffer, const auto& segments) { program.draw( context, drawMode, depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite), stencilModeForClipping(tile.clip), colorModeForRenderPass(), FillProgram::UniformValues { uniforms::u_matrix::Value{ tile.translatedMatrix(properties.get(), properties.get(), state) }, uniforms::u_opacity::Value{ properties.get() }, uniforms::u_color::Value{ properties.get() }, uniforms::u_outline_color::Value{ outlineColor }, uniforms::u_world::Value{ context.viewport.getCurrentValue().size }, }, vertexBuffer, indexBuffer, segments ); }; if (properties.get() && !layer.impl->paint.unevaluated.get().isUndefined() && pass == RenderPass::Translucent) { draw(2, parameters.programs.fillOutline, properties.get(), gl::Lines { 2.0f }, *bucket.vertexBuffer, *bucket.lineIndexBuffer, bucket.lineSegments); } // 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 ((properties.get().a >= 1.0f && properties.get() >= 1.0f) == (pass == RenderPass::Opaque)) { draw(1, parameters.programs.fill, properties.get(), gl::Triangles(), *bucket.vertexBuffer, *bucket.triangleIndexBuffer, bucket.triangleSegments); } if (properties.get() && layer.impl->paint.unevaluated.get().isUndefined() && pass == RenderPass::Translucent) { draw(2, parameters.programs.fillOutline, properties.get(), gl::Lines { 2.0f }, *bucket.vertexBuffer, *bucket.lineIndexBuffer, bucket.lineSegments); } } } } // namespace mbgl