diff options
Diffstat (limited to 'include/mbgl/geometry/vao.hpp')
-rw-r--r-- | include/mbgl/geometry/vao.hpp | 101 |
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 |