[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:
John Firebaugh
2016-11-07 12:26:05 -08:00
parent 66bdbc3b96
commit 1db2ffbc1b
42 changed files with 475 additions and 362 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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),

View File

@@ -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&);

View File

@@ -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,

View File

@@ -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

View File

@@ -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;
};

View 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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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<

View File

@@ -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,

View 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

View File

@@ -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>
{

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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;
};

View File

@@ -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>,

View File

@@ -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,

View File

@@ -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;
}
}
}

View File

@@ -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;
};

View File

@@ -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,

View File

@@ -32,7 +32,7 @@ public:
const optional<Timestamp> expires;
const MapDebugOptions debugMode;
gl::VertexBuffer<FillVertex> vertexBuffer;
gl::VertexBuffer<FillVertex, gl::Lines> vertexBuffer;
};
} // namespace mbgl

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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
);
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 });
}
}

View File

@@ -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);
}
}
}

View File

@@ -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()) {

View File

@@ -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

View File

@@ -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
);
}
}

View File

@@ -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
View 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