171 lines
7.6 KiB
C++
171 lines
7.6 KiB
C++
#pragma once
|
|
|
|
#include <mbgl/programs/program.hpp>
|
|
#include <mbgl/programs/attributes.hpp>
|
|
#include <mbgl/programs/uniforms.hpp>
|
|
#include <mbgl/style/properties.hpp>
|
|
#include <mbgl/util/geometry.hpp>
|
|
|
|
#include <cmath>
|
|
|
|
namespace mbgl {
|
|
|
|
using CollisionBoxLayoutAttributes = TypeList<attributes::pos, attributes::anchor_pos, attributes::extrude>;
|
|
|
|
using CollisionBoxDynamicAttributes = TypeList<attributes::placed, attributes::shift>;
|
|
|
|
class CollisionBoxProgram final
|
|
: public Program<CollisionBoxProgram,
|
|
shaders::BuiltIn::CollisionBoxProgram,
|
|
gfx::PrimitiveType::Line,
|
|
TypeListConcat<CollisionBoxLayoutAttributes, CollisionBoxDynamicAttributes>,
|
|
TypeList<uniforms::matrix, uniforms::extrude_scale, uniforms::camera_to_center_distance>,
|
|
TypeList<>,
|
|
style::Properties<>> {
|
|
public:
|
|
static constexpr std::string_view Name{"CollisionBoxProgram"};
|
|
const std::string_view typeName() const noexcept override { return Name; }
|
|
|
|
using Program::Program;
|
|
|
|
static gfx::Vertex<CollisionBoxLayoutAttributes> layoutVertex(Point<float> a, Point<float> anchor, Point<float> o) {
|
|
return {{{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))}}};
|
|
}
|
|
|
|
static gfx::Vertex<CollisionBoxDynamicAttributes> dynamicVertex(bool placed, bool notUsed, Point<float> shift) {
|
|
return {{{static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed)}}, {{shift.x, shift.y}}};
|
|
}
|
|
|
|
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 LayoutUniformValues& layoutUniformValues,
|
|
const gfx::VertexBuffer<gfx::Vertex<CollisionBoxLayoutAttributes>>& layoutVertexBuffer,
|
|
const gfx::VertexBuffer<gfx::Vertex<CollisionBoxDynamicAttributes>>& dynamicVertexBuffer,
|
|
const gfx::IndexBuffer& indexBuffer,
|
|
const SegmentVector<AttributeList>& segments,
|
|
const Binders& paintPropertyBinders,
|
|
const typename PaintProperties::PossiblyEvaluated& currentProperties,
|
|
const TextureBindings& textureBindings,
|
|
float currentZoom,
|
|
const std::string& layerID) {
|
|
UniformValues uniformValues = layoutUniformValues.concat(
|
|
paintPropertyBinders.uniformValues(currentZoom, currentProperties));
|
|
|
|
AttributeBindings allAttributeBindings =
|
|
gfx::AttributeBindings<CollisionBoxLayoutAttributes>(layoutVertexBuffer)
|
|
.concat(gfx::AttributeBindings<CollisionBoxDynamicAttributes>(dynamicVertexBuffer))
|
|
.concat(paintPropertyBinders.attributeBindings(currentProperties));
|
|
|
|
assert(layoutVertexBuffer.elements == dynamicVertexBuffer.elements);
|
|
|
|
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 CollisionCircleProgram final
|
|
: public Program<CollisionCircleProgram,
|
|
shaders::BuiltIn::CollisionCircleProgram,
|
|
gfx::PrimitiveType::Triangle,
|
|
TypeListConcat<CollisionBoxLayoutAttributes, CollisionBoxDynamicAttributes>,
|
|
TypeList<uniforms::matrix,
|
|
uniforms::extrude_scale,
|
|
uniforms::overscale_factor,
|
|
uniforms::camera_to_center_distance>,
|
|
TypeList<>,
|
|
style::Properties<>> {
|
|
public:
|
|
static constexpr std::string_view Name{"CollisionCircleProgram"};
|
|
const std::string_view typeName() const noexcept override { return Name; }
|
|
|
|
using Program::Program;
|
|
|
|
static gfx::Vertex<CollisionBoxLayoutAttributes> vertex(Point<float> a, Point<float> anchor, Point<float> o) {
|
|
return {{{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(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 LayoutUniformValues& layoutUniformValues,
|
|
const gfx::VertexBuffer<gfx::Vertex<CollisionBoxLayoutAttributes>>& layoutVertexBuffer,
|
|
const gfx::VertexBuffer<gfx::Vertex<CollisionBoxDynamicAttributes>>& dynamicVertexBuffer,
|
|
const gfx::IndexBuffer& indexBuffer,
|
|
const SegmentVector<AttributeList>& segments,
|
|
const Binders& paintPropertyBinders,
|
|
const typename PaintProperties::PossiblyEvaluated& currentProperties,
|
|
const TextureBindings& textureBindings,
|
|
float currentZoom,
|
|
const std::string& layerID) {
|
|
UniformValues uniformValues = layoutUniformValues.concat(
|
|
paintPropertyBinders.uniformValues(currentZoom, currentProperties));
|
|
|
|
AttributeBindings allAttributeBindings =
|
|
gfx::AttributeBindings<CollisionBoxLayoutAttributes>(layoutVertexBuffer)
|
|
.concat(gfx::AttributeBindings<CollisionBoxDynamicAttributes>(dynamicVertexBuffer))
|
|
.concat(paintPropertyBinders.attributeBindings(currentProperties));
|
|
|
|
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);
|
|
}
|
|
}
|
|
};
|
|
|
|
using CollisionBoxVertex = CollisionBoxProgram::LayoutVertex;
|
|
|
|
} // namespace mbgl
|