166 lines
5.8 KiB
C++
166 lines
5.8 KiB
C++
#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 Segment<AttributeList>& segment,
|
|
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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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
|