diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-09-26 12:53:32 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-10-05 10:52:19 -0700 |
commit | 7a3bef091e7390fa57bf33f1a704c893768b5625 (patch) | |
tree | af798d879923fd45e763f5dc5449b7e8419aa192 /include | |
parent | ac8a74ebccb85f83c40b9fccfeb11dc2cb3c79e4 (diff) | |
download | qtlocation-mapboxgl-7a3bef091e7390fa57bf33f1a704c893768b5625.tar.gz |
[core] Refactor Buffer
Diffstat (limited to 'include')
-rw-r--r-- | include/mbgl/gl/gl.hpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/include/mbgl/gl/gl.hpp b/include/mbgl/gl/gl.hpp index a499d731d6..4468bf8c12 100644 --- a/include/mbgl/gl/gl.hpp +++ b/include/mbgl/gl/gl.hpp @@ -1,6 +1,10 @@ #pragma once +#include <mbgl/gl/types.hpp> + #include <stdexcept> +#include <type_traits> +#include <limits> #if __APPLE__ #include "TargetConditionals.h" @@ -36,12 +40,40 @@ struct Error : std::runtime_error { void checkError(const char *cmd, const char *file, int line); -} // namespace gl -} // namespace mbgl - #ifndef NDEBUG #define MBGL_CHECK_ERROR(cmd) ([&]() { struct __MBGL_C_E { ~__MBGL_C_E() { ::mbgl::gl::checkError(#cmd, __FILE__, __LINE__); } } __MBGL_C_E; return cmd; }()) #else #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)>(Shader::member, &VertexType::member, offset) + +} // namespace gl +} // namespace mbgl |