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