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/collision_box.hpp> 7 #include <mbgl/shaders/collision_circle.hpp> 8 #include <mbgl/style/properties.hpp> 9 #include <mbgl/util/geometry.hpp> 10 11 #include <cmath> 12 13 namespace mbgl { 14 15 using CollisionBoxLayoutAttributes = gl::Attributes< 16 attributes::a_pos, 17 attributes::a_anchor_pos, 18 attributes::a_extrude>; 19 20 struct CollisionBoxDynamicAttributes : gl::Attributes<attributes::a_placed> { vertexmbgl::CollisionBoxDynamicAttributes21 static Vertex vertex(bool placed, bool notUsed) { 22 return Vertex { 23 {{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed) }} 24 }; 25 } 26 }; 27 28 class CollisionBoxProgram : public Program< 29 shaders::collision_box, 30 gl::Line, 31 gl::ConcatenateAttributes<CollisionBoxLayoutAttributes, CollisionBoxDynamicAttributes>, 32 gl::Uniforms< 33 uniforms::u_matrix, 34 uniforms::u_extrude_scale, 35 uniforms::u_camera_to_center_distance>, 36 style::Properties<>> 37 { 38 public: 39 using Program::Program; 40 vertex(Point<float> a,Point<float> anchor,Point<float> o)41 static CollisionBoxLayoutAttributes::Vertex vertex(Point<float> a, Point<float> anchor, Point<float> o) { 42 return CollisionBoxLayoutAttributes::Vertex { 43 {{ 44 static_cast<int16_t>(a.x), 45 static_cast<int16_t>(a.y) 46 }}, 47 {{ 48 static_cast<int16_t>(anchor.x), 49 static_cast<int16_t>(anchor.y) 50 }}, 51 {{ 52 static_cast<int16_t>(::round(o.x)), 53 static_cast<int16_t>(::round(o.y)) 54 }} 55 }; 56 } 57 58 template <class DrawMode> draw(gl::Context & context,DrawMode drawMode,gl::DepthMode depthMode,gl::StencilMode stencilMode,gl::ColorMode colorMode,const UniformValues & uniformValues,const gl::VertexBuffer<CollisionBoxLayoutAttributes::Vertex> & layoutVertexBuffer,const gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex> & dynamicVertexBuffer,const gl::IndexBuffer<DrawMode> & indexBuffer,const SegmentVector<Attributes> & segments,const PaintPropertyBinders & paintPropertyBinders,const typename PaintProperties::PossiblyEvaluated & currentProperties,float currentZoom,const std::string & layerID)59 void draw(gl::Context& context, 60 DrawMode drawMode, 61 gl::DepthMode depthMode, 62 gl::StencilMode stencilMode, 63 gl::ColorMode colorMode, 64 const UniformValues& uniformValues, 65 const gl::VertexBuffer<CollisionBoxLayoutAttributes::Vertex>& layoutVertexBuffer, 66 const gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex>& dynamicVertexBuffer, 67 const gl::IndexBuffer<DrawMode>& indexBuffer, 68 const SegmentVector<Attributes>& segments, 69 const PaintPropertyBinders& paintPropertyBinders, 70 const typename PaintProperties::PossiblyEvaluated& currentProperties, 71 float currentZoom, 72 const std::string& layerID) { 73 typename AllUniforms::Values allUniformValues = uniformValues 74 .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); 75 76 typename Attributes::Bindings allAttributeBindings = CollisionBoxLayoutAttributes::bindings(layoutVertexBuffer) 77 .concat(CollisionBoxDynamicAttributes::bindings(dynamicVertexBuffer)) 78 .concat(paintPropertyBinders.attributeBindings(currentProperties)); 79 80 assert(layoutVertexBuffer.vertexCount == dynamicVertexBuffer.vertexCount); 81 82 for (auto& segment : segments) { 83 auto vertexArrayIt = segment.vertexArrays.find(layerID); 84 85 if (vertexArrayIt == segment.vertexArrays.end()) { 86 vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; 87 } 88 89 program.draw( 90 context, 91 std::move(drawMode), 92 std::move(depthMode), 93 std::move(stencilMode), 94 std::move(colorMode), 95 allUniformValues, 96 vertexArrayIt->second, 97 Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), 98 indexBuffer, 99 segment.indexOffset, 100 segment.indexLength); 101 } 102 } 103 }; 104 105 106 class CollisionCircleProgram : public Program< 107 shaders::collision_circle, 108 gl::Triangle, 109 gl::ConcatenateAttributes<CollisionBoxLayoutAttributes, CollisionBoxDynamicAttributes>, 110 gl::Uniforms< 111 uniforms::u_matrix, 112 uniforms::u_extrude_scale, 113 uniforms::u_overscale_factor, 114 uniforms::u_camera_to_center_distance>, 115 style::Properties<>> 116 { 117 public: 118 using Program::Program; 119 vertex(Point<float> a,Point<float> anchor,Point<float> o)120 static CollisionBoxLayoutAttributes::Vertex vertex(Point<float> a, Point<float> anchor, Point<float> o) { 121 return CollisionBoxLayoutAttributes::Vertex { 122 {{ 123 static_cast<int16_t>(a.x), 124 static_cast<int16_t>(a.y) 125 }}, 126 {{ 127 static_cast<int16_t>(anchor.x), 128 static_cast<int16_t>(anchor.y) 129 }}, 130 {{ 131 static_cast<int16_t>(::round(o.x)), 132 static_cast<int16_t>(::round(o.y)) 133 }} 134 }; 135 } 136 137 template <class DrawMode> draw(gl::Context & context,DrawMode drawMode,gl::DepthMode depthMode,gl::StencilMode stencilMode,gl::ColorMode colorMode,const UniformValues & uniformValues,const gl::VertexBuffer<CollisionBoxLayoutAttributes::Vertex> & layoutVertexBuffer,const gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex> & dynamicVertexBuffer,const gl::IndexBuffer<DrawMode> & indexBuffer,const SegmentVector<Attributes> & segments,const PaintPropertyBinders & paintPropertyBinders,const typename PaintProperties::PossiblyEvaluated & currentProperties,float currentZoom,const std::string & layerID)138 void draw(gl::Context& context, 139 DrawMode drawMode, 140 gl::DepthMode depthMode, 141 gl::StencilMode stencilMode, 142 gl::ColorMode colorMode, 143 const UniformValues& uniformValues, 144 const gl::VertexBuffer<CollisionBoxLayoutAttributes::Vertex>& layoutVertexBuffer, 145 const gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex>& dynamicVertexBuffer, 146 const gl::IndexBuffer<DrawMode>& indexBuffer, 147 const SegmentVector<Attributes>& segments, 148 const PaintPropertyBinders& paintPropertyBinders, 149 const typename PaintProperties::PossiblyEvaluated& currentProperties, 150 float currentZoom, 151 const std::string& layerID) { 152 typename AllUniforms::Values allUniformValues = uniformValues 153 .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); 154 155 typename Attributes::Bindings allAttributeBindings = CollisionBoxLayoutAttributes::bindings(layoutVertexBuffer) 156 .concat(CollisionBoxDynamicAttributes::bindings(dynamicVertexBuffer)) 157 .concat(paintPropertyBinders.attributeBindings(currentProperties)); 158 159 for (auto& segment : segments) { 160 auto vertexArrayIt = segment.vertexArrays.find(layerID); 161 162 if (vertexArrayIt == segment.vertexArrays.end()) { 163 vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; 164 } 165 166 program.draw( 167 context, 168 std::move(drawMode), 169 std::move(depthMode), 170 std::move(stencilMode), 171 std::move(colorMode), 172 allUniformValues, 173 vertexArrayIt->second, 174 Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), 175 indexBuffer, 176 segment.indexOffset, 177 segment.indexLength); 178 } 179 } 180 }; 181 182 using CollisionBoxVertex = CollisionBoxProgram::LayoutVertex; 183 184 } // namespace mbgl 185