#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #if !MLN_RENDER_BACKEND_METAL #include #endif namespace mbgl { namespace gfx { class RenderPass; } // namespace gfx template class Program : public gfx::Shader { public: using LayoutVertex = gfx::Vertex; using PaintProperties = PaintProps; using Binders = PaintPropertyBinders; using PaintAttributeList = typename Binders::AttributeList; using AttributeList = TypeListConcat; using AttributeBindings = gfx::AttributeBindings; using PaintUniformList = typename Binders::UniformList; using UniformList = TypeListConcat; using LayoutUniformValues = gfx::UniformValues; using UniformValues = gfx::UniformValues; using TextureList = Textures; using TextureBindings = gfx::TextureBindings; std::unique_ptr> program; Program(const ProgramParameters& programParameters) { switch (gfx::Backend::GetType()) { #if MLN_RENDER_BACKEND_METAL case gfx::Backend::Type::Metal: { break; } #else // MLN_RENDER_BACKEND_OPENGL case gfx::Backend::Type::OpenGL: { program = std::make_unique>(programParameters.withDefaultSource( {gfx::Backend::Type::OpenGL, shaders::ShaderSource::vertex, shaders::ShaderSource::fragment})); break; } #endif default: { throw std::runtime_error("Unsupported rendering backend!"); } } } 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& layoutVertexBuffer, const Binders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties) { return gfx::AttributeBindings(layoutVertexBuffer) .concat(paintPropertyBinders.attributeBindings(currentProperties)); } static uint32_t activeBindingCount(const AttributeBindings& allAttributeBindings) { return allAttributeBindings.activeCount(); } template 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& segment, const UniformValues& uniformValues, const AttributeBindings& allAttributeBindings, const TextureBindings& textureBindings, const std::string& layerID) { static_assert(Primitive == gfx::PrimitiveTypeOf::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 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& segments, const UniformValues& uniformValues, const AttributeBindings& allAttributeBindings, const TextureBindings& textureBindings, const std::string& layerID) { static_assert(Primitive == gfx::PrimitiveTypeOf::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