1 #include <mbgl/programs/symbol_program.hpp>
2 #include <mbgl/renderer/render_tile.hpp>
3 #include <mbgl/map/transform_state.hpp>
4 #include <mbgl/style/layers/symbol_layer_impl.hpp>
5 #include <mbgl/layout/symbol_projection.hpp>
6 #include <mbgl/tile/tile.hpp>
7 #include <mbgl/util/enum.hpp>
8 #include <mbgl/math/clamp.hpp>
9
10 namespace mbgl {
11
12 using namespace style;
13
14 static_assert(sizeof(SymbolLayoutVertex) == 16, "expected SymbolLayoutVertex size");
15
create(const float tileZoom,const style::DataDrivenPropertyValue<float> & sizeProperty,const float defaultValue)16 std::unique_ptr<SymbolSizeBinder> SymbolSizeBinder::create(const float tileZoom,
17 const style::DataDrivenPropertyValue<float>& sizeProperty,
18 const float defaultValue) {
19 return sizeProperty.match(
20 [&] (const Undefined& value) -> std::unique_ptr<SymbolSizeBinder> {
21 return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, value, defaultValue);
22 },
23 [&] (float value) -> std::unique_ptr<SymbolSizeBinder> {
24 return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, value, defaultValue);
25 },
26 [&] (const style::PropertyExpression<float>& expression) -> std::unique_ptr<SymbolSizeBinder> {
27 if (expression.isFeatureConstant()) {
28 return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, expression, defaultValue);
29 } else if (expression.isZoomConstant()) {
30 return std::make_unique<SourceFunctionSymbolSizeBinder>(tileZoom, expression, defaultValue);
31 } else {
32 return std::make_unique<CompositeFunctionSymbolSizeBinder>(tileZoom, expression, defaultValue);
33 }
34 }
35 );
36 }
37
38 template <class Values, class...Args>
makeValues(const bool isText,const style::SymbolPropertyValues & values,const Size & texsize,const std::array<float,2> & pixelsToGLUnits,const bool alongLine,const RenderTile & tile,const TransformState & state,const float symbolFadeChange,Args &&...args)39 Values makeValues(const bool isText,
40 const style::SymbolPropertyValues& values,
41 const Size& texsize,
42 const std::array<float, 2>& pixelsToGLUnits,
43 const bool alongLine,
44 const RenderTile& tile,
45 const TransformState& state,
46 const float symbolFadeChange,
47 Args&&... args) {
48 std::array<float, 2> extrudeScale;
49
50 if (values.pitchAlignment == AlignmentType::Map) {
51 extrudeScale.fill(tile.id.pixelsToTileUnits(1, state.getZoom()));
52 } else {
53 extrudeScale = {{
54 pixelsToGLUnits[0] * state.getCameraToCenterDistance(),
55 pixelsToGLUnits[1] * state.getCameraToCenterDistance()
56 }};
57 }
58
59 const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, state.getZoom());
60 const bool pitchWithMap = values.pitchAlignment == style::AlignmentType::Map;
61 const bool rotateWithMap = values.rotationAlignment == style::AlignmentType::Map;
62
63 // Line label rotation happens in `updateLineLabels`
64 // Pitched point labels are automatically rotated by the labelPlaneMatrix projection
65 // Unpitched point labels need to have their rotation applied after projection
66 const bool rotateInShader = rotateWithMap && !pitchWithMap && !alongLine;
67
68 mat4 labelPlaneMatrix;
69 if (alongLine) {
70 // For labels that follow lines the first part of the projection is handled on the cpu.
71 // Pass an identity matrix because no transformation needs to be done in the vertex shader.
72 matrix::identity(labelPlaneMatrix);
73 } else {
74 labelPlaneMatrix = getLabelPlaneMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits);
75 }
76
77 mat4 glCoordMatrix = getGlCoordMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits);
78
79 return Values {
80 uniforms::u_matrix::Value{ tile.translatedMatrix(values.translate,
81 values.translateAnchor,
82 state) },
83 uniforms::u_label_plane_matrix::Value{labelPlaneMatrix},
84 uniforms::u_gl_coord_matrix::Value{ tile.translateVtxMatrix(glCoordMatrix,
85 values.translate,
86 values.translateAnchor,
87 state,
88 true) },
89 uniforms::u_extrude_scale::Value{ extrudeScale },
90 uniforms::u_texsize::Value{ texsize },
91 uniforms::u_texture::Value{ 0 },
92 uniforms::u_fade_change::Value{ symbolFadeChange },
93 uniforms::u_is_text::Value{ isText },
94 uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() },
95 uniforms::u_pitch::Value{ state.getPitch() },
96 uniforms::u_pitch_with_map::Value{ pitchWithMap },
97 uniforms::u_rotate_symbol::Value{ rotateInShader },
98 uniforms::u_aspect_ratio::Value{ state.getSize().aspectRatio() },
99 std::forward<Args>(args)...
100 };
101 }
102
103 SymbolIconProgram::UniformValues
uniformValues(const bool isText,const style::SymbolPropertyValues & values,const Size & texsize,const std::array<float,2> & pixelsToGLUnits,const bool alongLine,const RenderTile & tile,const TransformState & state,const float symbolFadeChange)104 SymbolIconProgram::uniformValues(const bool isText,
105 const style::SymbolPropertyValues& values,
106 const Size& texsize,
107 const std::array<float, 2>& pixelsToGLUnits,
108 const bool alongLine,
109 const RenderTile& tile,
110 const TransformState& state,
111 const float symbolFadeChange)
112 {
113 return makeValues<SymbolIconProgram::UniformValues>(
114 isText,
115 values,
116 texsize,
117 pixelsToGLUnits,
118 alongLine,
119 tile,
120 state,
121 symbolFadeChange
122 );
123 }
124
125 template <class PaintProperties>
uniformValues(const bool isText,const style::SymbolPropertyValues & values,const Size & texsize,const std::array<float,2> & pixelsToGLUnits,const bool alongLine,const RenderTile & tile,const TransformState & state,const float symbolFadeChange,const SymbolSDFPart part)126 typename SymbolSDFProgram<PaintProperties>::UniformValues SymbolSDFProgram<PaintProperties>::uniformValues(
127 const bool isText,
128 const style::SymbolPropertyValues& values,
129 const Size& texsize,
130 const std::array<float, 2>& pixelsToGLUnits,
131 const bool alongLine,
132 const RenderTile& tile,
133 const TransformState& state,
134 const float symbolFadeChange,
135 const SymbolSDFPart part)
136 {
137 const float gammaScale = (values.pitchAlignment == AlignmentType::Map
138 ? std::cos(state.getPitch()) * state.getCameraToCenterDistance()
139 : 1.0);
140
141 return makeValues<SymbolSDFProgram<PaintProperties>::UniformValues>(
142 isText,
143 values,
144 texsize,
145 pixelsToGLUnits,
146 alongLine,
147 tile,
148 state,
149 symbolFadeChange,
150 uniforms::u_gamma_scale::Value{ gammaScale },
151 uniforms::u_is_halo::Value{ part == SymbolSDFPart::Halo }
152 );
153 }
154
155 template class SymbolSDFProgram<style::IconPaintProperties>;
156 template class SymbolSDFProgram<style::TextPaintProperties>;
157
158 } // namespace mbgl
159