summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-09-26 12:53:32 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-10-05 10:52:19 -0700
commit7a3bef091e7390fa57bf33f1a704c893768b5625 (patch)
treeaf798d879923fd45e763f5dc5449b7e8419aa192 /include
parentac8a74ebccb85f83c40b9fccfeb11dc2cb3c79e4 (diff)
downloadqtlocation-mapboxgl-7a3bef091e7390fa57bf33f1a704c893768b5625.tar.gz
[core] Refactor Buffer
Diffstat (limited to 'include')
-rw-r--r--include/mbgl/gl/gl.hpp38
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