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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#pragma once
#include <mbgl/gfx/attribute.hpp>
#include <mbgl/gfx/uniform.hpp>
#include <mbgl/gfx/draw_mode.hpp>
#include <mbgl/programs/segment.hpp>
#include <mbgl/programs/attributes.hpp>
#include <mbgl/programs/program_parameters.hpp>
#include <mbgl/style/paint_property.hpp>
#include <mbgl/renderer/paint_property_binder.hpp>
#include <mbgl/util/io.hpp>
#include <unordered_map>
namespace mbgl {
namespace gfx {
class RenderPass;
} // namespace gfx
template <class Name,
gfx::PrimitiveType Primitive,
class LayoutAttributeList,
class LayoutUniformList,
class Textures,
class PaintProps>
class Program {
public:
using LayoutVertex = gfx::Vertex<LayoutAttributeList>;
using PaintProperties = PaintProps;
using Binders = PaintPropertyBinders<typename PaintProperties::DataDrivenProperties>;
using PaintAttributeList = typename Binders::AttributeList;
using AttributeList = TypeListConcat<LayoutAttributeList, PaintAttributeList>;
using AttributeBindings = gfx::AttributeBindings<AttributeList>;
using PaintUniformList = typename Binders::UniformList;
using UniformList = TypeListConcat<LayoutUniformList, PaintUniformList>;
using LayoutUniformValues = gfx::UniformValues<LayoutUniformList>;
using UniformValues = gfx::UniformValues<UniformList>;
using TextureList = Textures;
using TextureBindings = gfx::TextureBindings<TextureList>;
std::unique_ptr<gfx::Program<Name>> program;
Program(gfx::Context& context, const ProgramParameters& programParameters)
: program(context.createProgram<Name>(programParameters)) {
}
static UniformValues computeAllUniformValues(
const LayoutUniformValues& layoutUniformValues,
const Binders& paintPropertyBinders,
const typename PaintProperties::PossiblyEvaluated& currentProperties,
float currentZoom) {
return layoutUniformValues
.concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties));
}
static AttributeBindings computeAllAttributeBindings(
const gfx::VertexBuffer<LayoutVertex>& layoutVertexBuffer,
const Binders& paintPropertyBinders,
const typename PaintProperties::PossiblyEvaluated& currentProperties) {
return gfx::AttributeBindings<LayoutAttributeList>(layoutVertexBuffer)
.concat(paintPropertyBinders.attributeBindings(currentProperties));
}
static uint32_t activeBindingCount(const AttributeBindings& allAttributeBindings) {
return allAttributeBindings.activeCount();
}
template <class DrawMode>
void draw(gfx::Context& context,
gfx::RenderPass& renderPass,
const DrawMode& drawMode,
const gfx::DepthMode& depthMode,
const gfx::StencilMode& stencilMode,
const gfx::ColorMode& colorMode,
const gfx::CullFaceMode& cullFaceMode,
const gfx::IndexBuffer& indexBuffer,
const SegmentVector<AttributeList>& segments,
const UniformValues& uniformValues,
const AttributeBindings& allAttributeBindings,
const TextureBindings& textureBindings,
const std::string& layerID) {
static_assert(Primitive == gfx::PrimitiveTypeOf<DrawMode>::value, "incompatible draw mode");
if (!program) {
return;
}
for (auto& segment : segments) {
auto drawScopeIt = segment.drawScopes.find(layerID);
if (drawScopeIt == segment.drawScopes.end()) {
drawScopeIt = segment.drawScopes.emplace(layerID, context.createDrawScope()).first;
}
program->draw(
context,
renderPass,
drawMode,
depthMode,
stencilMode,
colorMode,
cullFaceMode,
uniformValues,
drawScopeIt->second,
allAttributeBindings.offset(segment.vertexOffset),
textureBindings,
indexBuffer,
segment.indexOffset,
segment.indexLength);
}
}
};
class LayerTypePrograms {
public:
virtual ~LayerTypePrograms() = default;
};
} // namespace mbgl
|