1 #pragma once
2 
3 #include <mbgl/programs/program.hpp>
4 #include <mbgl/programs/attributes.hpp>
5 #include <mbgl/programs/uniforms.hpp>
6 #include <mbgl/shaders/line.hpp>
7 #include <mbgl/shaders/line_pattern.hpp>
8 #include <mbgl/shaders/line_sdf.hpp>
9 #include <mbgl/util/geometry.hpp>
10 #include <mbgl/renderer/layers/render_line_layer.hpp>
11 
12 #include <cmath>
13 
14 namespace mbgl {
15 
16 class RenderTile;
17 class TransformState;
18 class LinePatternPos;
19 class ImagePosition;
20 
21 namespace uniforms {
22 MBGL_DEFINE_UNIFORM_SCALAR(float, u_ratio);
23 MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_a);
24 MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_b);
25 MBGL_DEFINE_UNIFORM_SCALAR(float, u_sdfgamma);
26 MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade);
27 MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_a);
28 MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_b);
29 MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_gl_units_to_pixels);
30 } // namespace uniforms
31 
32 struct LineLayoutAttributes : gl::Attributes<
33     attributes::a_pos_normal,
34     attributes::a_data<uint8_t, 4>>
35 {};
36 
37 class LineProgram : public Program<
38     shaders::line,
39     gl::Triangle,
40     LineLayoutAttributes,
41     gl::Uniforms<
42         uniforms::u_matrix,
43         uniforms::u_ratio,
44         uniforms::u_gl_units_to_pixels>,
45     RenderLinePaintProperties>
46 {
47 public:
48     using Program::Program;
49 
50     /*
51      * @param p vertex position
52      * @param e extrude normal
53      * @param round whether the vertex uses a round line cap
54      * @param up whether the line normal points up or down
55      * @param dir direction of the line cap (-1/0/1)
56      */
layoutVertex(Point<int16_t> p,Point<double> e,bool round,bool up,int8_t dir,int32_t linesofar=0)57     static LayoutVertex layoutVertex(Point<int16_t> p, Point<double> e, bool round, bool up, int8_t dir, int32_t linesofar = 0) {
58         return LayoutVertex {
59             {{
60                 p.x,
61                 p.y,
62                 static_cast<int16_t>(round ? 1 : 0),
63                 static_cast<int16_t>(up ? 1 : -1)
64             }},
65             {{
66                 // add 128 to store a byte in an unsigned byte
67                 static_cast<uint8_t>(::round(extrudeScale * e.x) + 128),
68                 static_cast<uint8_t>(::round(extrudeScale * e.y) + 128),
69 
70                 // Encode the -1/0/1 direction value into the first two bits of .z of a_data.
71                 // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make
72                 // room for the direction value). The upper 8 bits of `linesofar` are placed in
73                 // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that
74                 // we can store longer distances while sacrificing precision.
75 
76                 // Encode the -1/0/1 direction value into .zw coordinates of a_data, which is normally covered
77                 // by linesofar, so we need to merge them.
78                 // The z component's first bit, as well as the sign bit is reserved for the direction,
79                 // so we need to shift the linesofar.
80                 static_cast<uint8_t>(((dir == 0 ? 0 : (dir < 0 ? -1 : 1 )) + 1) | ((linesofar & 0x3F) << 2)),
81                 static_cast<uint8_t>(linesofar >> 6)
82             }}
83         };
84     }
85 
86     /*
87      * Scale the extrusion vector so that the normal length is this value.
88      * Contains the "texture" normals (-1..1). This is distinct from the extrude
89      * normals for line joins, because the x-value remains 0 for the texture
90      * normal array, while the extrude normal actually moves the vertex to create
91      * the acute/bevelled line join.
92      */
93     static const int8_t extrudeScale = 63;
94 
95     static UniformValues uniformValues(const RenderLinePaintProperties::PossiblyEvaluated&,
96                                        const RenderTile&,
97                                        const TransformState&,
98                                        const std::array<float, 2>& pixelsToGLUnits);
99 };
100 
101 class LinePatternProgram : public Program<
102     shaders::line_pattern,
103     gl::Triangle,
104     LineLayoutAttributes,
105     gl::Uniforms<
106         uniforms::u_matrix,
107         uniforms::u_ratio,
108         uniforms::u_gl_units_to_pixels,
109         uniforms::u_pattern_tl_a,
110         uniforms::u_pattern_br_a,
111         uniforms::u_pattern_tl_b,
112         uniforms::u_pattern_br_b,
113         uniforms::u_pattern_size_a,
114         uniforms::u_pattern_size_b,
115         uniforms::u_texsize,
116         uniforms::u_fade,
117         uniforms::u_image>,
118     RenderLinePaintProperties>
119 {
120 public:
121     using Program::Program;
122 
123     static UniformValues uniformValues(const RenderLinePaintProperties::PossiblyEvaluated&,
124                                        const RenderTile&,
125                                        const TransformState&,
126                                        const std::array<float, 2>& pixelsToGLUnits,
127                                        Size atlasSize,
128                                        const ImagePosition& posA,
129                                        const ImagePosition& posB);
130 };
131 
132 class LineSDFProgram : public Program<
133     shaders::line_sdf,
134     gl::Triangle,
135     LineLayoutAttributes,
136     gl::Uniforms<
137         uniforms::u_matrix,
138         uniforms::u_ratio,
139         uniforms::u_gl_units_to_pixels,
140         uniforms::u_patternscale_a,
141         uniforms::u_patternscale_b,
142         uniforms::u_tex_y_a,
143         uniforms::u_tex_y_b,
144         uniforms::u_mix,
145         uniforms::u_sdfgamma,
146         uniforms::u_image>,
147     RenderLinePaintProperties>
148 {
149 public:
150     using Program::Program;
151 
152     static UniformValues uniformValues(const RenderLinePaintProperties::PossiblyEvaluated&,
153                                        float pixelRatio,
154                                        const RenderTile&,
155                                        const TransformState&,
156                                        const std::array<float, 2>& pixelsToGLUnits,
157                                        const LinePatternPos& posA,
158                                        const LinePatternPos& posB,
159                                        float atlasWidth);
160 };
161 
162 using LineLayoutVertex = LineProgram::LayoutVertex;
163 using LineAttributes = LineProgram::Attributes;
164 
165 } // namespace mbgl
166