diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-10-02 17:43:51 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-10-05 10:52:19 -0700 |
commit | e4310aa87489c2db52d7ff65f71e51cc6c9700b6 (patch) | |
tree | 438e67108779aac6f8787ef7b03644534955bf1f | |
parent | b9b8657d43aa1172e9ca6be162e915006806ee57 (diff) | |
download | qtlocation-mapboxgl-e4310aa87489c2db52d7ff65f71e51cc6c9700b6.tar.gz |
[core] Improve attribute binding API
45 files changed, 258 insertions, 235 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 44a79dc0fb..119379c25d 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -56,6 +56,7 @@ set(MBGL_CORE_FILES # gl include/mbgl/gl/gl.hpp + src/mbgl/gl/attribute.hpp src/mbgl/gl/context.cpp src/mbgl/gl/context.hpp src/mbgl/gl/debugging.cpp diff --git a/include/mbgl/gl/gl.hpp b/include/mbgl/gl/gl.hpp index c826e1f4e8..b3c2d83a5e 100644 --- a/include/mbgl/gl/gl.hpp +++ b/include/mbgl/gl/gl.hpp @@ -1,9 +1,6 @@ #pragma once -#include <mbgl/gl/types.hpp> - #include <stdexcept> -#include <type_traits> #include <limits> #if __APPLE__ @@ -46,34 +43,5 @@ void checkError(const char *cmd, const char *file, int line); #define MBGL_CHECK_ERROR(cmd) (cmd) #endif -template <typename T> struct AttributeType; - -template <> struct AttributeType<int8_t> : std::integral_constant<GLenum, GL_BYTE> {}; -template <> struct AttributeType<uint8_t> : std::integral_constant<GLenum, GL_UNSIGNED_BYTE> {}; -template <> struct AttributeType<int16_t> : std::integral_constant<GLenum, GL_SHORT> {}; -template <> struct AttributeType<uint16_t> : std::integral_constant<GLenum, GL_UNSIGNED_SHORT> {}; -template <> struct AttributeType<int32_t> : std::integral_constant<GLenum, GL_INT> {}; -template <> struct AttributeType<uint32_t> : std::integral_constant<GLenum, GL_UNSIGNED_INT> {}; -template <> struct AttributeType<float> : std::integral_constant<GLenum, GL_FLOAT> {}; - -template <std::size_t memberOffset, class V, class E, std::size_t N> -void bindVertexAttribute(AttributeLocation location, const E (V::*)[N], const int8_t* offset) { - static_assert(std::is_standard_layout<V>::value, "vertex type must use standard layout"); - static_assert(memberOffset % 4 == 0, "vertex attribute must be optimally aligned"); - static_assert(1 <= N && N <= 4, "count must be 1, 2, 3, or 4"); - static_assert(sizeof(V) <= std::numeric_limits<GLsizei>::max(), "vertex type is too big"); - MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttribPointer(location, - static_cast<GLint>(N), - AttributeType<E>::value, - false, - static_cast<GLsizei>(sizeof(V)), - offset + memberOffset)); -} - -// This has to be a macro because it uses the offsetof macro, which is the only legal way to get a member offset. -#define MBGL_BIND_VERTEX_ATTRIBUTE(VertexType, member, offset) \ - ::mbgl::gl::bindVertexAttribute<offsetof(VertexType, member)>(gl::Shader::member, &VertexType::member, offset) - } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp new file mode 100644 index 0000000000..8bc474e967 --- /dev/null +++ b/src/mbgl/gl/attribute.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include <mbgl/gl/types.hpp> +#include <mbgl/gl/shader.hpp> + +#include <cstddef> +#include <limits> +#include <vector> + +namespace mbgl { +namespace gl { + +template <typename T, std::size_t N> +class Attribute { +public: + Attribute(const char* name, const Shader& shader) + : location(shader.getAttributeLocation(name)) {} + + AttributeLocation location; +}; + +class AttributeBinding { +public: + template <class Vertex, class T, std::size_t N, std::size_t O> + AttributeBinding(const T (Vertex::*)[N], const Attribute<T, N>& attribute, std::integral_constant<std::size_t, O>) + : location(attribute.location), + type(DataTypeOf<T>::value), + count(N), + offset(O) { + static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout"); + static_assert(O % 4 == 0, "vertex attribute must be optimally aligned"); + static_assert(1 <= N && N <= 4, "count must be 1, 2, 3, or 4"); + static_assert(sizeof(Vertex) <= std::numeric_limits<int32_t>::max(), "vertex type is too big"); + } + + AttributeLocation location; + DataType type; + uint8_t count; + std::size_t offset; +}; + +#define MBGL_MAKE_ATTRIBUTE_BINDING(Vertex, shader, name) \ + ::mbgl::gl::AttributeBinding(&Vertex::name, \ + shader.name, \ + std::integral_constant<std::size_t, offsetof(Vertex, name)>()) + +template <class Shader, class Vertex> struct AttributeBindings; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 5837aa3399..2a04fcc18e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -109,6 +109,16 @@ UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) { return result; } +void Context::bindAttribute(const AttributeBinding& binding, std::size_t stride, const int8_t* offset) { + MBGL_CHECK_ERROR(glEnableVertexAttribArray(binding.location)); + MBGL_CHECK_ERROR(glVertexAttribPointer(binding.location, + binding.count, + static_cast<GLenum>(binding.type), + false, + static_cast<GLsizei>(stride), + offset + binding.offset)); +} + UniqueTexture Context::createTexture() { if (pooledTextures.empty()) { pooledTextures.resize(TextureMax); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index e26b35e7c0..6a5d44793a 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -6,6 +6,7 @@ #include <mbgl/gl/texture.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/util/noncopyable.hpp> #include <memory> @@ -60,6 +61,14 @@ public: TextureFilter = TextureFilter::Nearest, TextureMipMap = TextureMipMap::No); + template <class Shader, class Vertex> + void bindAttributes(const Shader& shader, const VertexBuffer<Vertex>&, const int8_t* offset) { + static_assert(std::is_same<typename Shader::VertexType, Vertex>::value, "vertex type mismatch"); + for (const auto& binding : AttributeBindings<Shader, Vertex>()(shader)) { + bindAttribute(binding, sizeof(Vertex), offset); + } + } + // Actually remove the objects we marked as abandoned with the above methods. // Only call this while the OpenGL context is exclusive to this thread. void performCleanup(); @@ -115,6 +124,7 @@ private: UniqueBuffer createVertexBuffer(const void* data, std::size_t size); UniqueBuffer createIndexBuffer(const void* data, std::size_t size); UniqueTexture createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit); + void bindAttribute(const AttributeBinding&, std::size_t stride, const int8_t* offset); friend detail::ProgramDeleter; friend detail::ShaderDeleter; diff --git a/src/mbgl/gl/shader.cpp b/src/mbgl/gl/shader.cpp index 5b3712e80d..d8ee734567 100644 --- a/src/mbgl/gl/shader.cpp +++ b/src/mbgl/gl/shader.cpp @@ -48,13 +48,6 @@ Shader::Shader(const char* name_, MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get())); MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get())); - // Bind attribute variables - MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_pos, "a_pos")); - MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_extrude, "a_extrude")); - MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_offset, "a_offset")); - MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data, "a_data")); - MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_texture_pos, "a_texture_pos")); - // Link program GLint status; MBGL_CHECK_ERROR(glLinkProgram(program.get())); @@ -112,5 +105,9 @@ UniformLocation Shader::getUniformLocation(const char* uniform) const { return MBGL_CHECK_ERROR(glGetUniformLocation(program.get(), uniform)); } +AttributeLocation Shader::getAttributeLocation(const char* attribute) const { + return MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), attribute)); +} + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/shader.hpp b/src/mbgl/gl/shader.hpp index f73400bc15..f88bd4f867 100644 --- a/src/mbgl/gl/shader.hpp +++ b/src/mbgl/gl/shader.hpp @@ -18,6 +18,7 @@ public: return program.get(); } + AttributeLocation getAttributeLocation(const char* uniform) const; UniformLocation getUniformLocation(const char* uniform) const; enum Defines : bool { @@ -32,13 +33,6 @@ protected: Context&, Defines defines = Defines::None); -public: - static constexpr AttributeLocation a_pos = 0; - static constexpr AttributeLocation a_extrude = 1; - static constexpr AttributeLocation a_offset = 2; - static constexpr AttributeLocation a_data = 3; - static constexpr AttributeLocation a_texture_pos = 4; - private: bool compileShader(UniqueShader&, const char *source); diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index e9d14e4807..f24674457a 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -1,6 +1,7 @@ #pragma once #include <cstdint> +#include <type_traits> namespace mbgl { namespace gl { @@ -22,6 +23,26 @@ using DepthValue = double; using StencilValue = int32_t; using StencilMaskValue = uint32_t; +enum class DataType : uint32_t { + Byte = 0x1400, + UnsignedByte = 0x1401, + Short = 0x1402, + UnsignedShort = 0x1403, + Integer = 0x1404, + UnsignedInteger = 0x1405, + Float = 0x1406 +}; + +template <typename T> struct DataTypeOf; + +template <> struct DataTypeOf<int8_t> : std::integral_constant<DataType, DataType::Byte> {}; +template <> struct DataTypeOf<uint8_t> : std::integral_constant<DataType, DataType::UnsignedByte> {}; +template <> struct DataTypeOf<int16_t> : std::integral_constant<DataType, DataType::Short> {}; +template <> struct DataTypeOf<uint16_t> : std::integral_constant<DataType, DataType::UnsignedShort> {}; +template <> struct DataTypeOf<int32_t> : std::integral_constant<DataType, DataType::Integer> {}; +template <> struct DataTypeOf<uint32_t> : std::integral_constant<DataType, DataType::UnsignedInteger> {}; +template <> struct DataTypeOf<float> : std::integral_constant<DataType, DataType::Float> {}; + enum class BufferType : uint32_t { Vertex = 0x8892, Element = 0x8893 diff --git a/src/mbgl/gl/vao.hpp b/src/mbgl/gl/vao.hpp index 3fe307ed4d..6a5e7d0e60 100644 --- a/src/mbgl/gl/vao.hpp +++ b/src/mbgl/gl/vao.hpp @@ -24,7 +24,7 @@ public: bindVertexArrayObject(context); if (bound_shader == 0) { context.vertexBuffer = vertexBuffer.buffer; - shader.bind(vertexBuffer, offset); + context.bindAttributes(shader, vertexBuffer, offset); if (vertexArray) { storeBinding(shader, vertexBuffer.buffer, 0, offset); } @@ -43,7 +43,7 @@ public: if (bound_shader == 0) { context.vertexBuffer = vertexBuffer.buffer; context.elementBuffer = indexBuffer.buffer; - shader.bind(vertexBuffer, offset); + context.bindAttributes(shader, vertexBuffer, offset); if (vertexArray) { storeBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset); } diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp index 5ad6a73a1a..9e294f8d76 100644 --- a/src/mbgl/shader/circle_shader.cpp +++ b/src/mbgl/shader/circle_shader.cpp @@ -12,9 +12,4 @@ CircleShader::CircleShader(gl::Context& context, Defines defines) context, defines) { } -void CircleShader::bind(const gl::VertexBuffer<CircleVertex>&, - const int8_t* offset) { - CircleVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp index 99f099800d..c2c4053ba4 100644 --- a/src/mbgl/shader/circle_shader.hpp +++ b/src/mbgl/shader/circle_shader.hpp @@ -1,23 +1,21 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> #include <mbgl/util/color.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class CircleVertex; class CircleShader : public gl::Shader { public: CircleShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<CircleVertex>&, - const int8_t* offset); + using VertexType = CircleVertex; + + gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this}; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this}; diff --git a/src/mbgl/shader/circle_vertex.cpp b/src/mbgl/shader/circle_vertex.cpp index e449734ca4..8beb88e650 100644 --- a/src/mbgl/shader/circle_vertex.cpp +++ b/src/mbgl/shader/circle_vertex.cpp @@ -1,13 +1,7 @@ #include <mbgl/shader/circle_vertex.hpp> -#include <mbgl/gl/shader.hpp> -#include <mbgl/gl/gl.hpp> namespace mbgl { -void CircleVertex::bind(const int8_t* offset) { - static_assert(sizeof(CircleVertex) == 4, "expected CircleVertex size"); - - MBGL_BIND_VERTEX_ATTRIBUTE(CircleVertex, a_pos, offset); -} +static_assert(sizeof(CircleVertex) == 4, "expected CircleVertex size"); } // namespace mbgl diff --git a/src/mbgl/shader/circle_vertex.hpp b/src/mbgl/shader/circle_vertex.hpp index 8b4e37431b..4fce49f137 100644 --- a/src/mbgl/shader/circle_vertex.hpp +++ b/src/mbgl/shader/circle_vertex.hpp @@ -1,5 +1,8 @@ #pragma once +#include <mbgl/gl/attribute.hpp> + +#include <array> #include <cstdint> namespace mbgl { @@ -19,8 +22,18 @@ public: } {} const int16_t a_pos[2]; +}; + +namespace gl { - static void bind(const int8_t* offset); +template <class Shader> +struct AttributeBindings<Shader, CircleVertex> { + std::array<AttributeBinding, 1> operator()(const Shader& shader) { + return {{ + MBGL_MAKE_ATTRIBUTE_BINDING(CircleVertex, shader, a_pos) + }}; + }; }; +} // namespace gl } // namespace mbgl diff --git a/src/mbgl/shader/collision_box_shader.cpp b/src/mbgl/shader/collision_box_shader.cpp index 8fed895c86..a53821072d 100644 --- a/src/mbgl/shader/collision_box_shader.cpp +++ b/src/mbgl/shader/collision_box_shader.cpp @@ -12,9 +12,4 @@ CollisionBoxShader::CollisionBoxShader(gl::Context& context) context) { } -void CollisionBoxShader::bind(const gl::VertexBuffer<CollisionBoxVertex>&, - const int8_t* offset) { - CollisionBoxVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/collision_box_shader.hpp b/src/mbgl/shader/collision_box_shader.hpp index 7248193a21..2f5c506168 100644 --- a/src/mbgl/shader/collision_box_shader.hpp +++ b/src/mbgl/shader/collision_box_shader.hpp @@ -1,22 +1,22 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class CollisionBoxVertex; class CollisionBoxShader : public gl::Shader { public: CollisionBoxShader(gl::Context&); - void bind(const gl::VertexBuffer<CollisionBoxVertex>&, - const int8_t* offset); + using VertexType = CollisionBoxVertex; + + gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this}; + gl::Attribute<int16_t, 2> a_extrude = {"a_extrude", *this}; + gl::Attribute<uint8_t, 2> a_data = {"a_data", *this}; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<float> u_scale = {"u_scale", *this}; diff --git a/src/mbgl/shader/collision_box_vertex.cpp b/src/mbgl/shader/collision_box_vertex.cpp index 0295a78b55..397fbfe6a3 100644 --- a/src/mbgl/shader/collision_box_vertex.cpp +++ b/src/mbgl/shader/collision_box_vertex.cpp @@ -1,15 +1,7 @@ #include <mbgl/shader/collision_box_vertex.hpp> -#include <mbgl/gl/shader.hpp> -#include <mbgl/gl/gl.hpp> namespace mbgl { -void CollisionBoxVertex::bind(const int8_t* offset) { - static_assert(sizeof(CollisionBoxVertex) == 10, "expected CollisionBoxVertex size"); - - MBGL_BIND_VERTEX_ATTRIBUTE(CollisionBoxVertex, a_pos, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(CollisionBoxVertex, a_extrude, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(CollisionBoxVertex, a_data, offset); -} +static_assert(sizeof(CollisionBoxVertex) == 10, "expected CollisionBoxVertex size"); } // namespace mbgl diff --git a/src/mbgl/shader/collision_box_vertex.hpp b/src/mbgl/shader/collision_box_vertex.hpp index f591a64ca1..ba72b1c0ee 100644 --- a/src/mbgl/shader/collision_box_vertex.hpp +++ b/src/mbgl/shader/collision_box_vertex.hpp @@ -1,5 +1,8 @@ #pragma once +#include <mbgl/gl/attribute.hpp> + +#include <array> #include <cstdint> #include <cmath> @@ -21,8 +24,20 @@ public: const int16_t a_pos[2]; const int16_t a_extrude[2]; const uint8_t a_data[2]; +}; + +namespace gl { - static void bind(const int8_t* offset); +template <class Shader> +struct AttributeBindings<Shader, CollisionBoxVertex> { + std::array<AttributeBinding, 3> operator()(const Shader& shader) { + return {{ + MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_pos), + MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_extrude), + MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_data) + }}; + }; }; +} // namespace gl } // namespace mbgl diff --git a/src/mbgl/shader/icon_shader.cpp b/src/mbgl/shader/icon_shader.cpp index 520c987768..5ae6e10e0f 100644 --- a/src/mbgl/shader/icon_shader.cpp +++ b/src/mbgl/shader/icon_shader.cpp @@ -12,9 +12,4 @@ IconShader::IconShader(gl::Context& context, Defines defines) context, defines) { } -void IconShader::bind(const gl::VertexBuffer<TextureRectVertex>&, - const int8_t* offset) { - TextureRectVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/icon_shader.hpp b/src/mbgl/shader/icon_shader.hpp index 9c7d073683..ee5a5114c7 100644 --- a/src/mbgl/shader/icon_shader.hpp +++ b/src/mbgl/shader/icon_shader.hpp @@ -1,22 +1,23 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class TextureRectVertex; class IconShader : public gl::Shader { public: IconShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<TextureRectVertex>&, - const int8_t* offset); + using VertexType = TextureRectVertex; + + gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this }; + gl::Attribute<int16_t, 2> a_offset = { "a_offset", *this }; + gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this }; + gl::Attribute<uint8_t, 4> a_data = { "a_data", *this }; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this}; diff --git a/src/mbgl/shader/line_shader.cpp b/src/mbgl/shader/line_shader.cpp index 866c814384..4e934cd60c 100644 --- a/src/mbgl/shader/line_shader.cpp +++ b/src/mbgl/shader/line_shader.cpp @@ -12,9 +12,4 @@ LineShader::LineShader(gl::Context& context, Defines defines) context, defines) { } -void LineShader::bind(const gl::VertexBuffer<LineVertex>&, - const int8_t* offset) { - LineVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp index 74ca7f16df..79991e1883 100644 --- a/src/mbgl/shader/line_shader.hpp +++ b/src/mbgl/shader/line_shader.hpp @@ -1,23 +1,22 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> #include <mbgl/util/color.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class LineVertex; class LineShader : public gl::Shader { public: LineShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<LineVertex>&, - const int8_t* offset); + using VertexType = LineVertex; + + gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this }; + gl::Attribute<uint8_t, 4> a_data = { "a_data", *this }; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<Color> u_color = {"u_color", *this}; diff --git a/src/mbgl/shader/line_vertex.cpp b/src/mbgl/shader/line_vertex.cpp index c40c60e9f6..ad466310d8 100644 --- a/src/mbgl/shader/line_vertex.cpp +++ b/src/mbgl/shader/line_vertex.cpp @@ -1,14 +1,7 @@ #include <mbgl/shader/line_vertex.hpp> -#include <mbgl/gl/shader.hpp> -#include <mbgl/gl/gl.hpp> namespace mbgl { -void LineVertex::bind(const int8_t* offset) { - static_assert(sizeof(LineVertex) == 8, "expected LineVertex size"); - - MBGL_BIND_VERTEX_ATTRIBUTE(LineVertex, a_pos, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(LineVertex, a_data, offset); -} +static_assert(sizeof(LineVertex) == 8, "expected LineVertex size"); } // namespace mbgl diff --git a/src/mbgl/shader/line_vertex.hpp b/src/mbgl/shader/line_vertex.hpp index 8a85397539..086100810e 100644 --- a/src/mbgl/shader/line_vertex.hpp +++ b/src/mbgl/shader/line_vertex.hpp @@ -1,5 +1,8 @@ #pragma once +#include <mbgl/gl/attribute.hpp> + +#include <array> #include <cstdint> #include <cmath> @@ -51,8 +54,19 @@ public: * the acute/bevelled line join. */ static const int8_t extrudeScale = 63; +}; + +namespace gl { - static void bind(const int8_t* offset); +template <class Shader> +struct AttributeBindings<Shader, LineVertex> { + std::array<AttributeBinding, 2> operator()(const Shader& shader) { + return {{ + MBGL_MAKE_ATTRIBUTE_BINDING(LineVertex, shader, a_pos), + MBGL_MAKE_ATTRIBUTE_BINDING(LineVertex, shader, a_data) + }}; + }; }; +} // namespace gl } // namespace mbgl diff --git a/src/mbgl/shader/linepattern_shader.cpp b/src/mbgl/shader/linepattern_shader.cpp index 86f58d9d99..0f3fb415ac 100644 --- a/src/mbgl/shader/linepattern_shader.cpp +++ b/src/mbgl/shader/linepattern_shader.cpp @@ -12,9 +12,4 @@ LinepatternShader::LinepatternShader(gl::Context& context, Defines defines) context, defines) { } -void LinepatternShader::bind(const gl::VertexBuffer<LineVertex>&, - const int8_t* offset) { - LineVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp index 94b4916f25..22ee32564f 100644 --- a/src/mbgl/shader/linepattern_shader.hpp +++ b/src/mbgl/shader/linepattern_shader.hpp @@ -2,21 +2,20 @@ #include <mbgl/gl/shader.hpp> #include <mbgl/gl/uniform.hpp> +#include <mbgl/gl/attribute.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class LineVertex; class LinepatternShader : public gl::Shader { public: LinepatternShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<LineVertex>&, - const int8_t* offset); + using VertexType = LineVertex; + + gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this }; + gl::Attribute<uint8_t, 4> a_data = { "a_data", *this }; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<float> u_linewidth = {"u_linewidth", *this}; diff --git a/src/mbgl/shader/linesdf_shader.cpp b/src/mbgl/shader/linesdf_shader.cpp index 5245bc71f4..507c0f9499 100644 --- a/src/mbgl/shader/linesdf_shader.cpp +++ b/src/mbgl/shader/linesdf_shader.cpp @@ -12,9 +12,4 @@ LineSDFShader::LineSDFShader(gl::Context& context, Defines defines) context, defines) { } -void LineSDFShader::bind(const gl::VertexBuffer<LineVertex>&, - const int8_t* offset) { - LineVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp index 41ad8dc22a..d74e42e50f 100644 --- a/src/mbgl/shader/linesdf_shader.hpp +++ b/src/mbgl/shader/linesdf_shader.hpp @@ -1,23 +1,22 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> #include <mbgl/util/color.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class LineVertex; class LineSDFShader : public gl::Shader { public: LineSDFShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<LineVertex>&, - const int8_t* offset); + using VertexType = LineVertex; + + gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this }; + gl::Attribute<uint8_t, 4> a_data = { "a_data", *this }; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<Color> u_color = {"u_color", *this}; diff --git a/src/mbgl/shader/outline_shader.cpp b/src/mbgl/shader/outline_shader.cpp index 3f7642b2c9..5566a343e3 100644 --- a/src/mbgl/shader/outline_shader.cpp +++ b/src/mbgl/shader/outline_shader.cpp @@ -12,9 +12,4 @@ OutlineShader::OutlineShader(gl::Context& context, Defines defines) context, defines) { } -void OutlineShader::bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset) { - PlainVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/outline_shader.hpp b/src/mbgl/shader/outline_shader.hpp index 50e7a2dfc2..f9a3456864 100644 --- a/src/mbgl/shader/outline_shader.hpp +++ b/src/mbgl/shader/outline_shader.hpp @@ -1,23 +1,21 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> #include <mbgl/util/color.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class PlainVertex; class OutlineShader : public gl::Shader { public: OutlineShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset); + using VertexType = PlainVertex; + + gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this}; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<Color> u_outline_color = {"u_outline_color", *this}; diff --git a/src/mbgl/shader/outlinepattern_shader.cpp b/src/mbgl/shader/outlinepattern_shader.cpp index afe375f377..1b2c4ac894 100644 --- a/src/mbgl/shader/outlinepattern_shader.cpp +++ b/src/mbgl/shader/outlinepattern_shader.cpp @@ -12,9 +12,4 @@ OutlinePatternShader::OutlinePatternShader(gl::Context& context, Defines defines context, defines) { } -void OutlinePatternShader::bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset) { - PlainVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/outlinepattern_shader.hpp b/src/mbgl/shader/outlinepattern_shader.hpp index cb47f8731b..9e9c47e7a9 100644 --- a/src/mbgl/shader/outlinepattern_shader.hpp +++ b/src/mbgl/shader/outlinepattern_shader.hpp @@ -1,22 +1,20 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class PlainVertex; class OutlinePatternShader : public gl::Shader { public: OutlinePatternShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset); + using VertexType = PlainVertex; + + gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this}; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this}; diff --git a/src/mbgl/shader/pattern_shader.cpp b/src/mbgl/shader/pattern_shader.cpp index 632775c181..89600bb54d 100644 --- a/src/mbgl/shader/pattern_shader.cpp +++ b/src/mbgl/shader/pattern_shader.cpp @@ -12,9 +12,4 @@ PatternShader::PatternShader(gl::Context& context, Defines defines) context, defines) { } -void PatternShader::bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset) { - PlainVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp index f036a4849d..8d06bb2962 100644 --- a/src/mbgl/shader/pattern_shader.hpp +++ b/src/mbgl/shader/pattern_shader.hpp @@ -1,22 +1,20 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class PlainVertex; class PatternShader : public gl::Shader { public: PatternShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset); + using VertexType = PlainVertex; + + gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this}; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this}; diff --git a/src/mbgl/shader/plain_shader.cpp b/src/mbgl/shader/plain_shader.cpp index a6dce02a32..03ba9a4c8f 100644 --- a/src/mbgl/shader/plain_shader.cpp +++ b/src/mbgl/shader/plain_shader.cpp @@ -12,9 +12,4 @@ PlainShader::PlainShader(gl::Context& context, Defines defines) context, defines) { } -void PlainShader::bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset) { - PlainVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/plain_shader.hpp b/src/mbgl/shader/plain_shader.hpp index 64cca095d8..b7173d0943 100644 --- a/src/mbgl/shader/plain_shader.hpp +++ b/src/mbgl/shader/plain_shader.hpp @@ -1,23 +1,21 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> #include <mbgl/util/color.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class PlainVertex; class PlainShader : public gl::Shader { public: PlainShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<PlainVertex>&, - const int8_t* offset); + using VertexType = PlainVertex; + + gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this}; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<Color> u_color = {"u_color", *this}; diff --git a/src/mbgl/shader/plain_vertex.cpp b/src/mbgl/shader/plain_vertex.cpp index 85a97a9827..5f0c71497a 100644 --- a/src/mbgl/shader/plain_vertex.cpp +++ b/src/mbgl/shader/plain_vertex.cpp @@ -1,13 +1,7 @@ #include <mbgl/shader/plain_vertex.hpp> -#include <mbgl/gl/shader.hpp> -#include <mbgl/gl/gl.hpp> namespace mbgl { -void PlainVertex::bind(const int8_t* offset) { - static_assert(sizeof(PlainVertex) == 4, "expected PlainVertex size"); - - MBGL_BIND_VERTEX_ATTRIBUTE(PlainVertex, a_pos, offset); -} +static_assert(sizeof(PlainVertex) == 4, "expected PlainVertex size"); } // namespace mbgl diff --git a/src/mbgl/shader/plain_vertex.hpp b/src/mbgl/shader/plain_vertex.hpp index 46abbf737c..0d164d1267 100644 --- a/src/mbgl/shader/plain_vertex.hpp +++ b/src/mbgl/shader/plain_vertex.hpp @@ -1,5 +1,8 @@ #pragma once +#include <mbgl/gl/attribute.hpp> + +#include <array> #include <cstdint> namespace mbgl { @@ -10,8 +13,18 @@ public: : a_pos { x, y } {} const int16_t a_pos[2]; +}; + +namespace gl { - static void bind(const int8_t* offset); +template <class Shader> +struct AttributeBindings<Shader, PlainVertex> { + std::array<AttributeBinding, 1> operator()(const Shader& shader) { + return {{ + MBGL_MAKE_ATTRIBUTE_BINDING(PlainVertex, shader, a_pos) + }}; + }; }; +} // namespace gl } // namespace mbgl diff --git a/src/mbgl/shader/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp index f3909bb2ac..34b2bdf47b 100644 --- a/src/mbgl/shader/raster_shader.cpp +++ b/src/mbgl/shader/raster_shader.cpp @@ -12,9 +12,4 @@ RasterShader::RasterShader(gl::Context& context, Defines defines) context, defines) { } -void RasterShader::bind(const gl::VertexBuffer<RasterVertex>&, - const int8_t* offset) { - RasterVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp index 063bf78fd7..9633fd5fa0 100644 --- a/src/mbgl/shader/raster_shader.hpp +++ b/src/mbgl/shader/raster_shader.hpp @@ -1,22 +1,21 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class RasterVertex; class RasterShader : public gl::Shader { public: RasterShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<RasterVertex>&, - const int8_t* offset); + using VertexType = RasterVertex; + + gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this }; + gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this }; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<int32_t> u_image0 = {"u_image0", *this}; diff --git a/src/mbgl/shader/raster_vertex.cpp b/src/mbgl/shader/raster_vertex.cpp index 47f267ea0e..fc9b1f11c2 100644 --- a/src/mbgl/shader/raster_vertex.cpp +++ b/src/mbgl/shader/raster_vertex.cpp @@ -1,14 +1,7 @@ #include <mbgl/shader/raster_vertex.hpp> -#include <mbgl/gl/shader.hpp> -#include <mbgl/gl/gl.hpp> namespace mbgl { -void RasterVertex::bind(const int8_t* offset) { - static_assert(sizeof(RasterVertex) == 8, "expected RasterVertex size"); - - MBGL_BIND_VERTEX_ATTRIBUTE(RasterVertex, a_pos, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(RasterVertex, a_texture_pos, offset); -} +static_assert(sizeof(RasterVertex) == 8, "expected RasterVertex size"); } // namespace mbgl diff --git a/src/mbgl/shader/raster_vertex.hpp b/src/mbgl/shader/raster_vertex.hpp index b983010d3d..70e08c609d 100644 --- a/src/mbgl/shader/raster_vertex.hpp +++ b/src/mbgl/shader/raster_vertex.hpp @@ -1,12 +1,15 @@ #pragma once +#include <mbgl/gl/attribute.hpp> + +#include <array> #include <cstdint> namespace mbgl { class RasterVertex { public: - RasterVertex(int16_t x, int16_t y, int16_t tx, int16_t ty) + RasterVertex(int16_t x, int16_t y, uint16_t tx, uint16_t ty) : a_pos { x, y @@ -17,9 +20,20 @@ public: } {} const int16_t a_pos[2]; - const int16_t a_texture_pos[2]; + const uint16_t a_texture_pos[2]; +}; + +namespace gl { - static void bind(const int8_t* offset); +template <class Shader> +struct AttributeBindings<Shader, RasterVertex> { + std::array<AttributeBinding, 2> operator()(const Shader& shader) { + return {{ + MBGL_MAKE_ATTRIBUTE_BINDING(RasterVertex, shader, a_pos), + MBGL_MAKE_ATTRIBUTE_BINDING(RasterVertex, shader, a_texture_pos) + }}; + }; }; +} // namespace gl } // namespace mbgl diff --git a/src/mbgl/shader/sdf_shader.cpp b/src/mbgl/shader/sdf_shader.cpp index 804e96706f..73717ea9a8 100644 --- a/src/mbgl/shader/sdf_shader.cpp +++ b/src/mbgl/shader/sdf_shader.cpp @@ -12,9 +12,4 @@ SDFShader::SDFShader(gl::Context& context, Defines defines) context, defines) { } -void SDFShader::bind(const gl::VertexBuffer<TextureRectVertex>&, - const int8_t* offset) { - TextureRectVertex::bind(offset); -} - } // namespace mbgl diff --git a/src/mbgl/shader/sdf_shader.hpp b/src/mbgl/shader/sdf_shader.hpp index 5c10e2c52c..68e65bbb18 100644 --- a/src/mbgl/shader/sdf_shader.hpp +++ b/src/mbgl/shader/sdf_shader.hpp @@ -1,23 +1,24 @@ #pragma once #include <mbgl/gl/shader.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> #include <mbgl/util/color.hpp> namespace mbgl { -namespace gl { -template <class> class VertexBuffer; -} // namespace gl - class TextureRectVertex; class SDFShader : public gl::Shader { public: SDFShader(gl::Context&, Defines defines = None); - void bind(const gl::VertexBuffer<TextureRectVertex>&, - const int8_t* offset); + using VertexType = TextureRectVertex; + + gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this }; + gl::Attribute<int16_t, 2> a_offset = { "a_offset", *this }; + gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this }; + gl::Attribute<uint8_t, 4> a_data = { "a_data", *this }; gl::UniformMatrix<4> u_matrix = {"u_matrix", *this}; gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this}; diff --git a/src/mbgl/shader/texture_rect_vertex.cpp b/src/mbgl/shader/texture_rect_vertex.cpp index cbb186ffb4..4950487b01 100644 --- a/src/mbgl/shader/texture_rect_vertex.cpp +++ b/src/mbgl/shader/texture_rect_vertex.cpp @@ -4,13 +4,6 @@ namespace mbgl { -void TextureRectVertex::bind(const int8_t* offset) { - static_assert(sizeof(TextureRectVertex) == 16, "expected TextureRectVertex size"); - - MBGL_BIND_VERTEX_ATTRIBUTE(TextureRectVertex, a_pos, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(TextureRectVertex, a_offset, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(TextureRectVertex, a_texture_pos, offset); - MBGL_BIND_VERTEX_ATTRIBUTE(TextureRectVertex, a_data, offset); -} +static_assert(sizeof(TextureRectVertex) == 16, "expected TextureRectVertex size"); } // namespace mbgl diff --git a/src/mbgl/shader/texture_rect_vertex.hpp b/src/mbgl/shader/texture_rect_vertex.hpp index e2e2526f16..4c45087c68 100644 --- a/src/mbgl/shader/texture_rect_vertex.hpp +++ b/src/mbgl/shader/texture_rect_vertex.hpp @@ -1,5 +1,8 @@ #pragma once +#include <mbgl/gl/attribute.hpp> + +#include <array> #include <cstdint> #include <cmath> @@ -32,8 +35,21 @@ public: const int16_t a_offset[2]; const uint16_t a_texture_pos[2]; const uint8_t a_data[4]; +}; + +namespace gl { - static void bind(const int8_t* offset); +template <class Shader> +struct AttributeBindings<Shader, TextureRectVertex> { + std::array<AttributeBinding, 4> operator()(const Shader& shader) { + return {{ + MBGL_MAKE_ATTRIBUTE_BINDING(TextureRectVertex, shader, a_pos), + MBGL_MAKE_ATTRIBUTE_BINDING(TextureRectVertex, shader, a_offset), + MBGL_MAKE_ATTRIBUTE_BINDING(TextureRectVertex, shader, a_texture_pos), + MBGL_MAKE_ATTRIBUTE_BINDING(TextureRectVertex, shader, a_data) + }}; + }; }; +} // namespace gl } // namespace mbgl |