summaryrefslogtreecommitdiff
path: root/include/llmr/renderer/painter.hpp
blob: 3a96f8100173d8208e631a076ee67c6c7dde7b2a (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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef LLMR_RENDERER_PAINTER
#define LLMR_RENDERER_PAINTER

#include <llmr/map/tile_data.hpp>
#include <llmr/geometry/vao.hpp>
#include <llmr/geometry/vertex_buffer.hpp>
#include <llmr/util/mat4.hpp>
#include <llmr/util/noncopyable.hpp>
#include <llmr/renderer/frame_history.hpp>

#include <llmr/shader/plain_shader.hpp>
#include <llmr/shader/outline_shader.hpp>
#include <llmr/shader/pattern_shader.hpp>
#include <llmr/shader/line_shader.hpp>
#include <llmr/shader/linejoin_shader.hpp>
#include <llmr/shader/point_shader.hpp>
#include <llmr/shader/raster_shader.hpp>
#include <llmr/shader/text_shader.hpp>

namespace llmr {

class Transform;
class Settings;
class Style;
class Tile;

class FillBucket;
class LineBucket;
class PointBucket;
class TextBucket;

class Painter : private util::noncopyable {
public:
    Painter(Transform& transform, Settings& settings, Style& style, GlyphAtlas& glyphAtlas);

    void setup();
    void clear();
    void changeMatrix();
    void render(const Tile& tile);
    void renderMatte();
    void renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id);
    void renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id);
    void renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id);
    void renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id);

    void resize();

    void prepareClippingMask();
    void drawClippingMask(const mat4& matrix, uint8_t clip_id, bool opaque = true);
    void finishClippingMask();

    bool needsAnimation() const;
private:
    void setupShaders();
    void renderRaster(const std::shared_ptr<TileData>& tile);
    void renderLayers(const std::shared_ptr<TileData>& tile, const std::vector<LayerDescription>& layers);
    void renderLayer(const std::shared_ptr<TileData>& tile_data, const LayerDescription& layer_desc);
    void renderDebug(const std::shared_ptr<TileData>& tile);

    void useProgram(uint32_t program);
    void lineWidth(float lineWidth);
    void depthMask(bool value);

public:
    mat4 matrix;
    mat4 projMatrix;
    mat4 nativeMatrix;
    mat4 extrudeMatrix;

private:
    Transform& transform;
    Settings& settings;
    Style& style;
    GlyphAtlas& glyphAtlas;

    FrameHistory frameHistory;

    uint32_t gl_program = 0;
    float gl_lineWidth = 0;
    bool gl_depthMask = true;
    float strata = 0;
    const float strata_epsilon = 1.0f / (1 << 16);
    enum { Opaque, Translucent } pass = Opaque;

    std::unique_ptr<PlainShader> plainShader;
    std::unique_ptr<OutlineShader> outlineShader;
    std::unique_ptr<LineShader> lineShader;
    std::unique_ptr<LinejoinShader> linejoinShader;
    std::unique_ptr<PatternShader> patternShader;
    std::unique_ptr<PointShader> pointShader;
    std::unique_ptr<RasterShader> rasterShader;
    std::unique_ptr<TextShader> textShader;

    // Set up the stencil quad we're using to generate the stencil mask.
    VertexBuffer tileStencilBuffer = {
        // top left triangle
        0, 0,
        4096, 0,
        0, 4096,

        // bottom right triangle
        4096, 0,
        0, 4096,
        4096, 4096
    };

    VertexArrayObject coveringPlainArray;
    VertexArrayObject coveringPatternArray;
    VertexArrayObject coveringRasterArray;

    // Set up the tile boundary lines we're using to draw the tile outlines.
    VertexBuffer tileBorderBuffer = {
        0, 0,
        4096, 0,
        4096, 4096,
        0, 4096,
        0, 0
    };

    VertexArrayObject tileBorderArray;

    // Set up the matte buffer we're using to draw the filling background.
    VertexBuffer matteBuffer = {
        // top left triangle
        0, 0,
        1920, 0,
        0, 1080,

        // bottom right triangle
        1920, 0,
        0, 1080,
        1920, 1080
    };

    VertexArrayObject matteArray;
};

}

#endif