summaryrefslogtreecommitdiff
path: root/src/mbgl/programs/collision_box_program.hpp
blob: 2547da9f18b7a4dc5083b47ab1e97f5ec30c8dfd (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
#pragma once

#include <mbgl/programs/program.hpp>
#include <mbgl/programs/attributes.hpp>
#include <mbgl/programs/uniforms.hpp>
#include <mbgl/shaders/collision_box.hpp>
#include <mbgl/style/properties.hpp>
#include <mbgl/util/geometry.hpp>

#include <cmath>

namespace mbgl {

using CollisionBoxLayoutAttributes = gl::Attributes<
    attributes::a_pos,
    attributes::a_anchor_pos,
    attributes::a_extrude>;

struct CollisionBoxOpacityAttributes : gl::Attributes<attributes::a_placed> {
    static Vertex vertex(bool placed, bool notUsed) {
        return Vertex {
            {{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed)  }}
        };
    }
};

class CollisionBoxProgram : public Program<
    shaders::collision_box,
    gl::Line,
    gl::ConcatenateAttributes<CollisionBoxLayoutAttributes, CollisionBoxOpacityAttributes>,
    gl::Uniforms<
        uniforms::u_matrix,
        uniforms::u_extrude_scale,
        uniforms::u_camera_to_center_distance>,
    style::Properties<>>
{
public:
    using Program::Program;

    static CollisionBoxLayoutAttributes::Vertex vertex(Point<float> a, Point<float> anchor, Point<float> o) {
        return CollisionBoxLayoutAttributes::Vertex {
            {{
                static_cast<int16_t>(a.x),
                static_cast<int16_t>(a.y)
            }},
            {{
                static_cast<int16_t>(anchor.x),
                static_cast<int16_t>(anchor.y)
            }},
            {{
                static_cast<int16_t>(::round(o.x)),
                static_cast<int16_t>(::round(o.y))
            }}
        };
    }

	template <class DrawMode>
		void 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<CollisionBoxOpacityAttributes::Vertex>& opacityVertexBuffer,
				const gl::IndexBuffer<DrawMode>& indexBuffer,
				const SegmentVector<Attributes>& segments,
				const PaintPropertyBinders& paintPropertyBinders,
				const typename PaintProperties::PossiblyEvaluated& currentProperties,
				float currentZoom,
				const std::string& layerID) {
			typename AllUniforms::Values allUniformValues = uniformValues
				.concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties));

			typename Attributes::Bindings allAttributeBindings = CollisionBoxLayoutAttributes::bindings(layoutVertexBuffer)
                .concat(CollisionBoxOpacityAttributes::bindings(opacityVertexBuffer))
				.concat(paintPropertyBinders.attributeBindings(currentProperties));

			for (auto& segment : segments) {
				auto vertexArrayIt = segment.vertexArrays.find(layerID);

				if (vertexArrayIt == segment.vertexArrays.end()) {
					vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first;
				}

				program.draw(
						context,
						std::move(drawMode),
						std::move(depthMode),
						std::move(stencilMode),
						std::move(colorMode),
						allUniformValues,
						vertexArrayIt->second,
						Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset),
						indexBuffer,
						segment.indexOffset,
						segment.indexLength);
			}
		}

};

using CollisionBoxVertex = CollisionBoxProgram::LayoutVertex;

} // namespace mbgl