#pragma once #include #include #include #include #include #include #include #include namespace mbgl { namespace gl { template class Program { public: using Primitive = P; using Attributes = As; using Uniforms = Us; using Vertex = typename Attributes::Vertex; using UniformValues = typename Uniforms::Values; static_assert(std::is_standard_layout::value, "vertex type must use standard layout"); Program(Context& context, const std::string& vertexSource, const std::string& fragmentSource) : vertexShader(context.createShader(ShaderType::Vertex, vertexSource)), fragmentShader(context.createShader(ShaderType::Fragment, fragmentSource)), program(context.createProgram(vertexShader, fragmentShader)), attributesState(Attributes::state(program)), uniformsState((context.linkProgram(program), Uniforms::state(program))) {} template void draw(Context& context, DrawMode drawMode, DepthMode depthMode, StencilMode stencilMode, ColorMode colorMode, UniformValues&& uniformValues, const VertexBuffer& vertexBuffer, const IndexBuffer& indexBuffer, const SegmentVector& segments) { static_assert(std::is_same::value, "incompatible draw mode"); context.draw({ std::move(drawMode), std::move(depthMode), std::move(stencilMode), std::move(colorMode), program, vertexBuffer.buffer, indexBuffer.buffer, segments, Uniforms::binder(uniformsState, std::move(uniformValues)), Attributes::binder(attributesState) }); } private: UniqueShader vertexShader; UniqueShader fragmentShader; UniqueProgram program; typename Attributes::State attributesState; typename Uniforms::State uniformsState; }; } // namespace gl } // namespace mbgl