summaryrefslogtreecommitdiff
path: root/include/mbgl/geometry/vao.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/mbgl/geometry/vao.hpp')
-rw-r--r--include/mbgl/geometry/vao.hpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/include/mbgl/geometry/vao.hpp b/include/mbgl/geometry/vao.hpp
new file mode 100644
index 0000000000..71d7ff89fe
--- /dev/null
+++ b/include/mbgl/geometry/vao.hpp
@@ -0,0 +1,101 @@
+#ifndef MBGL_GEOMETRY_VAO
+#define MBGL_GEOMETRY_VAO
+
+#include <mbgl/platform/gl.hpp>
+
+#include <stdexcept>
+
+namespace mbgl {
+
+class VertexArrayObject {
+public:
+ template <typename Shader, typename VertexBuffer>
+ void bind(Shader& shader, VertexBuffer& vertex_buffer, char *offset) {
+#ifdef GL_ARB_vertex_array_object
+ if (!vao) {
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ } else {
+ // We have been given the correct information.
+ glBindVertexArray(vao);
+ }
+
+ if (shader_ptr != &shader) {
+ if (shader_ptr != nullptr) {
+ fprintf(stderr, "shader rebind!");
+ }
+#endif
+ vertex_buffer.bind();
+ shader.bind(offset);
+
+#ifdef GL_ARB_vertex_array_object
+ shader_ptr = &shader;
+ vertex_buffer_ptr = &vertex_buffer;
+ elements_buffer_ptr = nullptr;
+ offset_ptr = offset;
+ } else if (vertex_buffer_ptr != &vertex_buffer) {
+ throw std::runtime_error("trying to bind VAO to another vertex buffer");
+ } else if (elements_buffer_ptr != nullptr) {
+ throw std::runtime_error("trying to bind VAO to another elements buffer");
+ } else if (offset_ptr != offset) {
+ throw std::runtime_error("trying to bind VAO to another offset");
+ }
+#endif
+ }
+
+ template <typename Shader, typename VertexBuffer, typename ElementsBuffer>
+ void bind(Shader& shader, VertexBuffer& vertex_buffer, ElementsBuffer& elements_buffer, char *offset) {
+#ifdef GL_ARB_vertex_array_object
+ if (!vao) {
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ } else {
+ // We have been given the correct information.
+ glBindVertexArray(vao);
+ }
+
+ if (shader_ptr != &shader) {
+#endif
+ vertex_buffer.bind();
+ elements_buffer.bind();
+ shader.bind(offset);
+
+#ifdef GL_ARB_vertex_array_object
+ shader_ptr = &shader;
+ vertex_buffer_ptr = &vertex_buffer;
+ elements_buffer_ptr = &elements_buffer;
+ offset_ptr = offset;
+ } else if (vertex_buffer_ptr != &vertex_buffer) {
+ throw std::runtime_error("trying to bind VAO to another vertex buffer");
+ } else if (elements_buffer_ptr != &elements_buffer) {
+ throw std::runtime_error("trying to bind VAO to another elements buffer");
+ } else if (offset_ptr != offset) {
+ throw std::runtime_error("trying to bind VAO to another offset");
+ }
+#endif
+ }
+
+ ~VertexArrayObject() {
+#ifdef GL_ARB_vertex_array_object
+ if (vao) {
+ glDeleteVertexArrays(1, &vao);
+ }
+#endif
+ }
+
+private:
+#ifdef GL_ARB_vertex_array_object
+ GLuint vao = 0;
+
+ // For debug reasons, we're storing the bind information so that we can
+ // detect errors and report
+ void *shader_ptr = nullptr;
+ void *vertex_buffer_ptr = nullptr;
+ void *elements_buffer_ptr = nullptr;
+ char *offset_ptr = 0;
+#endif
+};
+
+}
+
+#endif