#pragma once #include #include #include #include #include #include #include #include #include namespace mbgl { template class Program { public: using LayoutAttributes = LayoutAttrs; using LayoutVertex = typename LayoutAttributes::Vertex; using PaintProperties = PaintProps; using PaintPropertyBinders = typename PaintProperties::Binders; using PaintAttributes = typename PaintPropertyBinders::Attributes; using Attributes = gl::ConcatenateAttributes; using UniformValues = typename Uniforms::Values; using PaintUniforms = typename PaintPropertyBinders::Uniforms; using AllUniforms = gl::ConcatenateUniforms; using ProgramType = gl::Program; ProgramType program; Program(gl::Context& context, const ProgramParameters& programParameters) : program(ProgramType::createProgram( context, programParameters, Shaders::name, Shaders::vertexSource, Shaders::fragmentSource)) { } template void draw(gl::Context& context, DrawMode drawMode, gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, UniformValues&& uniformValues, const gl::VertexBuffer& layoutVertexBuffer, const gl::IndexBuffer& indexBuffer, const gl::SegmentVector& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, float currentZoom) { program.draw( context, std::move(drawMode), std::move(depthMode), std::move(stencilMode), std::move(colorMode), uniformValues .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), LayoutAttributes::bindings(layoutVertexBuffer) .concat(paintPropertyBinders.attributeBindings(currentProperties)), indexBuffer, segments ); } }; template class ProgramMap { public: using PaintProperties = typename Program::PaintProperties; using PaintPropertyBinders = typename Program::PaintPropertyBinders; using Bitset = typename PaintPropertyBinders::Bitset; ProgramMap(gl::Context& context_, ProgramParameters parameters_) : context(context_), parameters(std::move(parameters_)) { } Program& get(const typename PaintProperties::PossiblyEvaluated& currentProperties) { Bitset bits = PaintPropertyBinders::constants(currentProperties); auto it = programs.find(bits); if (it != programs.end()) { return it->second; } return programs.emplace(std::piecewise_construct, std::forward_as_tuple(bits), std::forward_as_tuple(context, parameters.withAdditionalDefines(PaintPropertyBinders::defines(currentProperties)))).first->second; } private: gl::Context& context; ProgramParameters parameters; std::unordered_map programs; }; } // namespace mbgl