diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-11-07 12:26:05 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-11-08 08:09:29 -0800 |
commit | 1db2ffbc1b69069eca39f786cacc45dbb02c3052 (patch) | |
tree | 9d6ed2a7302492f41c52ea3fdeadabf6466b0d8d /src | |
parent | 66bdbc3b969083b9d647abdf72784be64a125949 (diff) | |
download | qtlocation-mapboxgl-1db2ffbc1b69069eca39f786cacc45dbb02c3052.tar.gz |
[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.
Diffstat (limited to 'src')
41 files changed, 470 insertions, 358 deletions
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 126da38de5..a2b165fa21 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -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 diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index b12c77c1a1..c4485ad0fd 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -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), diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 2a3fbea33d..154921a1b9 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -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&); diff --git a/src/mbgl/gl/draw_mode.hpp b/src/mbgl/gl/draw_mode.hpp index a379162210..8f7db0a3fa 100644 --- a/src/mbgl/gl/draw_mode.hpp +++ b/src/mbgl/gl/draw_mode.hpp @@ -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, diff --git a/src/mbgl/gl/drawable.hpp b/src/mbgl/gl/drawable.hpp deleted file mode 100644 index 747d8facf0..0000000000 --- a/src/mbgl/gl/drawable.hpp +++ /dev/null @@ -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 diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp index 5d8630b902..8b40bf68c3 100644 --- a/src/mbgl/gl/index_buffer.hpp +++ b/src/mbgl/gl/index_buffer.hpp @@ -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; - - 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 <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)...}); + } -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<uint16_t> v; }; -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; }; diff --git a/src/mbgl/gl/primitives.hpp b/src/mbgl/gl/primitives.hpp new file mode 100644 index 0000000000..fe6b1b2e5b --- /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 ea4dbcc1df..929237037b 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -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; diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp index 648d02e902..f65f2a5f7e 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 90ca16e46f..df4de0c75a 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -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 diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp index c77a9a4213..9d5532beab 100644 --- a/src/mbgl/gl/vertex_buffer.hpp +++ b/src/mbgl/gl/vertex_buffer.hpp @@ -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; }; diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index c2f8426785..932745aa57 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<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); diff --git a/src/mbgl/programs/circle_program.hpp b/src/mbgl/programs/circle_program.hpp index 690608a438..75c030b1c8 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 66b1284621..5eda3fefb0 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 0000000000..3596dc1f7e --- /dev/null +++ b/src/mbgl/programs/debug_program.hpp @@ -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 diff --git a/src/mbgl/programs/fill_program.hpp b/src/mbgl/programs/fill_program.hpp index 3f738527c8..d885215c59 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 960438f4cd..07ae35b8ed 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 @@ 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, diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 9f154b051a..fa41d43e5c 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 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) { diff --git a/src/mbgl/programs/programs.hpp b/src/mbgl/programs/programs.hpp index aebafaec62..53ed26e969 100644 --- a/src/mbgl/programs/programs.hpp +++ b/src/mbgl/programs/programs.hpp @@ -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; }; diff --git a/src/mbgl/programs/raster_program.hpp b/src/mbgl/programs/raster_program.hpp index 1e9a0cdb6a..1bab2d5765 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 eb8c56b326..be987551c0 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 @@ public: 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 08f2a144a1..ba2285c4eb 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<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; } } } diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index d5df06f110..a93b052d68 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -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; }; diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp index 931d1bf30d..4beb16a996 100644 --- a/src/mbgl/renderer/debug_bucket.cpp +++ b/src/mbgl/renderer/debug_bucket.cpp @@ -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, diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp index 9b19e7f949..4c173786ae 100644 --- a/src/mbgl/renderer/debug_bucket.hpp +++ b/src/mbgl/renderer/debug_bucket.hpp @@ -32,7 +32,7 @@ public: const optional<Timestamp> expires; const MapDebugOptions debugMode; - gl::VertexBuffer<FillVertex> vertexBuffer; + gl::VertexBuffer<FillVertex, gl::Lines> vertexBuffer; }; } // namespace mbgl diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 2eee8f2d6d..96e44d6903 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -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; } } diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index b2c549a758..4ea558b629 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -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 diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 1db075652c..554fef5ca7 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<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); } diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 4d78a80123..9903ca1842 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -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 { diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index d9e7f9fd35..a09e3b73fc 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -41,30 +41,44 @@ namespace mbgl { using namespace style; -Painter::Painter(gl::Context& context_, const TransformState& state_) - : context(context_), - state(state_), - tileTriangleVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{ +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 }), - 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({ 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<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 }) - }})) { + 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(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 53215c5033..3f5f28dad1 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -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 diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index 3e2597e47c..5e71cb7b20 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<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 + ); } } } diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index e4977b8abb..e9c828bcd8 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -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 diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index b64c5d5efc..2054424475 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, 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 diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index a0fc98b8c1..8969354d23 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -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 }); } } diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index cdce181e1c..e5a536fde3 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<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); } } } diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 7f9556fd3f..a495edc428 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<gl::Triangles>( - *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 c619cad2aa..e19cde289a 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 { 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 diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 2f94544486..d2dee5d99d 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<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 + ); } } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index d33341008e..f1fc3d324e 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -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; }; diff --git a/src/mbgl/util/ignore.hpp b/src/mbgl/util/ignore.hpp new file mode 100644 index 0000000000..31cd092c0e --- /dev/null +++ b/src/mbgl/util/ignore.hpp @@ -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 |