summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/painter_line.cpp
blob: 377c956e7cf44a4f0d16e12a7ca1d01fe8a650c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/line_layer_impl.hpp>
#include <mbgl/shader/shaders.hpp>
#include <mbgl/shader/line_uniforms.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>

namespace mbgl {

using namespace style;

void Painter::renderLine(PaintParameters& parameters,
                         LineBucket& bucket,
                         const LineLayer& layer,
                         const RenderTile& tile) {
    if (pass == RenderPass::Opaque) {
        return;
    }

    const auto& properties = layer.impl->paint;

    auto draw = [&] (auto& shader, auto&& uniformValues) {
        context.draw({
            depthModeForSublayer(0, gl::DepthMode::ReadOnly),
            stencilModeForClipping(tile.clip),
            colorModeForRenderPass(),
            shader,
            std::move(uniformValues),
            gl::Segmented<gl::Triangles>(
                *bucket.vertexBuffer,
                *bucket.indexBuffer,
                bucket.segments
            )
        });
    };

    if (!properties.lineDasharray.value.from.empty()) {
        const LinePatternCap cap = bucket.layout.lineCap == LineCapType::Round
            ? LinePatternCap::Round : LinePatternCap::Square;
        LinePatternPos posA = lineAtlas->getDashPosition(properties.lineDasharray.value.from, cap);
        LinePatternPos posB = lineAtlas->getDashPosition(properties.lineDasharray.value.to, cap);

        lineAtlas->bind(context, 0);

        draw(parameters.shaders.lineSDF,
             LineSDFUniforms::values(
                 properties,
                 frame.pixelRatio,
                 tile,
                 state,
                 posA,
                 posB,
                 layer.impl->dashLineWidth,
                 lineAtlas->getSize().width));

    } else if (!properties.linePattern.value.from.empty()) {
        optional<SpriteAtlasPosition> posA = spriteAtlas->getPosition(
            properties.linePattern.value.from, SpritePatternMode::Repeating);
        optional<SpriteAtlasPosition> posB = spriteAtlas->getPosition(
            properties.linePattern.value.to, SpritePatternMode::Repeating);

        if (!posA || !posB)
            return;

        spriteAtlas->bind(true, context, 0);

        draw(parameters.shaders.linePattern,
             LinePatternUniforms::values(
                 properties,
                 frame.pixelRatio,
                 tile,
                 state,
                 *posA,
                 *posB));

    } else {
        draw(parameters.shaders.line,
             LineColorUniforms::values(
                 properties,
                 frame.pixelRatio,
                 tile,
                 state));
    }
}

} // namespace mbgl