diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 97f10968707..3fd52d99887 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -66,7 +66,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 @@ -74,6 +73,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 @@ -155,6 +155,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 diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 126da38de50..a2b165fa217 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -157,17 +158,14 @@ class Attributes { template static std::function binder(const State& state, std::index_sequence) { return [&state] (std::size_t vertexOffset) { - noop((bindAttribute(std::get(state).location, - std::get(state).count, - std::get(state).type, - sizeof(Vertex), - vertexOffset, - Vertex::attributeOffsets[Is]), 0)...); + ignore((bindAttribute(std::get(state).location, + std::get(state).count, + std::get(state).type, + sizeof(Vertex), + vertexOffset, + Vertex::attributeOffsets[Is]), 0)...); }; } - - // This exists only to provide a varags context for unpacking the assignments in `binder`. - template static void noop(int...) {} }; } // namespace gl diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 52d0820dcf2..9899485a16f 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -492,9 +492,9 @@ void Context::draw(const Drawable& drawable) { if (drawable.indexBuffer) { MBGL_CHECK_ERROR(glDrawElements( static_cast(primitiveType), - static_cast(drawable.primitiveSize / sizeof(uint16_t) * segment.primitiveLength), + static_cast(segment.indexLength), GL_UNSIGNED_SHORT, - reinterpret_cast(drawable.primitiveSize * segment.primitiveOffset))); + reinterpret_cast(sizeof(uint16_t) * segment.indexOffset))); } else { MBGL_CHECK_ERROR(glDrawArrays( static_cast(primitiveType), diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 85d8f32058a..aece92ea52d 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -8,9 +8,16 @@ #include #include #include -#include +#include +#include +#include +#include +#include +#include #include + +#include #include #include #include @@ -33,18 +40,18 @@ class Context : private util::noncopyable { UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader); UniqueTexture createTexture(); - template - VertexBuffer createVertexBuffer(std::vector&& v) { - return VertexBuffer { - v.size(), - createVertexBuffer(v.data(), v.size() * sizeof(V)) + template + VertexBuffer createVertexBuffer(VertexVector&& v) { + return VertexBuffer { + v.vertexSize(), + createVertexBuffer(v.data(), v.byteSize()) }; } - template - IndexBuffer

createIndexBuffer(std::vector

&& v) { - return IndexBuffer

{ - createIndexBuffer(v.data(), v.size() * sizeof(P)) + template + IndexBuffer createIndexBuffer(IndexVector&& v) { + return IndexBuffer { + createIndexBuffer(v.data(), v.byteSize()) }; } @@ -94,6 +101,19 @@ class Context : private util::noncopyable { optional depth, optional stencil); + struct Drawable { + DrawMode drawMode; + DepthMode depthMode; + StencilMode stencilMode; + ColorMode colorMode; + gl::ProgramID program; + gl::BufferID vertexBuffer; + gl::BufferID indexBuffer; + const std::vector& segments; + std::function bindUniforms; + std::function bindAttributes; + }; + void draw(const Drawable&); void setDepthMode(const DepthMode&); diff --git a/src/mbgl/gl/draw_mode.hpp b/src/mbgl/gl/draw_mode.hpp index a3791622105..8f7db0a3fa2 100644 --- a/src/mbgl/gl/draw_mode.hpp +++ b/src/mbgl/gl/draw_mode.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include 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, 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, diff --git a/src/mbgl/gl/drawable.hpp b/src/mbgl/gl/drawable.hpp deleted file mode 100644 index 747d8facf04..00000000000 --- a/src/mbgl/gl/drawable.hpp +++ /dev/null @@ -1,124 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace mbgl { -namespace gl { - -template -class UnindexedVertices { -public: - using VertexType = Vertex; - - UnindexedVertices(DrawMode drawMode_, const VertexBuffer& 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 segments; -}; - -template -auto Unindexed(const VertexBuffer& vertexBuffer, - Args&&... drawModeArguments) { - return UnindexedVertices( - DrawMode { std::forward(drawModeArguments)... }, - vertexBuffer); -} - -template -class SegmentedVertices { -public: - using VertexType = Vertex; - - SegmentedVertices(DrawMode drawMode_, - const VertexBuffer& vertexBuffer_, - const IndexBuffer& indexBuffer_, - const std::vector& 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& segments; -}; - -template -auto Segmented(const VertexBuffer& vertexBuffer, - const IndexBuffer& indexBuffer, - const std::vector& segments, - Args&&... drawModeArguments) { - static_assert(std::is_same::value, "primitive mode mismatch"); - return SegmentedVertices( - DrawMode { std::forward(drawModeArguments)... }, - vertexBuffer, - indexBuffer, - segments); -} - -class Drawable { -public: - template - 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::value, "vertex type must use standard layout"); - static_assert(std::is_same::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& segments; - std::function bindUniforms; - std::function bindAttributes; -}; - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp index 5d8630b902d..8b40bf68c39 100644 --- a/src/mbgl/gl/index_buffer.hpp +++ b/src/mbgl/gl/index_buffer.hpp @@ -2,39 +2,37 @@ #include #include +#include + +#include namespace mbgl { namespace gl { -class Line { +template +class IndexVector { public: - using DrawMode = Lines; - - Line(uint16_t a_, uint16_t b_) - : a(a_), b(b_) {} + static constexpr std::size_t groupSize = DrawMode::bufferGroupSize; - uint16_t a; - uint16_t b; -}; + template + void emplace_back(Args&&... args) { + static_assert(sizeof...(args) == groupSize, "wrong buffer element count"); + ignore({(v.emplace_back(std::forward(args)), 0)...}); + } -class Triangle { -public: - using DrawMode = Triangles; + std::size_t indexSize() const { return v.size(); } + std::size_t byteSize() const { return v.size() * sizeof(uint16_t); } - Triangle(uint16_t a_, uint16_t b_, uint16_t c_) - : a(a_), b(b_), c(c_) {} + bool empty() const { return v.empty(); } + const uint16_t* data() const { return v.data(); } - uint16_t a; - uint16_t b; - uint16_t c; +private: + std::vector v; }; -template +template class IndexBuffer { public: - static_assert(std::is_same::value || std::is_same::value, - "primitive must be Line or Triangle"); - static constexpr std::size_t primitiveSize = sizeof(Primitive); UniqueBuffer buffer; }; diff --git a/src/mbgl/gl/primitives.hpp b/src/mbgl/gl/primitives.hpp new file mode 100644 index 00000000000..fe6b1b2e5b0 --- /dev/null +++ b/src/mbgl/gl/primitives.hpp @@ -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 diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index ea4dbcc1df1..929237037bb 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -3,21 +3,28 @@ #include #include #include +#include +#include +#include +#include #include namespace mbgl { namespace gl { -template +template 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::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 @@ class Program { attributesState(Attributes::state(program)), uniformsState(Uniforms::state(program)) {} + // Indexed drawing. + template + void draw(Context& context, + DrawMode drawMode, + DepthMode depthMode, + StencilMode stencilMode, + ColorMode colorMode, + UniformValues&& uniformValues, + const VertexBuffer& vertexBuffer, + const IndexBuffer& indexBuffer, + const std::vector& segments) { + static_assert(std::is_same::value, "incompatible draw mode"); + context.draw({ + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + program, + vertexBuffer.buffer, + indexBuffer.buffer, + segments, + Uniforms::binder(uniformsState, std::move(uniformValues)), + Attributes::binder(attributesState) + }); + } + + // Unindexed drawing. + template + void draw(Context& context, + DrawMode drawMode, + DepthMode depthMode, + StencilMode stencilMode, + ColorMode colorMode, + UniformValues&& uniformValues, + const VertexBuffer& vertexBuffer) { + static_assert(std::is_same::value, "incompatible draw mode"); + context.draw({ + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + program, + vertexBuffer.buffer, + 0, + {{ 0, 0, vertexBuffer.vertexCount, 0 }}, + Uniforms::binder(uniformsState, std::move(uniformValues)), + Attributes::binder(attributesState) + }); + } + +private: UniqueShader vertexShader; UniqueShader fragmentShader; UniqueProgram program; diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp index 648d02e9029..f65f2a5f7e4 100644 --- a/src/mbgl/gl/segment.hpp +++ b/src/mbgl/gl/segment.hpp @@ -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 diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 52ee08bb4cc..1c1d7d60757 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -73,13 +74,9 @@ class Uniforms { static std::function binder(State& state, Values&& values_) { return [&state, values = std::move(values_)] () mutable { - noop((std::get(state) = std::get(values), 0)...); + ignore((std::get(state) = std::get(values), 0)...); }; } - -private: - // This exists only to provide a varags context for unpacking the assignments in `binder`. - template static void noop(int...) {} }; } // namespace gl diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp index c77a9a42134..9d5532beabe 100644 --- a/src/mbgl/gl/vertex_buffer.hpp +++ b/src/mbgl/gl/vertex_buffer.hpp @@ -1,14 +1,43 @@ #pragma once #include +#include +#include +#include + +#include namespace mbgl { namespace gl { -template +template +class VertexVector { +public: + using Vertex = V; + static constexpr std::size_t groupSize = DrawMode::bufferGroupSize; + + template + void emplace_back(Args&&... args) { + static_assert(sizeof...(args) == groupSize, "wrong buffer element count"); + ignore({(v.emplace_back(std::forward(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 v; +}; + +template class VertexBuffer { public: + using Vertex = V; static constexpr std::size_t vertexSize = sizeof(Vertex); + std::size_t vertexCount; UniqueBuffer buffer; }; diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index c2f8426785e..932745aa57c 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -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::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); diff --git a/src/mbgl/programs/circle_program.hpp b/src/mbgl/programs/circle_program.hpp index 690608a4388..75c030b1c8c 100644 --- a/src/mbgl/programs/circle_program.hpp +++ b/src/mbgl/programs/circle_program.hpp @@ -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< diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index 66b12846210..5eda3fefb06 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -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, diff --git a/src/mbgl/programs/debug_program.hpp b/src/mbgl/programs/debug_program.hpp new file mode 100644 index 00000000000..3596dc1f7e3 --- /dev/null +++ b/src/mbgl/programs/debug_program.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include +#include + +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 diff --git a/src/mbgl/programs/fill_program.hpp b/src/mbgl/programs/fill_program.hpp index 3f738527c8c..d885215c596 100644 --- a/src/mbgl/programs/fill_program.hpp +++ b/src/mbgl/programs/fill_program.hpp @@ -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> { diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index 960438f4cd9..07ae35b8edc 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -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 @@ class LineProgram : public Program< class LinePatternProgram : public Program< shaders::line_pattern, + gl::Triangle, LineAttributes, gl::Uniforms< uniforms::u_matrix, @@ -147,6 +149,7 @@ class LinePatternProgram : public Program< class LineSDFProgram : public Program< shaders::line_sdf, + gl::Triangle, LineAttributes, gl::Uniforms< uniforms::u_matrix, diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 9f154b051af..fa41d43e5cc 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -11,11 +11,13 @@ enum class ProgramDefines : bool { Overdraw = true, }; -template -class Program : public gl::Program { +template +class Program : public gl::Program { public: + using ParentType = gl::Program; + Program(gl::Context& context, ProgramDefines defines) - : gl::Program(context, Shaders::vertexSource, fragmentSource(defines)) + : ParentType(context, Shaders::vertexSource, fragmentSource(defines)) {} static std::string fragmentSource(ProgramDefines defines) { diff --git a/src/mbgl/programs/programs.hpp b/src/mbgl/programs/programs.hpp index aebafaec62b..53ed26e969c 100644 --- a/src/mbgl/programs/programs.hpp +++ b/src/mbgl/programs/programs.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace mbgl { @@ -24,6 +25,7 @@ class Programs { symbolIcon(context, defines), symbolIconSDF(context, defines), symbolGlyph(context, defines), + debug(context, ProgramDefines::None), collisionBox(context, ProgramDefines::None) { } @@ -40,6 +42,7 @@ class Programs { SymbolSDFProgram symbolIconSDF; SymbolSDFProgram symbolGlyph; + DebugProgram debug; CollisionBoxProgram collisionBox; }; diff --git a/src/mbgl/programs/raster_program.hpp b/src/mbgl/programs/raster_program.hpp index 1e9a0cdb6a1..1bab2d5765b 100644 --- a/src/mbgl/programs/raster_program.hpp +++ b/src/mbgl/programs/raster_program.hpp @@ -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>, diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index eb8c56b3261..be987551c0b 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -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 @@ class SymbolIconProgram : public Program< class SymbolSDFProgram : public Program< shaders::symbol_sdf, + gl::Triangle, SymbolAttributes, gl::Uniforms< uniforms::u_matrix, diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp index 08f2a144a19..ba2285c4eb7 100644 --- a/src/mbgl/renderer/circle_bucket.cpp +++ b/src/mbgl/renderer/circle_bucket.cpp @@ -46,7 +46,7 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) { if (segments.empty() || segments.back().vertexLength + vertexLength > std::numeric_limits::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; } } } diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index d5df06f1109..a93b052d681 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -20,12 +20,12 @@ class CircleBucket : public Bucket { bool hasData() const override; void addGeometry(const GeometryCollection&); - std::vector vertices; - std::vector triangles; + gl::VertexVector vertices; + gl::IndexVector triangles; std::vector segments; optional> vertexBuffer; - optional> indexBuffer; + optional> indexBuffer; const MapMode mode; }; diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp index 72fce8b9bf0..fc62db794a4 100644 --- a/src/mbgl/renderer/debug_bucket.cpp +++ b/src/mbgl/renderer/debug_bucket.cpp @@ -12,13 +12,14 @@ namespace mbgl { -std::vector buildTextVertices(const OverscaledTileID& id, - const bool renderable, - const bool complete, - optional modified, - optional expires, - MapDebugOptions debugMode) { - std::vector textPoints; +gl::VertexVector +buildTextVertices(const OverscaledTileID& id, + const bool renderable, + const bool complete, + optional modified, + optional expires, + MapDebugOptions debugMode) { + gl::VertexVector textLines; auto addText = [&] (const std::string& text, double left, double baseline, double scale) { for (uint8_t c : text) { @@ -38,8 +39,8 @@ std::vector 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; @@ -66,7 +67,7 @@ std::vector buildTextVertices(const OverscaledTileID& id, addText(expiresText, 50, baseline + 200, 5); } - return textPoints; + return textLines; } DebugBucket::DebugBucket(const OverscaledTileID& id, diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp index 9b19e7f949d..4c173786ae5 100644 --- a/src/mbgl/renderer/debug_bucket.hpp +++ b/src/mbgl/renderer/debug_bucket.hpp @@ -32,7 +32,7 @@ class DebugBucket : private util::noncopyable { const optional expires; const MapDebugOptions debugMode; - gl::VertexBuffer vertexBuffer; + gl::VertexBuffer vertexBuffer; }; } // namespace mbgl diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index c87e640624a..c0d6bfbbd13 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -40,7 +40,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(); @@ -49,7 +49,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) { continue; if (lineSegments.empty() || lineSegments.back().vertexLength + nVertices > std::numeric_limits::max()) { - lineSegments.emplace_back(vertices.size(), lines.size()); + lineSegments.emplace_back(vertices.vertexSize(), lines.indexSize()); } auto& lineSegment = lineSegments.back(); @@ -65,7 +65,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) { } lineSegment.vertexLength += nVertices; - lineSegment.primitiveLength += nVertices; + lineSegment.indexLength += nVertices * 2; } std::vector indices = mapbox::earcut(polygon); @@ -74,7 +74,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) { assert(nIndicies % 3 == 0); if (triangleSegments.empty() || triangleSegments.back().vertexLength + totalVertices > std::numeric_limits::max()) { - triangleSegments.emplace_back(startVertices, triangles.size()); + triangleSegments.emplace_back(startVertices, triangles.indexSize()); } auto& triangleSegment = triangleSegments.back(); @@ -88,7 +88,7 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) { } triangleSegment.vertexLength += totalVertices; - triangleSegment.primitiveLength += nIndicies / 3; + triangleSegment.indexLength += nIndicies; } } diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index b2c549a7588..4ea558b6298 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -19,15 +19,15 @@ class FillBucket : public Bucket { void addGeometry(const GeometryCollection&); - std::vector vertices; - std::vector lines; - std::vector triangles; + gl::VertexVector vertices; + gl::IndexVector lines; + gl::IndexVector triangles; std::vector lineSegments; std::vector triangleSegments; optional> vertexBuffer; - optional> lineIndexBuffer; - optional> triangleIndexBuffer; + optional> lineIndexBuffer; + optional> triangleIndexBuffer; }; } // namespace mbgl diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 1db075652c9..554fef5ca75 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -96,7 +96,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) { nextNormal = util::perp(util::unit(convertPoint(firstCoordinate - *currentCoordinate))); } - const std::size_t startVertex = vertices.size(); + const std::size_t startVertex = vertices.vertexSize(); std::vector 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::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& triangleStore) { Point 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); } diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 4d78a80123f..9903ca1842b 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -26,12 +26,12 @@ class LineBucket : public Bucket { style::LineLayoutProperties layout; - std::vector vertices; - std::vector triangles; + gl::VertexVector vertices; + gl::IndexVector triangles; std::vector segments; optional> vertexBuffer; - optional> indexBuffer; + optional> indexBuffer; private: struct TriangleElement { diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 084879426a4..3be3e5670a2 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -42,30 +42,44 @@ namespace mbgl { using namespace style; -Painter::Painter(gl::Context& context_, const TransformState& state_) - : context(context_), - state(state_), - tileTriangleVertexBuffer(context.createVertexBuffer(std::vector {{ +static gl::VertexVector tileTriangles() { + gl::VertexVector result; + result.emplace_back( 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 {{ - FillAttributes::vertex({ 0, 0 }), + FillAttributes::vertex({ 0, util::EXTENT })); + result.emplace_back( 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 {{ - 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 }) - }})) { + FillAttributes::vertex({ util::EXTENT, util::EXTENT })); + return result; +} + +static gl::VertexVector tileLineStrip() { + gl::VertexVector 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 rasterTriangleStrip() { + gl::VertexVector 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(tileTriangles())), + tileLineStripVertexBuffer(context.createVertexBuffer(tileLineStrip())), + rasterVertexBuffer(context.createVertexBuffer(rasterTriangleStrip())) { #ifndef NDEBUG gl::debugging::enable(); #endif diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 53215c5033c..3f5f28dad1f 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -156,9 +156,9 @@ class Painter : private util::noncopyable { std::unique_ptr overdrawPrograms; #endif - gl::VertexBuffer tileTriangleVertexBuffer; - gl::VertexBuffer tileLineStripVertexBuffer; - gl::VertexBuffer rasterVertexBuffer; + gl::VertexBuffer tileTriangleVertexBuffer; + gl::VertexBuffer tileLineStripVertexBuffer; + gl::VertexBuffer rasterVertexBuffer; }; } // namespace mbgl diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index 0dd8b63e586..adb0bd17110 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -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(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, FillUniforms::values( matrixForTile(tileID), properties.backgroundOpacity.value, @@ -60,8 +62,8 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye properties.backgroundColor.value, context.viewport.getCurrentValue().size ), - gl::Unindexed(tileTriangleVertexBuffer) - }); + tileTriangleVertexBuffer + ); } } } diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index 5679aa314e0..ea4ea5964d7 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -22,13 +22,14 @@ void Painter::renderCircle(PaintParameters& parameters, const CirclePaintProperties& properties = layer.impl->paint; - 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( tile.translatedMatrix(properties.circleTranslate.value, properties.circleTranslateAnchor.value, @@ -46,12 +47,10 @@ void Painter::renderCircle(PaintParameters& parameters, : pixelsToGLUnits, frame.pixelRatio ), - gl::Segmented( - *bucket.vertexBuffer, - *bucket.indexBuffer, - bucket.segments - ) - }); + *bucket.vertexBuffer, + *bucket.indexBuffer, + bucket.segments + ); } } // namespace mbgl diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index ba860cee962..df73cb6e61c 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -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, FillUniforms::values( matrixForTile(tileID), 0.0f, @@ -25,8 +26,8 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl Color {}, context.viewport.getCurrentValue().size ), - gl::Unindexed(tileTriangleVertexBuffer) - }); + tileTriangleVertexBuffer + ); } } // namespace mbgl diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index ff9067a70ca..4a7a9ff27dc 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -19,21 +19,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, - FillUniforms::values( + DebugProgram::UniformValues( renderTile.matrix, - 1.0f, - color, - color, - context.viewport.getCurrentValue().size + color ), - subject - }); + vertexBuffer + ); }; if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) { @@ -48,15 +46,12 @@ void Painter::renderTileDebug(const RenderTile& renderTile) { tile.expires, frame.debugOptions, context); } - const auto& vertexBuffer = tile.debugBucket->vertexBuffer; - - draw(Color::white(), gl::Unindexed(vertexBuffer, 4.0f * frame.pixelRatio)); - draw(Color::black(), gl::Unindexed(vertexBuffer, 2.0f)); - draw(Color::black(), gl::Unindexed(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(tileLineStripVertexBuffer, 4.0f * frame.pixelRatio)); + draw(Color::red(), tileLineStripVertexBuffer, gl::LineStrip { 4.0f * frame.pixelRatio }); } } diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index a8f37d4bb26..8a166f23776 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -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( - *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( - *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, FillUniforms::values( tile.translatedMatrix(properties.fillTranslate.value, properties.fillTranslateAnchor.value, @@ -91,19 +105,20 @@ void Painter::renderFill(PaintParameters& parameters, outlineColor, 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( - *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( - *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( - *bucket.vertexBuffer, - *bucket.lineIndexBuffer, - bucket.lineSegments, - 2.0f)); + gl::Lines { 2.0f }, + *bucket.vertexBuffer, + *bucket.lineIndexBuffer, + bucket.lineSegments); } } } diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 7f9556fd3fa..a495edc428a 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -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( - *bucket.vertexBuffer, - *bucket.indexBuffer, - bucket.segments - ) - }); + *bucket.vertexBuffer, + *bucket.indexBuffer, + bucket.segments + ); }; if (!properties.lineDasharray.value.from.empty()) { diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index da76558cab7..ff4fac49a92 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -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( tile.matrix, 0, @@ -74,8 +75,8 @@ void Painter::renderRaster(PaintParameters& parameters, 1.0f, std::array {{ 0.0f, 0.0f }} ), - gl::Unindexed(rasterVertexBuffer) - }); + rasterVertexBuffer + ); } } // namespace mbgl diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index aedede18b38..7813d96b9f3 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -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( - *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( tile.matrix, std::pow(2.0f, state.getZoom() - tile.tile.id.overscaledZ), state.getZoom() * 10, (tile.id.canonical.z + 1) * 10 ), - gl::Unindexed( - *bucket.collisionBox.vertexBuffer, - 1.0f - ) - }); + *bucket.collisionBox.vertexBuffer + ); } } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index d33341008e6..f1fc3d324e1 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -34,26 +34,26 @@ class SymbolBucket : public Bucket { const bool iconsNeedLinear; struct TextBuffer { - std::vector vertices; - std::vector triangles; + gl::VertexVector vertices; + gl::IndexVector triangles; std::vector segments; optional> vertexBuffer; - optional> indexBuffer; + optional> indexBuffer; } text; struct IconBuffer { - std::vector vertices; - std::vector triangles; + gl::VertexVector vertices; + gl::IndexVector triangles; std::vector segments; optional> vertexBuffer; - optional> indexBuffer; + optional> indexBuffer; } icon; struct CollisionBoxBuffer { - std::vector vertices; - optional> vertexBuffer; + gl::VertexVector vertices; + optional> vertexBuffer; } collisionBox; }; diff --git a/src/mbgl/util/ignore.hpp b/src/mbgl/util/ignore.hpp new file mode 100644 index 00000000000..31cd092c0ef --- /dev/null +++ b/src/mbgl/util/ignore.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +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 void ignore(Ts&&...) {} + +// std::initializer_list overload, for situations where you need sequenced +// modifications. +// +template void ignore(const std::initializer_list&) {} + +} // namespace mbgl