[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.
This commit is contained in:
@@ -65,7 +65,6 @@ set(MBGL_CORE_FILES
|
||||
src/mbgl/gl/depth_mode.cpp
|
||||
src/mbgl/gl/depth_mode.hpp
|
||||
src/mbgl/gl/draw_mode.hpp
|
||||
src/mbgl/gl/drawable.hpp
|
||||
src/mbgl/gl/extension.cpp
|
||||
src/mbgl/gl/extension.hpp
|
||||
src/mbgl/gl/framebuffer.hpp
|
||||
@@ -73,6 +72,7 @@ set(MBGL_CORE_FILES
|
||||
src/mbgl/gl/index_buffer.hpp
|
||||
src/mbgl/gl/object.cpp
|
||||
src/mbgl/gl/object.hpp
|
||||
src/mbgl/gl/primitives.hpp
|
||||
src/mbgl/gl/program.hpp
|
||||
src/mbgl/gl/renderbuffer.hpp
|
||||
src/mbgl/gl/segment.hpp
|
||||
@@ -154,6 +154,7 @@ set(MBGL_CORE_FILES
|
||||
src/mbgl/programs/circle_program.hpp
|
||||
src/mbgl/programs/collision_box_program.cpp
|
||||
src/mbgl/programs/collision_box_program.hpp
|
||||
src/mbgl/programs/debug_program.hpp
|
||||
src/mbgl/programs/fill_program.cpp
|
||||
src/mbgl/programs/fill_program.hpp
|
||||
src/mbgl/programs/line_program.cpp
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -157,17 +158,14 @@ private:
|
||||
template <std::size_t... Is>
|
||||
static std::function<void (std::size_t)> binder(const State& state, std::index_sequence<Is...>) {
|
||||
return [&state] (std::size_t vertexOffset) {
|
||||
noop((bindAttribute(std::get<Is>(state).location,
|
||||
std::get<Is>(state).count,
|
||||
std::get<Is>(state).type,
|
||||
sizeof(Vertex),
|
||||
vertexOffset,
|
||||
Vertex::attributeOffsets[Is]), 0)...);
|
||||
ignore((bindAttribute(std::get<Is>(state).location,
|
||||
std::get<Is>(state).count,
|
||||
std::get<Is>(state).type,
|
||||
sizeof(Vertex),
|
||||
vertexOffset,
|
||||
Vertex::attributeOffsets[Is]), 0)...);
|
||||
};
|
||||
}
|
||||
|
||||
// This exists only to provide a varags context for unpacking the assignments in `binder`.
|
||||
template <int...> static void noop(int...) {}
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -533,9 +533,9 @@ void Context::draw(const Drawable& drawable) {
|
||||
if (drawable.indexBuffer) {
|
||||
MBGL_CHECK_ERROR(glDrawElements(
|
||||
static_cast<GLenum>(primitiveType),
|
||||
static_cast<GLsizei>(drawable.primitiveSize / sizeof(uint16_t) * segment.primitiveLength),
|
||||
static_cast<GLsizei>(segment.indexLength),
|
||||
GL_UNSIGNED_SHORT,
|
||||
reinterpret_cast<GLvoid*>(drawable.primitiveSize * segment.primitiveOffset)));
|
||||
reinterpret_cast<GLvoid*>(sizeof(uint16_t) * segment.indexOffset)));
|
||||
} else {
|
||||
MBGL_CHECK_ERROR(glDrawArrays(
|
||||
static_cast<GLenum>(primitiveType),
|
||||
|
||||
@@ -8,9 +8,16 @@
|
||||
#include <mbgl/gl/framebuffer.hpp>
|
||||
#include <mbgl/gl/vertex_buffer.hpp>
|
||||
#include <mbgl/gl/index_buffer.hpp>
|
||||
#include <mbgl/gl/drawable.hpp>
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/gl/draw_mode.hpp>
|
||||
#include <mbgl/gl/depth_mode.hpp>
|
||||
#include <mbgl/gl/stencil_mode.hpp>
|
||||
#include <mbgl/gl/color_mode.hpp>
|
||||
#include <mbgl/gl/segment.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
@@ -33,18 +40,18 @@ public:
|
||||
UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader);
|
||||
UniqueTexture createTexture();
|
||||
|
||||
template <class V>
|
||||
VertexBuffer<V> createVertexBuffer(std::vector<V>&& v) {
|
||||
return VertexBuffer<V> {
|
||||
v.size(),
|
||||
createVertexBuffer(v.data(), v.size() * sizeof(V))
|
||||
template <class Vertex, class DrawMode>
|
||||
VertexBuffer<Vertex, DrawMode> createVertexBuffer(VertexVector<Vertex, DrawMode>&& v) {
|
||||
return VertexBuffer<Vertex, DrawMode> {
|
||||
v.vertexSize(),
|
||||
createVertexBuffer(v.data(), v.byteSize())
|
||||
};
|
||||
}
|
||||
|
||||
template <class P>
|
||||
IndexBuffer<P> createIndexBuffer(std::vector<P>&& v) {
|
||||
return IndexBuffer<P> {
|
||||
createIndexBuffer(v.data(), v.size() * sizeof(P))
|
||||
template <class DrawMode>
|
||||
IndexBuffer<DrawMode> createIndexBuffer(IndexVector<DrawMode>&& v) {
|
||||
return IndexBuffer<DrawMode> {
|
||||
createIndexBuffer(v.data(), v.byteSize())
|
||||
};
|
||||
}
|
||||
|
||||
@@ -111,6 +118,19 @@ public:
|
||||
optional<float> depth,
|
||||
optional<int32_t> stencil);
|
||||
|
||||
struct Drawable {
|
||||
DrawMode drawMode;
|
||||
DepthMode depthMode;
|
||||
StencilMode stencilMode;
|
||||
ColorMode colorMode;
|
||||
gl::ProgramID program;
|
||||
gl::BufferID vertexBuffer;
|
||||
gl::BufferID indexBuffer;
|
||||
const std::vector<Segment>& segments;
|
||||
std::function<void ()> bindUniforms;
|
||||
std::function<void (std::size_t)> bindAttributes;
|
||||
};
|
||||
|
||||
void draw(const Drawable&);
|
||||
|
||||
void setDepthMode(const DepthMode&);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/primitives.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -7,21 +8,50 @@ namespace gl {
|
||||
|
||||
class Points {
|
||||
public:
|
||||
using Primitive = Point;
|
||||
static constexpr std::size_t bufferGroupSize = 1;
|
||||
|
||||
float pointSize;
|
||||
};
|
||||
|
||||
class Lines {
|
||||
public:
|
||||
using Primitive = Line;
|
||||
static constexpr std::size_t bufferGroupSize = 2;
|
||||
|
||||
float lineWidth;
|
||||
};
|
||||
|
||||
class LineStrip {
|
||||
public:
|
||||
// LineStrip is a form of "Line" rendering, but the element buffer
|
||||
// cannot be grouped into logical elements beyond a single Point.
|
||||
using Primitive = Line;
|
||||
static constexpr std::size_t bufferGroupSize = 1;
|
||||
|
||||
float lineWidth;
|
||||
};
|
||||
|
||||
class Triangles {};
|
||||
class TriangleStrip {};
|
||||
class Triangles {
|
||||
public:
|
||||
using Primitive = Triangle;
|
||||
static constexpr std::size_t bufferGroupSize = 3;
|
||||
};
|
||||
|
||||
class TriangleStrip {
|
||||
public:
|
||||
// TriangleStrip is a form of "Triangle" rendering, but the element buffer
|
||||
// cannot be grouped into logical elements beyond a single Point.
|
||||
using Primitive = Triangle;
|
||||
static constexpr std::size_t bufferGroupSize = 1;
|
||||
};
|
||||
|
||||
// Special draw mode for use with VertexVector<Indexed, Vertex>, in which
|
||||
// case the true draw mode is denoted by the IndexVector type.
|
||||
class Indexed {
|
||||
public:
|
||||
static constexpr std::size_t bufferGroupSize = 1;
|
||||
};
|
||||
|
||||
using DrawMode = variant<
|
||||
Points,
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/gl/draw_mode.hpp>
|
||||
#include <mbgl/gl/depth_mode.hpp>
|
||||
#include <mbgl/gl/stencil_mode.hpp>
|
||||
#include <mbgl/gl/color_mode.hpp>
|
||||
#include <mbgl/gl/vertex_buffer.hpp>
|
||||
#include <mbgl/gl/index_buffer.hpp>
|
||||
#include <mbgl/gl/attribute.hpp>
|
||||
#include <mbgl/gl/uniform.hpp>
|
||||
#include <mbgl/gl/segment.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
template <class Vertex>
|
||||
class UnindexedVertices {
|
||||
public:
|
||||
using VertexType = Vertex;
|
||||
|
||||
UnindexedVertices(DrawMode drawMode_, const VertexBuffer<Vertex>& vertexBuffer_)
|
||||
: drawMode(std::move(drawMode_)),
|
||||
vertexBuffer(vertexBuffer_.buffer),
|
||||
segments({{ 0, 0, vertexBuffer_.vertexCount, 0 }}) {}
|
||||
|
||||
DrawMode drawMode;
|
||||
gl::BufferID vertexBuffer;
|
||||
static constexpr std::size_t vertexSize = sizeof(Vertex);
|
||||
static constexpr gl::BufferID indexBuffer = 0;
|
||||
static constexpr std::size_t primitiveSize = 0;
|
||||
std::vector<Segment> segments;
|
||||
};
|
||||
|
||||
template <class DrawMode, class Vertex, class...Args>
|
||||
auto Unindexed(const VertexBuffer<Vertex>& vertexBuffer,
|
||||
Args&&... drawModeArguments) {
|
||||
return UnindexedVertices<Vertex>(
|
||||
DrawMode { std::forward<Args>(drawModeArguments)... },
|
||||
vertexBuffer);
|
||||
}
|
||||
|
||||
template <class Vertex, class Primitive>
|
||||
class SegmentedVertices {
|
||||
public:
|
||||
using VertexType = Vertex;
|
||||
|
||||
SegmentedVertices(DrawMode drawMode_,
|
||||
const VertexBuffer<Vertex>& vertexBuffer_,
|
||||
const IndexBuffer<Primitive>& indexBuffer_,
|
||||
const std::vector<Segment>& segments_)
|
||||
: drawMode(std::move(drawMode_)),
|
||||
vertexBuffer(vertexBuffer_.buffer),
|
||||
indexBuffer(indexBuffer_.buffer),
|
||||
segments(segments_) {}
|
||||
|
||||
DrawMode drawMode;
|
||||
gl::BufferID vertexBuffer;
|
||||
static constexpr std::size_t vertexSize = sizeof(Vertex);
|
||||
gl::BufferID indexBuffer;
|
||||
static constexpr std::size_t primitiveSize = sizeof(Primitive);
|
||||
const std::vector<Segment>& segments;
|
||||
};
|
||||
|
||||
template <class DrawMode, class Vertex, class Primitive, class...Args>
|
||||
auto Segmented(const VertexBuffer<Vertex>& vertexBuffer,
|
||||
const IndexBuffer<Primitive>& indexBuffer,
|
||||
const std::vector<Segment>& segments,
|
||||
Args&&... drawModeArguments) {
|
||||
static_assert(std::is_same<typename Primitive::DrawMode, DrawMode>::value, "primitive mode mismatch");
|
||||
return SegmentedVertices<Vertex, Primitive>(
|
||||
DrawMode { std::forward<Args>(drawModeArguments)... },
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
segments);
|
||||
}
|
||||
|
||||
class Drawable {
|
||||
public:
|
||||
template <class Program, class Subject>
|
||||
Drawable(DepthMode depthMode_,
|
||||
StencilMode stencilMode_,
|
||||
ColorMode colorMode_,
|
||||
Program& program_,
|
||||
typename Program::UniformValues&& uniformValues,
|
||||
const Subject& subject)
|
||||
: drawMode(subject.drawMode),
|
||||
depthMode(std::move(depthMode_)),
|
||||
stencilMode(std::move(stencilMode_)),
|
||||
colorMode(std::move(colorMode_)),
|
||||
program(program_.program),
|
||||
vertexBuffer(subject.vertexBuffer),
|
||||
vertexSize(subject.vertexSize),
|
||||
indexBuffer(subject.indexBuffer),
|
||||
primitiveSize(subject.primitiveSize),
|
||||
segments(subject.segments),
|
||||
bindUniforms(Program::Uniforms::binder(program_.uniformsState, std::move(uniformValues))),
|
||||
bindAttributes(Program::Attributes::binder(program_.attributesState))
|
||||
{
|
||||
static_assert(std::is_standard_layout<typename Program::Vertex>::value, "vertex type must use standard layout");
|
||||
static_assert(std::is_same<typename Program::Vertex, typename Subject::VertexType>::value, "vertex type mismatch");
|
||||
}
|
||||
|
||||
DrawMode drawMode;
|
||||
DepthMode depthMode;
|
||||
StencilMode stencilMode;
|
||||
ColorMode colorMode;
|
||||
gl::ProgramID program;
|
||||
gl::BufferID vertexBuffer;
|
||||
std::size_t vertexSize;
|
||||
gl::BufferID indexBuffer;
|
||||
std::size_t primitiveSize;
|
||||
const std::vector<Segment>& segments;
|
||||
std::function<void ()> bindUniforms;
|
||||
std::function<void (std::size_t)> bindAttributes;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -2,39 +2,37 @@
|
||||
|
||||
#include <mbgl/gl/object.hpp>
|
||||
#include <mbgl/gl/draw_mode.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class Line {
|
||||
template <class DrawMode>
|
||||
class IndexVector {
|
||||
public:
|
||||
using DrawMode = Lines;
|
||||
static constexpr std::size_t groupSize = DrawMode::bufferGroupSize;
|
||||
|
||||
Line(uint16_t a_, uint16_t b_)
|
||||
: a(a_), b(b_) {}
|
||||
template <class... Args>
|
||||
void emplace_back(Args&&... args) {
|
||||
static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
|
||||
ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
|
||||
}
|
||||
|
||||
uint16_t a;
|
||||
uint16_t b;
|
||||
std::size_t indexSize() const { return v.size(); }
|
||||
std::size_t byteSize() const { return v.size() * sizeof(uint16_t); }
|
||||
|
||||
bool empty() const { return v.empty(); }
|
||||
const uint16_t* data() const { return v.data(); }
|
||||
|
||||
private:
|
||||
std::vector<uint16_t> v;
|
||||
};
|
||||
|
||||
class Triangle {
|
||||
public:
|
||||
using DrawMode = Triangles;
|
||||
|
||||
Triangle(uint16_t a_, uint16_t b_, uint16_t c_)
|
||||
: a(a_), b(b_), c(c_) {}
|
||||
|
||||
uint16_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
};
|
||||
|
||||
template <class Primitive>
|
||||
template <class DrawMode>
|
||||
class IndexBuffer {
|
||||
public:
|
||||
static_assert(std::is_same<Primitive, Line>::value || std::is_same<Primitive, Triangle>::value,
|
||||
"primitive must be Line or Triangle");
|
||||
static constexpr std::size_t primitiveSize = sizeof(Primitive);
|
||||
UniqueBuffer buffer;
|
||||
};
|
||||
|
||||
|
||||
22
src/mbgl/gl/primitives.hpp
Normal file
22
src/mbgl/gl/primitives.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class Point {
|
||||
public:
|
||||
static constexpr std::size_t vertexCount = 1;
|
||||
};
|
||||
|
||||
class Line {
|
||||
public:
|
||||
static constexpr std::size_t vertexCount = 2;
|
||||
};
|
||||
|
||||
class Triangle {
|
||||
public:
|
||||
static constexpr std::size_t vertexCount = 3;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -3,21 +3,28 @@
|
||||
#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 As, class Us>
|
||||
template <class P, class As, class Us>
|
||||
class Program {
|
||||
public:
|
||||
using Primitive = P;
|
||||
using Attributes = As;
|
||||
using Vertex = typename Attributes::Vertex;
|
||||
|
||||
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)),
|
||||
@@ -25,6 +32,57 @@ public:
|
||||
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;
|
||||
|
||||
@@ -8,19 +8,19 @@ namespace gl {
|
||||
class Segment {
|
||||
public:
|
||||
Segment(std::size_t vertexOffset_,
|
||||
std::size_t primitiveOffset_,
|
||||
std::size_t indexOffset_,
|
||||
std::size_t vertexLength_ = 0,
|
||||
std::size_t primitiveLength_ = 0)
|
||||
std::size_t indexLength_ = 0)
|
||||
: vertexOffset(vertexOffset_),
|
||||
primitiveOffset(primitiveOffset_),
|
||||
indexOffset(indexOffset_),
|
||||
vertexLength(vertexLength_),
|
||||
primitiveLength(primitiveLength_) {}
|
||||
indexLength(indexLength_) {}
|
||||
|
||||
const std::size_t vertexOffset;
|
||||
const std::size_t primitiveOffset;
|
||||
const std::size_t indexOffset;
|
||||
|
||||
std::size_t vertexLength;
|
||||
std::size_t primitiveLength;
|
||||
std::size_t indexLength;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
@@ -71,13 +72,9 @@ public:
|
||||
|
||||
static std::function<void ()> binder(State& state, Values&& values_) {
|
||||
return [&state, values = std::move(values_)] () mutable {
|
||||
noop((std::get<typename Us::State>(state) = std::get<typename Us::Value>(values), 0)...);
|
||||
ignore((std::get<typename Us::State>(state) = std::get<typename Us::Value>(values), 0)...);
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
// This exists only to provide a varags context for unpacking the assignments in `binder`.
|
||||
template <int...> static void noop(int...) {}
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -1,14 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/object.hpp>
|
||||
#include <mbgl/gl/primitives.hpp>
|
||||
#include <mbgl/gl/draw_mode.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
template <class Vertex>
|
||||
template <class V, class DrawMode = Indexed>
|
||||
class VertexVector {
|
||||
public:
|
||||
using Vertex = V;
|
||||
static constexpr std::size_t groupSize = DrawMode::bufferGroupSize;
|
||||
|
||||
template <class... Args>
|
||||
void emplace_back(Args&&... args) {
|
||||
static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
|
||||
ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
|
||||
}
|
||||
|
||||
std::size_t vertexSize() const { return v.size(); }
|
||||
std::size_t byteSize() const { return v.size() * sizeof(Vertex); }
|
||||
|
||||
bool empty() const { return v.empty(); }
|
||||
const Vertex* data() const { return v.data(); }
|
||||
|
||||
private:
|
||||
std::vector<Vertex> v;
|
||||
};
|
||||
|
||||
template <class V, class DrawMode = Indexed>
|
||||
class VertexBuffer {
|
||||
public:
|
||||
using Vertex = V;
|
||||
static constexpr std::size_t vertexSize = sizeof(Vertex);
|
||||
|
||||
std::size_t vertexCount;
|
||||
UniqueBuffer buffer;
|
||||
};
|
||||
|
||||
@@ -449,7 +449,7 @@ void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
|
||||
}
|
||||
|
||||
if (buffer.segments.empty() || buffer.segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
|
||||
buffer.segments.emplace_back(buffer.vertices.size(), buffer.triangles.size());
|
||||
buffer.segments.emplace_back(buffer.vertices.vertexSize(), buffer.triangles.indexSize());
|
||||
}
|
||||
|
||||
// We're generating triangle fans, so we always start with the first
|
||||
@@ -476,7 +476,7 @@ void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
|
||||
buffer.triangles.emplace_back(index + 1, index + 2, index + 3);
|
||||
|
||||
segment.vertexLength += vertexLength;
|
||||
segment.primitiveLength += 2;
|
||||
segment.indexLength += 6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,14 +507,14 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket&
|
||||
const float maxZoom = util::clamp(zoom + util::log2(box.maxScale), util::MIN_ZOOM_F, util::MAX_ZOOM_F);
|
||||
const float placementZoom = util::clamp(zoom + util::log2(box.placementScale), util::MIN_ZOOM_F, util::MAX_ZOOM_F);
|
||||
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tl, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tr, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tr, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, br, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, br, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, bl, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, bl, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tl, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tl, maxZoom, placementZoom),
|
||||
CollisionBoxProgram::vertex(anchor, tr, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tr, maxZoom, placementZoom),
|
||||
CollisionBoxProgram::vertex(anchor, br, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, br, maxZoom, placementZoom),
|
||||
CollisionBoxProgram::vertex(anchor, bl, maxZoom, placementZoom));
|
||||
collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, bl, maxZoom, placementZoom),
|
||||
CollisionBoxProgram::vertex(anchor, tl, maxZoom, placementZoom));
|
||||
}
|
||||
};
|
||||
populateCollisionBox(symbolInstance.textCollisionFeature);
|
||||
|
||||
@@ -16,6 +16,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_devicepixelratio);
|
||||
|
||||
class CircleProgram : public Program<
|
||||
shaders::circle,
|
||||
gl::Triangle,
|
||||
gl::Attributes<
|
||||
attributes::a_pos>,
|
||||
gl::Uniforms<
|
||||
|
||||
@@ -17,6 +17,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_maxzoom);
|
||||
|
||||
class CollisionBoxProgram : public Program<
|
||||
shaders::collision_box,
|
||||
gl::Line,
|
||||
gl::Attributes<
|
||||
attributes::a_pos,
|
||||
attributes::a_extrude,
|
||||
|
||||
23
src/mbgl/programs/debug_program.hpp
Normal file
23
src/mbgl/programs/debug_program.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/programs/program.hpp>
|
||||
#include <mbgl/programs/attributes.hpp>
|
||||
#include <mbgl/programs/uniforms.hpp>
|
||||
#include <mbgl/shader/debug.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class DebugProgram : public Program<
|
||||
shaders::debug,
|
||||
gl::Line,
|
||||
gl::Attributes<
|
||||
attributes::a_pos>,
|
||||
gl::Uniforms<
|
||||
uniforms::u_matrix,
|
||||
uniforms::u_color>>
|
||||
{
|
||||
public:
|
||||
using Program::Program;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -86,6 +86,7 @@ struct FillPatternUniforms : gl::Uniforms<
|
||||
|
||||
class FillProgram : public Program<
|
||||
shaders::fill,
|
||||
gl::Triangle,
|
||||
FillAttributes,
|
||||
FillUniforms>
|
||||
{
|
||||
@@ -94,6 +95,7 @@ class FillProgram : public Program<
|
||||
|
||||
class FillPatternProgram : public Program<
|
||||
shaders::fill_pattern,
|
||||
gl::Triangle,
|
||||
FillAttributes,
|
||||
FillPatternUniforms>
|
||||
{
|
||||
@@ -102,6 +104,7 @@ class FillPatternProgram : public Program<
|
||||
|
||||
class FillOutlineProgram : public Program<
|
||||
shaders::fill_outline,
|
||||
gl::Line,
|
||||
FillAttributes,
|
||||
FillUniforms>
|
||||
{
|
||||
@@ -110,6 +113,7 @@ class FillOutlineProgram : public Program<
|
||||
|
||||
class FillOutlinePatternProgram : public Program<
|
||||
shaders::fill_outline_pattern,
|
||||
gl::Line,
|
||||
FillAttributes,
|
||||
FillPatternUniforms>
|
||||
{
|
||||
|
||||
@@ -88,6 +88,7 @@ using LineVertex = LineAttributes::Vertex;
|
||||
|
||||
class LineProgram : public Program<
|
||||
shaders::line,
|
||||
gl::Triangle,
|
||||
LineAttributes,
|
||||
gl::Uniforms<
|
||||
uniforms::u_matrix,
|
||||
@@ -113,6 +114,7 @@ public:
|
||||
|
||||
class LinePatternProgram : public Program<
|
||||
shaders::line_pattern,
|
||||
gl::Triangle,
|
||||
LineAttributes,
|
||||
gl::Uniforms<
|
||||
uniforms::u_matrix,
|
||||
@@ -147,6 +149,7 @@ public:
|
||||
|
||||
class LineSDFProgram : public Program<
|
||||
shaders::line_sdf,
|
||||
gl::Triangle,
|
||||
LineAttributes,
|
||||
gl::Uniforms<
|
||||
uniforms::u_matrix,
|
||||
|
||||
@@ -11,11 +11,13 @@ enum class ProgramDefines : bool {
|
||||
Overdraw = true,
|
||||
};
|
||||
|
||||
template <class Shaders, class As, class Us>
|
||||
class Program : public gl::Program<As, Us> {
|
||||
template <class Shaders, class Primitive, class Attributes, class Uniforms>
|
||||
class Program : public gl::Program<Primitive, Attributes, Uniforms> {
|
||||
public:
|
||||
using ParentType = gl::Program<Primitive, Attributes, Uniforms>;
|
||||
|
||||
Program(gl::Context& context, ProgramDefines defines)
|
||||
: gl::Program<As, Us>(context, Shaders::vertexSource, fragmentSource(defines))
|
||||
: ParentType(context, Shaders::vertexSource, fragmentSource(defines))
|
||||
{}
|
||||
|
||||
static std::string fragmentSource(ProgramDefines defines) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mbgl/programs/line_program.hpp>
|
||||
#include <mbgl/programs/raster_program.hpp>
|
||||
#include <mbgl/programs/symbol_program.hpp>
|
||||
#include <mbgl/programs/debug_program.hpp>
|
||||
#include <mbgl/programs/collision_box_program.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -24,6 +25,7 @@ public:
|
||||
symbolIcon(context, defines),
|
||||
symbolIconSDF(context, defines),
|
||||
symbolGlyph(context, defines),
|
||||
debug(context, ProgramDefines::None),
|
||||
collisionBox(context, ProgramDefines::None) {
|
||||
}
|
||||
|
||||
@@ -40,6 +42,7 @@ public:
|
||||
SymbolSDFProgram symbolIconSDF;
|
||||
SymbolSDFProgram symbolGlyph;
|
||||
|
||||
DebugProgram debug;
|
||||
CollisionBoxProgram collisionBox;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_tl_parent);
|
||||
|
||||
class RasterProgram : public Program<
|
||||
shaders::raster,
|
||||
gl::Triangle,
|
||||
gl::Attributes<
|
||||
attributes::a_pos,
|
||||
attributes::a_texture_pos>,
|
||||
|
||||
@@ -72,6 +72,7 @@ using SymbolVertex = SymbolAttributes::Vertex;
|
||||
|
||||
class SymbolIconProgram : public Program<
|
||||
shaders::symbol_icon,
|
||||
gl::Triangle,
|
||||
SymbolAttributes,
|
||||
gl::Uniforms<
|
||||
uniforms::u_matrix,
|
||||
@@ -95,6 +96,7 @@ public:
|
||||
|
||||
class SymbolSDFProgram : public Program<
|
||||
shaders::symbol_sdf,
|
||||
gl::Triangle,
|
||||
SymbolAttributes,
|
||||
gl::Uniforms<
|
||||
uniforms::u_matrix,
|
||||
|
||||
@@ -46,7 +46,7 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
|
||||
|
||||
if (segments.empty() || segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
|
||||
// Move to a new segments because the old one can't hold the geometry.
|
||||
segments.emplace_back(vertices.size(), triangles.size());
|
||||
segments.emplace_back(vertices.vertexSize(), triangles.indexSize());
|
||||
}
|
||||
|
||||
// this geometry will be of the Point type, and we'll derive
|
||||
@@ -73,7 +73,7 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
|
||||
triangles.emplace_back(index, index + 3, index + 2);
|
||||
|
||||
segment.vertexLength += vertexLength;
|
||||
segment.primitiveLength += 2;
|
||||
segment.indexLength += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ public:
|
||||
bool hasData() const override;
|
||||
void addGeometry(const GeometryCollection&);
|
||||
|
||||
std::vector<CircleVertex> vertices;
|
||||
std::vector<gl::Triangle> triangles;
|
||||
gl::VertexVector<CircleVertex> vertices;
|
||||
gl::IndexVector<gl::Triangles> triangles;
|
||||
std::vector<gl::Segment> segments;
|
||||
|
||||
optional<gl::VertexBuffer<CircleVertex>> vertexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
|
||||
|
||||
const MapMode mode;
|
||||
};
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
|
||||
const bool renderable,
|
||||
const bool complete,
|
||||
optional<Timestamp> modified,
|
||||
optional<Timestamp> expires,
|
||||
MapDebugOptions debugMode) {
|
||||
std::vector<FillVertex> textPoints;
|
||||
gl::VertexVector<FillVertex, gl::Lines>
|
||||
buildTextVertices(const OverscaledTileID& id,
|
||||
const bool renderable,
|
||||
const bool complete,
|
||||
optional<Timestamp> modified,
|
||||
optional<Timestamp> expires,
|
||||
MapDebugOptions debugMode) {
|
||||
gl::VertexVector<FillVertex, gl::Lines> textLines;
|
||||
|
||||
auto addText = [&] (const std::string& text, double left, double baseline, double scale) {
|
||||
for (uint8_t c : text) {
|
||||
@@ -36,8 +37,8 @@ std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
|
||||
};
|
||||
|
||||
if (prev) {
|
||||
textPoints.emplace_back(FillAttributes::vertex(*prev));
|
||||
textPoints.emplace_back(FillAttributes::vertex(p));
|
||||
textLines.emplace_back(FillAttributes::vertex(*prev),
|
||||
FillAttributes::vertex(p));
|
||||
}
|
||||
|
||||
prev = p;
|
||||
@@ -64,7 +65,7 @@ std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
|
||||
addText(expiresText, 50, baseline + 200, 5);
|
||||
}
|
||||
|
||||
return textPoints;
|
||||
return textLines;
|
||||
}
|
||||
|
||||
DebugBucket::DebugBucket(const OverscaledTileID& id,
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
const optional<Timestamp> expires;
|
||||
const MapDebugOptions debugMode;
|
||||
|
||||
gl::VertexBuffer<FillVertex> vertexBuffer;
|
||||
gl::VertexBuffer<FillVertex, gl::Lines> vertexBuffer;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -39,7 +39,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
|
||||
throw GeometryTooLongException();
|
||||
}
|
||||
|
||||
std::size_t startVertices = vertices.size();
|
||||
std::size_t startVertices = vertices.vertexSize();
|
||||
|
||||
for (const auto& ring : polygon) {
|
||||
std::size_t nVertices = ring.size();
|
||||
@@ -48,7 +48,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
|
||||
continue;
|
||||
|
||||
if (lineSegments.empty() || lineSegments.back().vertexLength + nVertices > std::numeric_limits<uint16_t>::max()) {
|
||||
lineSegments.emplace_back(vertices.size(), lines.size());
|
||||
lineSegments.emplace_back(vertices.vertexSize(), lines.indexSize());
|
||||
}
|
||||
|
||||
auto& lineSegment = lineSegments.back();
|
||||
@@ -64,7 +64,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
|
||||
}
|
||||
|
||||
lineSegment.vertexLength += nVertices;
|
||||
lineSegment.primitiveLength += nVertices;
|
||||
lineSegment.indexLength += nVertices * 2;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> indices = mapbox::earcut(polygon);
|
||||
@@ -73,7 +73,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
|
||||
assert(nIndicies % 3 == 0);
|
||||
|
||||
if (triangleSegments.empty() || triangleSegments.back().vertexLength + totalVertices > std::numeric_limits<uint16_t>::max()) {
|
||||
triangleSegments.emplace_back(startVertices, triangles.size());
|
||||
triangleSegments.emplace_back(startVertices, triangles.indexSize());
|
||||
}
|
||||
|
||||
auto& triangleSegment = triangleSegments.back();
|
||||
@@ -87,7 +87,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
|
||||
}
|
||||
|
||||
triangleSegment.vertexLength += totalVertices;
|
||||
triangleSegment.primitiveLength += nIndicies / 3;
|
||||
triangleSegment.indexLength += nIndicies;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,15 +19,15 @@ public:
|
||||
|
||||
void addGeometry(const GeometryCollection&);
|
||||
|
||||
std::vector<FillVertex> vertices;
|
||||
std::vector<gl::Line> lines;
|
||||
std::vector<gl::Triangle> triangles;
|
||||
gl::VertexVector<FillVertex> vertices;
|
||||
gl::IndexVector<gl::Lines> lines;
|
||||
gl::IndexVector<gl::Triangles> triangles;
|
||||
std::vector<gl::Segment> lineSegments;
|
||||
std::vector<gl::Segment> triangleSegments;
|
||||
|
||||
optional<gl::VertexBuffer<FillVertex>> vertexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Line>> lineIndexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangle>> triangleIndexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Lines>> lineIndexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangles>> triangleIndexBuffer;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -96,7 +96,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
|
||||
nextNormal = util::perp(util::unit(convertPoint<double>(firstCoordinate - *currentCoordinate)));
|
||||
}
|
||||
|
||||
const std::size_t startVertex = vertices.size();
|
||||
const std::size_t startVertex = vertices.vertexSize();
|
||||
std::vector<TriangleElement> triangleStore;
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
@@ -345,11 +345,11 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
|
||||
startOfLine = false;
|
||||
}
|
||||
|
||||
const std::size_t endVertex = vertices.size();
|
||||
const std::size_t endVertex = vertices.vertexSize();
|
||||
const std::size_t vertexCount = endVertex - startVertex;
|
||||
|
||||
if (segments.empty() || segments.back().vertexLength + vertexCount > std::numeric_limits<uint16_t>::max()) {
|
||||
segments.emplace_back(startVertex, triangles.size());
|
||||
segments.emplace_back(startVertex, triangles.indexSize());
|
||||
}
|
||||
|
||||
auto& segment = segments.back();
|
||||
@@ -361,7 +361,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
|
||||
}
|
||||
|
||||
segment.vertexLength += vertexCount;
|
||||
segment.primitiveLength += triangleStore.size();
|
||||
segment.indexLength += triangleStore.size() * 3;
|
||||
}
|
||||
|
||||
void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
|
||||
@@ -376,7 +376,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
|
||||
if (endLeft)
|
||||
extrude = extrude - (util::perp(normal) * endLeft);
|
||||
vertices.emplace_back(LineAttributes::vertex(currentCoordinate, extrude, { round, false }, endLeft, distance * LINE_DISTANCE_SCALE));
|
||||
e3 = vertices.size() - 1 - startVertex;
|
||||
e3 = vertices.vertexSize() - 1 - startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
}
|
||||
@@ -387,7 +387,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
|
||||
if (endRight)
|
||||
extrude = extrude - (util::perp(normal) * endRight);
|
||||
vertices.emplace_back(LineAttributes::vertex(currentCoordinate, extrude, { round, true }, -endRight, distance * LINE_DISTANCE_SCALE));
|
||||
e3 = vertices.size() - 1 - startVertex;
|
||||
e3 = vertices.vertexSize() - 1 - startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
}
|
||||
@@ -412,7 +412,7 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
|
||||
std::vector<TriangleElement>& triangleStore) {
|
||||
Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0);
|
||||
vertices.emplace_back(LineAttributes::vertex(currentVertex, flippedExtrude, { false, lineTurnsLeft }, 0, distance * LINE_DISTANCE_SCALE));
|
||||
e3 = vertices.size() - 1 - startVertex;
|
||||
e3 = vertices.vertexSize() - 1 - startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ public:
|
||||
|
||||
style::LineLayoutProperties layout;
|
||||
|
||||
std::vector<LineVertex> vertices;
|
||||
std::vector<gl::Triangle> triangles;
|
||||
gl::VertexVector<LineVertex> vertices;
|
||||
gl::IndexVector<gl::Triangles> triangles;
|
||||
std::vector<gl::Segment> segments;
|
||||
|
||||
optional<gl::VertexBuffer<LineVertex>> vertexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
|
||||
|
||||
private:
|
||||
struct TriangleElement {
|
||||
|
||||
@@ -41,30 +41,44 @@ namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
static gl::VertexVector<FillVertex, gl::Triangles> tileTriangles() {
|
||||
gl::VertexVector<FillVertex, gl::Triangles> result;
|
||||
result.emplace_back(
|
||||
FillAttributes::vertex({ 0, 0 }),
|
||||
FillAttributes::vertex({ util::EXTENT, 0 }),
|
||||
FillAttributes::vertex({ 0, util::EXTENT }));
|
||||
result.emplace_back(
|
||||
FillAttributes::vertex({ util::EXTENT, 0 }),
|
||||
FillAttributes::vertex({ 0, util::EXTENT }),
|
||||
FillAttributes::vertex({ util::EXTENT, util::EXTENT }));
|
||||
return result;
|
||||
}
|
||||
|
||||
static gl::VertexVector<FillVertex, gl::LineStrip> tileLineStrip() {
|
||||
gl::VertexVector<FillVertex, gl::LineStrip> result;
|
||||
result.emplace_back(FillAttributes::vertex({ 0, 0 }));
|
||||
result.emplace_back(FillAttributes::vertex({ util::EXTENT, 0 }));
|
||||
result.emplace_back(FillAttributes::vertex({ util::EXTENT, util::EXTENT }));
|
||||
result.emplace_back(FillAttributes::vertex({ 0, util::EXTENT }));
|
||||
result.emplace_back(FillAttributes::vertex({ 0, 0 }));
|
||||
return result;
|
||||
}
|
||||
|
||||
static gl::VertexVector<RasterVertex, gl::TriangleStrip> rasterTriangleStrip() {
|
||||
gl::VertexVector<RasterVertex, gl::TriangleStrip> result;
|
||||
result.emplace_back(RasterProgram::vertex({ 0, 0 }, { 0, 0 }));
|
||||
result.emplace_back(RasterProgram::vertex({ util::EXTENT, 0 }, { 32767, 0 }));
|
||||
result.emplace_back(RasterProgram::vertex({ 0, util::EXTENT }, { 0, 32767 }));
|
||||
result.emplace_back(RasterProgram::vertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 }));
|
||||
return result;
|
||||
}
|
||||
|
||||
Painter::Painter(gl::Context& context_, const TransformState& state_)
|
||||
: context(context_),
|
||||
state(state_),
|
||||
tileTriangleVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{
|
||||
FillAttributes::vertex({ 0, 0 }),
|
||||
FillAttributes::vertex({ util::EXTENT, 0 }),
|
||||
FillAttributes::vertex({ 0, util::EXTENT }),
|
||||
FillAttributes::vertex({ util::EXTENT, 0 }),
|
||||
FillAttributes::vertex({ 0, util::EXTENT }),
|
||||
FillAttributes::vertex({ util::EXTENT, util::EXTENT })
|
||||
}})),
|
||||
tileLineStripVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{
|
||||
FillAttributes::vertex({ 0, 0 }),
|
||||
FillAttributes::vertex({ util::EXTENT, 0 }),
|
||||
FillAttributes::vertex({ util::EXTENT, util::EXTENT }),
|
||||
FillAttributes::vertex({ 0, util::EXTENT }),
|
||||
FillAttributes::vertex({ 0, 0 })
|
||||
}})),
|
||||
rasterVertexBuffer(context.createVertexBuffer(std::vector<RasterVertex> {{
|
||||
RasterProgram::vertex({ 0, 0 }, { 0, 0 }),
|
||||
RasterProgram::vertex({ util::EXTENT, 0 }, { 32767, 0 }),
|
||||
RasterProgram::vertex({ 0, util::EXTENT }, { 0, 32767 }),
|
||||
RasterProgram::vertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 })
|
||||
}})) {
|
||||
tileTriangleVertexBuffer(context.createVertexBuffer(tileTriangles())),
|
||||
tileLineStripVertexBuffer(context.createVertexBuffer(tileLineStrip())),
|
||||
rasterVertexBuffer(context.createVertexBuffer(rasterTriangleStrip())) {
|
||||
#ifndef NDEBUG
|
||||
gl::debugging::enable();
|
||||
#endif
|
||||
|
||||
@@ -156,9 +156,9 @@ private:
|
||||
std::unique_ptr<Programs> overdrawPrograms;
|
||||
#endif
|
||||
|
||||
gl::VertexBuffer<FillVertex> tileTriangleVertexBuffer;
|
||||
gl::VertexBuffer<FillVertex> tileLineStripVertexBuffer;
|
||||
gl::VertexBuffer<RasterVertex> rasterVertexBuffer;
|
||||
gl::VertexBuffer<FillVertex, gl::Triangles> tileTriangleVertexBuffer;
|
||||
gl::VertexBuffer<FillVertex, gl::LineStrip> tileLineStripVertexBuffer;
|
||||
gl::VertexBuffer<RasterVertex, gl::TriangleStrip> rasterVertexBuffer;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -28,11 +28,12 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
|
||||
spriteAtlas->bind(true, context, 0);
|
||||
|
||||
for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) {
|
||||
context.draw({
|
||||
parameters.programs.fillPattern.draw(
|
||||
context,
|
||||
gl::Triangles(),
|
||||
depthModeForSublayer(0, gl::DepthMode::ReadOnly),
|
||||
gl::StencilMode::disabled(),
|
||||
colorModeForRenderPass(),
|
||||
parameters.programs.fillPattern,
|
||||
FillPatternUniforms::values(
|
||||
matrixForTile(tileID),
|
||||
properties.backgroundOpacity.value,
|
||||
@@ -43,16 +44,17 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
|
||||
tileID,
|
||||
state
|
||||
),
|
||||
gl::Unindexed<gl::TriangleStrip>(tileTriangleVertexBuffer)
|
||||
});
|
||||
tileTriangleVertexBuffer
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) {
|
||||
context.draw({
|
||||
parameters.programs.fill.draw(
|
||||
context,
|
||||
gl::Triangles(),
|
||||
depthModeForSublayer(0, gl::DepthMode::ReadOnly),
|
||||
gl::StencilMode::disabled(),
|
||||
colorModeForRenderPass(),
|
||||
parameters.programs.fill,
|
||||
FillProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ matrixForTile(tileID) },
|
||||
uniforms::u_opacity::Value{ properties.backgroundOpacity.value },
|
||||
@@ -60,8 +62,8 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
|
||||
uniforms::u_outline_color::Value{ properties.backgroundColor.value },
|
||||
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
|
||||
},
|
||||
gl::Unindexed<gl::TriangleStrip>(tileTriangleVertexBuffer)
|
||||
});
|
||||
tileTriangleVertexBuffer
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,14 @@ void Painter::renderCircle(PaintParameters& parameters,
|
||||
const CirclePaintProperties& properties = layer.impl->paint;
|
||||
const bool scaleWithMap = properties.circlePitchScale.value == CirclePitchScaleType::Map;
|
||||
|
||||
context.draw({
|
||||
parameters.programs.circle.draw(
|
||||
context,
|
||||
gl::Triangles(),
|
||||
depthModeForSublayer(0, gl::DepthMode::ReadOnly),
|
||||
frame.mapMode == MapMode::Still
|
||||
? stencilModeForClipping(tile.clip)
|
||||
: gl::StencilMode::disabled(),
|
||||
colorModeForRenderPass(),
|
||||
parameters.programs.circle,
|
||||
CircleProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ tile.translatedMatrix(properties.circleTranslate.value,
|
||||
properties.circleTranslateAnchor.value,
|
||||
@@ -47,12 +48,10 @@ void Painter::renderCircle(PaintParameters& parameters,
|
||||
: pixelsToGLUnits },
|
||||
uniforms::u_devicepixelratio::Value{ frame.pixelRatio },
|
||||
},
|
||||
gl::Segmented<gl::Triangles>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.indexBuffer,
|
||||
bucket.segments
|
||||
)
|
||||
});
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.indexBuffer,
|
||||
bucket.segments
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
namespace mbgl {
|
||||
|
||||
void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& clip) {
|
||||
context.draw({
|
||||
programs->fill.draw(
|
||||
context,
|
||||
gl::Triangles(),
|
||||
gl::DepthMode::disabled(),
|
||||
gl::StencilMode {
|
||||
gl::StencilMode::Always(),
|
||||
@@ -17,7 +19,6 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl
|
||||
gl::StencilMode::Replace
|
||||
},
|
||||
gl::ColorMode::disabled(),
|
||||
programs->fill,
|
||||
FillProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ matrixForTile(tileID) },
|
||||
uniforms::u_opacity::Value{ 0.0f },
|
||||
@@ -25,8 +26,8 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl
|
||||
uniforms::u_outline_color::Value{ Color {} },
|
||||
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
|
||||
},
|
||||
gl::Unindexed<gl::Triangles>(tileTriangleVertexBuffer)
|
||||
});
|
||||
tileTriangleVertexBuffer
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -18,21 +18,19 @@ void Painter::renderTileDebug(const RenderTile& renderTile) {
|
||||
|
||||
MBGL_DEBUG_GROUP(std::string { "debug " } + util::toString(renderTile.id));
|
||||
|
||||
auto draw = [&] (Color color, auto subject) {
|
||||
context.draw({
|
||||
auto draw = [&] (Color color, const auto& vertexBuffer, auto drawMode) {
|
||||
programs->debug.draw(
|
||||
context,
|
||||
drawMode,
|
||||
gl::DepthMode::disabled(),
|
||||
stencilModeForClipping(renderTile.clip),
|
||||
gl::ColorMode::unblended(),
|
||||
programs->fill,
|
||||
FillProgram::UniformValues {
|
||||
DebugProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ renderTile.matrix },
|
||||
uniforms::u_opacity::Value{ 1.0f },
|
||||
uniforms::u_color::Value{ color },
|
||||
uniforms::u_outline_color::Value{ color },
|
||||
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
|
||||
uniforms::u_color::Value{ color }
|
||||
},
|
||||
subject
|
||||
});
|
||||
vertexBuffer
|
||||
);
|
||||
};
|
||||
|
||||
if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
|
||||
@@ -47,15 +45,12 @@ void Painter::renderTileDebug(const RenderTile& renderTile) {
|
||||
tile.expires, frame.debugOptions, context);
|
||||
}
|
||||
|
||||
const auto& vertexBuffer = tile.debugBucket->vertexBuffer;
|
||||
|
||||
draw(Color::white(), gl::Unindexed<gl::Lines>(vertexBuffer, 4.0f * frame.pixelRatio));
|
||||
draw(Color::black(), gl::Unindexed<gl::Points>(vertexBuffer, 2.0f));
|
||||
draw(Color::black(), gl::Unindexed<gl::Lines>(vertexBuffer, 2.0f * frame.pixelRatio));
|
||||
draw(Color::white(), tile.debugBucket->vertexBuffer, gl::Lines { 4.0f * frame.pixelRatio });
|
||||
draw(Color::black(), tile.debugBucket->vertexBuffer, gl::Lines { 2.0f * frame.pixelRatio });
|
||||
}
|
||||
|
||||
if (frame.debugOptions & MapDebugOptions::TileBorders) {
|
||||
draw(Color::red(), gl::Unindexed<gl::LineStrip>(tileLineStripVertexBuffer, 4.0f * frame.pixelRatio));
|
||||
draw(Color::red(), tileLineStripVertexBuffer, gl::LineStrip { 4.0f * frame.pixelRatio });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,12 +35,18 @@ void Painter::renderFill(PaintParameters& parameters,
|
||||
|
||||
spriteAtlas->bind(true, context, 0);
|
||||
|
||||
auto draw = [&] (uint8_t sublayer, auto& program, const auto& subject) {
|
||||
context.draw({
|
||||
auto draw = [&] (uint8_t sublayer,
|
||||
auto& program,
|
||||
const auto& drawMode,
|
||||
const auto& vertexBuffer,
|
||||
const auto& indexBuffer,
|
||||
const auto& segments) {
|
||||
program.draw(
|
||||
context,
|
||||
drawMode,
|
||||
depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite),
|
||||
stencilModeForClipping(tile.clip),
|
||||
colorModeForRenderPass(),
|
||||
program,
|
||||
FillPatternUniforms::values(
|
||||
tile.translatedMatrix(properties.fillTranslate.value,
|
||||
properties.fillTranslateAnchor.value,
|
||||
@@ -53,16 +59,18 @@ void Painter::renderFill(PaintParameters& parameters,
|
||||
tile.id,
|
||||
state
|
||||
),
|
||||
subject
|
||||
});
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
segments
|
||||
);
|
||||
};
|
||||
|
||||
draw(0,
|
||||
parameters.programs.fillPattern,
|
||||
gl::Segmented<gl::Triangles>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.triangleIndexBuffer,
|
||||
bucket.triangleSegments));
|
||||
gl::Triangles(),
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.triangleIndexBuffer,
|
||||
bucket.triangleSegments);
|
||||
|
||||
if (!properties.fillAntialias.value || !properties.fillOutlineColor.isUndefined()) {
|
||||
return;
|
||||
@@ -70,18 +78,24 @@ void Painter::renderFill(PaintParameters& parameters,
|
||||
|
||||
draw(2,
|
||||
parameters.programs.fillOutlinePattern,
|
||||
gl::Segmented<gl::Lines>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.lineIndexBuffer,
|
||||
bucket.lineSegments,
|
||||
2.0f));
|
||||
gl::Lines { 2.0f },
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.lineIndexBuffer,
|
||||
bucket.lineSegments);
|
||||
} else {
|
||||
auto draw = [&] (uint8_t sublayer, auto& program, Color outlineColor, const auto& subject) {
|
||||
context.draw({
|
||||
auto draw = [&] (uint8_t sublayer,
|
||||
auto& program,
|
||||
Color outlineColor,
|
||||
const auto& drawMode,
|
||||
const auto& vertexBuffer,
|
||||
const auto& indexBuffer,
|
||||
const auto& segments) {
|
||||
program.draw(
|
||||
context,
|
||||
drawMode,
|
||||
depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite),
|
||||
stencilModeForClipping(tile.clip),
|
||||
colorModeForRenderPass(),
|
||||
program,
|
||||
FillProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ tile.translatedMatrix(properties.fillTranslate.value,
|
||||
properties.fillTranslateAnchor.value,
|
||||
@@ -91,19 +105,20 @@ void Painter::renderFill(PaintParameters& parameters,
|
||||
uniforms::u_outline_color::Value{ outlineColor },
|
||||
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
|
||||
},
|
||||
subject
|
||||
});
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
segments
|
||||
);
|
||||
};
|
||||
|
||||
if (properties.fillAntialias.value && !properties.fillOutlineColor.isUndefined() && pass == RenderPass::Translucent) {
|
||||
draw(2,
|
||||
parameters.programs.fillOutline,
|
||||
properties.fillOutlineColor.value,
|
||||
gl::Segmented<gl::Lines>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.lineIndexBuffer,
|
||||
bucket.lineSegments,
|
||||
2.0f));
|
||||
gl::Lines { 2.0f },
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.lineIndexBuffer,
|
||||
bucket.lineSegments);
|
||||
}
|
||||
|
||||
// Only draw the fill when it's opaque and we're drawing opaque fragments,
|
||||
@@ -112,21 +127,20 @@ void Painter::renderFill(PaintParameters& parameters,
|
||||
draw(1,
|
||||
parameters.programs.fill,
|
||||
properties.fillOutlineColor.value,
|
||||
gl::Segmented<gl::Triangles>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.triangleIndexBuffer,
|
||||
bucket.triangleSegments));
|
||||
gl::Triangles(),
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.triangleIndexBuffer,
|
||||
bucket.triangleSegments);
|
||||
}
|
||||
|
||||
if (properties.fillAntialias.value && properties.fillOutlineColor.isUndefined() && pass == RenderPass::Translucent) {
|
||||
draw(2,
|
||||
parameters.programs.fillOutline,
|
||||
properties.fillColor.value,
|
||||
gl::Segmented<gl::Lines>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.lineIndexBuffer,
|
||||
bucket.lineSegments,
|
||||
2.0f));
|
||||
gl::Lines { 2.0f },
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.lineIndexBuffer,
|
||||
bucket.lineSegments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,18 +24,17 @@ void Painter::renderLine(PaintParameters& parameters,
|
||||
const auto& properties = layer.impl->paint;
|
||||
|
||||
auto draw = [&] (auto& program, auto&& uniformValues) {
|
||||
context.draw({
|
||||
program.draw(
|
||||
context,
|
||||
gl::Triangles(),
|
||||
depthModeForSublayer(0, gl::DepthMode::ReadOnly),
|
||||
stencilModeForClipping(tile.clip),
|
||||
colorModeForRenderPass(),
|
||||
program,
|
||||
std::move(uniformValues),
|
||||
gl::Segmented<gl::Triangles>(
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.indexBuffer,
|
||||
bucket.segments
|
||||
)
|
||||
});
|
||||
*bucket.vertexBuffer,
|
||||
*bucket.indexBuffer,
|
||||
bucket.segments
|
||||
);
|
||||
};
|
||||
|
||||
if (!properties.lineDasharray.value.from.empty()) {
|
||||
|
||||
@@ -54,11 +54,12 @@ void Painter::renderRaster(PaintParameters& parameters,
|
||||
context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
|
||||
context.bindTexture(*bucket.texture, 1, gl::TextureFilter::Linear);
|
||||
|
||||
context.draw({
|
||||
parameters.programs.raster.draw(
|
||||
context,
|
||||
gl::TriangleStrip(),
|
||||
depthModeForSublayer(0, gl::DepthMode::ReadOnly),
|
||||
gl::StencilMode::disabled(),
|
||||
colorModeForRenderPass(),
|
||||
parameters.programs.raster,
|
||||
RasterProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ tile.matrix },
|
||||
uniforms::u_image0::Value{ 0 },
|
||||
@@ -74,8 +75,8 @@ void Painter::renderRaster(PaintParameters& parameters,
|
||||
uniforms::u_scale_parent::Value{ 1.0f },
|
||||
uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} },
|
||||
},
|
||||
gl::Unindexed<gl::TriangleStrip>(rasterVertexBuffer)
|
||||
});
|
||||
rasterVertexBuffer
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -46,7 +46,9 @@ void Painter::renderSymbol(PaintParameters& parameters,
|
||||
const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.textAllowOverlap || layout.iconAllowOverlap ||
|
||||
layout.textIgnorePlacement || layout.iconIgnorePlacement));
|
||||
|
||||
context.draw({
|
||||
program.draw(
|
||||
context,
|
||||
gl::Triangles(),
|
||||
values_.pitchAlignment == AlignmentType::Map
|
||||
? depthModeForSublayer(0, gl::DepthMode::ReadOnly)
|
||||
: gl::DepthMode::disabled(),
|
||||
@@ -54,14 +56,11 @@ void Painter::renderSymbol(PaintParameters& parameters,
|
||||
? gl::StencilMode::disabled()
|
||||
: stencilModeForClipping(tile.clip),
|
||||
colorModeForRenderPass(),
|
||||
program,
|
||||
std::move(uniformValues),
|
||||
gl::Segmented<gl::Triangles>(
|
||||
*buffers.vertexBuffer,
|
||||
*buffers.indexBuffer,
|
||||
buffers.segments
|
||||
)
|
||||
});
|
||||
*buffers.vertexBuffer,
|
||||
*buffers.indexBuffer,
|
||||
buffers.segments
|
||||
);
|
||||
};
|
||||
|
||||
if (bucket.hasIconData()) {
|
||||
@@ -119,22 +118,20 @@ void Painter::renderSymbol(PaintParameters& parameters,
|
||||
}
|
||||
|
||||
if (bucket.hasCollisionBoxData()) {
|
||||
context.draw({
|
||||
programs->collisionBox.draw(
|
||||
context,
|
||||
gl::Lines { 1.0f },
|
||||
gl::DepthMode::disabled(),
|
||||
gl::StencilMode::disabled(),
|
||||
colorModeForRenderPass(),
|
||||
programs->collisionBox,
|
||||
CollisionBoxProgram::UniformValues {
|
||||
uniforms::u_matrix::Value{ tile.matrix },
|
||||
uniforms::u_scale::Value{ std::pow(2.0f, float(state.getZoom() - tile.tile.id.overscaledZ)) },
|
||||
uniforms::u_zoom::Value{ float(state.getZoom() * 10) },
|
||||
uniforms::u_maxzoom::Value{ float((tile.id.canonical.z + 1) * 10) },
|
||||
},
|
||||
gl::Unindexed<gl::Lines>(
|
||||
*bucket.collisionBox.vertexBuffer,
|
||||
1.0f
|
||||
)
|
||||
});
|
||||
*bucket.collisionBox.vertexBuffer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,26 +34,26 @@ public:
|
||||
const bool iconsNeedLinear;
|
||||
|
||||
struct TextBuffer {
|
||||
std::vector<SymbolVertex> vertices;
|
||||
std::vector<gl::Triangle> triangles;
|
||||
gl::VertexVector<SymbolVertex> vertices;
|
||||
gl::IndexVector<gl::Triangles> triangles;
|
||||
std::vector<gl::Segment> segments;
|
||||
|
||||
optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
|
||||
} text;
|
||||
|
||||
struct IconBuffer {
|
||||
std::vector<SymbolVertex> vertices;
|
||||
std::vector<gl::Triangle> triangles;
|
||||
gl::VertexVector<SymbolVertex> vertices;
|
||||
gl::IndexVector<gl::Triangles> triangles;
|
||||
std::vector<gl::Segment> segments;
|
||||
|
||||
optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
|
||||
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
|
||||
} icon;
|
||||
|
||||
struct CollisionBoxBuffer {
|
||||
std::vector<CollisionBoxVertex> vertices;
|
||||
optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer;
|
||||
gl::VertexVector<CollisionBoxVertex, gl::Lines> vertices;
|
||||
optional<gl::VertexBuffer<CollisionBoxVertex, gl::Lines>> vertexBuffer;
|
||||
} collisionBox;
|
||||
};
|
||||
|
||||
|
||||
21
src/mbgl/util/ignore.hpp
Normal file
21
src/mbgl/util/ignore.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
// Accept any number of parameters of any types, and do nothing with them.
|
||||
// Useful for providing a context for parameter pack expansion where a legal
|
||||
// expansion context is not otherwise available.
|
||||
//
|
||||
// See https://github.com/mapbox/cpp/blob/master/C%2B%2B%20Structural%20Metaprogramming.md
|
||||
// for more details.
|
||||
//
|
||||
template <class... Ts> void ignore(Ts&&...) {}
|
||||
|
||||
// std::initializer_list overload, for situations where you need sequenced
|
||||
// modifications.
|
||||
//
|
||||
template <class T> void ignore(const std::initializer_list<T>&) {}
|
||||
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user