Files
MapLibreParticleLab/src/mbgl/gl/program.hpp
John Firebaugh 1db2ffbc1b [core] Use gl::Program to resolve some rough edges in the GL binding types
* Extract `ignore` util to separate header.
* `Segment` now tracks offset and length of indices, rather than primitives. This is more natural.
* Introduce `VertexVector` and `IndexVector` types. These types carry information about the intended draw mode (`Triangles`, `LineStrip`, etc.), and ensure that elements are always appended in a group size appropriate for that draw mode, for both indexed and unindexed rendering.
* `Program`, rather than `Drawable`, is now the unifying object for draw calls. `Program` is the best place to type check the draw call, because it is typed to carry information about the intended primitive, vertex type, attributes, and uniforms.
* Use the debug shaders for debug tile rendering, like gl-js.
* Fix the draw mode for background. It was drawing triangle strips with a triangles array. Surprised this didn’t cause issues. Now it’s type checked.
2016-11-08 08:09:29 -08:00

96 lines
3.1 KiB
C++

#pragma once
#include <mbgl/gl/types.hpp>
#include <mbgl/gl/object.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/vertex_buffer.hpp>
#include <mbgl/gl/index_buffer.hpp>
#include <mbgl/gl/attribute.hpp>
#include <mbgl/gl/uniform.hpp>
#include <string>
namespace mbgl {
namespace gl {
template <class P, class As, class Us>
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<Vertex>::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(Uniforms::state(program)) {}
// Indexed drawing.
template <class DrawMode>
void draw(Context& context,
DrawMode drawMode,
DepthMode depthMode,
StencilMode stencilMode,
ColorMode colorMode,
UniformValues&& uniformValues,
const VertexBuffer<Vertex>& vertexBuffer,
const IndexBuffer<DrawMode>& indexBuffer,
const std::vector<Segment>& segments) {
static_assert(std::is_same<Primitive, typename DrawMode::Primitive>::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)
});
}
// Unindexed drawing.
template <class DrawMode>
void draw(Context& context,
DrawMode drawMode,
DepthMode depthMode,
StencilMode stencilMode,
ColorMode colorMode,
UniformValues&& uniformValues,
const VertexBuffer<Vertex, DrawMode>& vertexBuffer) {
static_assert(std::is_same<Primitive, typename DrawMode::Primitive>::value, "incompatible draw mode");
context.draw({
std::move(drawMode),
std::move(depthMode),
std::move(stencilMode),
std::move(colorMode),
program,
vertexBuffer.buffer,
0,
{{ 0, 0, vertexBuffer.vertexCount, 0 }},
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