]> git.localhorst.tv Git - tacos.git/blobdiff - src/graphics/vao.hpp
isolate some GL stuff
[tacos.git] / src / graphics / vao.hpp
diff --git a/src/graphics/vao.hpp b/src/graphics/vao.hpp
new file mode 100644 (file)
index 0000000..debed55
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef TACOS_GRAPHICS_VAO_HPP_
+#define TACOS_GRAPHICS_VAO_HPP_
+
+#include "buffer.hpp"
+#include "gl_traits.hpp"
+
+#include <GL/glew.h>
+
+
+namespace tacos {
+
+/// Simple vertex array object based on indexed draw calls with attributes
+/// interleaved in a single buffer.
+template<class Attributes, class Element>
+class SimpleVAO {
+
+public:
+       SimpleVAO()
+       : vao(0)
+       , buffers{0} {
+               glGenVertexArrays(1, &vao);
+               glGenBuffers(2, buffers);
+       }
+       ~SimpleVAO() noexcept {
+               glDeleteBuffers(2, buffers);
+               glDeleteVertexArrays(1, &vao);
+       }
+
+       SimpleVAO(const SimpleVAO &) = delete;
+       SimpleVAO &operator =(const SimpleVAO &) = delete;
+
+public:
+       void Bind() const noexcept {
+               glBindVertexArray(vao);
+       }
+       void Unbind() const noexcept {
+               glBindVertexArray(0);
+       }
+       void BindAttributes() const noexcept {
+               glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
+       }
+       void BindElements() const noexcept {
+               glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
+       }
+       void EnableAttribute(GLuint index) noexcept {
+               glEnableVertexAttribArray(index);
+       }
+       void DisableAttribute(GLuint index) noexcept {
+               glDisableVertexAttribArray(index);
+       }
+       template<class Attribute>
+       void AttributePointer(GLuint index, bool normalized, std::size_t offset) noexcept {
+               glVertexAttribPointer(
+                       index,
+                       gl_traits<Attribute>::size,
+                       gl_traits<Attribute>::type,
+                       normalized,
+                       sizeof(Attributes),
+                       reinterpret_cast<const void *>(offset)
+               );
+       }
+       void ReserveAttributes(std::size_t size, GLenum usage) noexcept {
+               glBufferData(GL_ARRAY_BUFFER, size * sizeof(Attributes), nullptr, usage);
+       }
+       MappedBuffer<Attributes> MapAttributes(GLenum access) {
+               return MappedBuffer<Attributes>(GL_ARRAY_BUFFER, access);
+       }
+       void ReserveElements(std::size_t size, GLenum usage) noexcept {
+               glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(Element), nullptr, usage);
+       }
+       MappedBuffer<Element> MapElements(GLenum access) {
+               return MappedBuffer<Element>(GL_ELEMENT_ARRAY_BUFFER, access);
+       }
+       void DrawTriangles(std::size_t size, std::size_t offset = 0) const noexcept {
+               glDrawElements(GL_TRIANGLES, size, gl_traits<Element>::type, ((Element *) nullptr) + offset);
+       }
+
+private:
+       GLuint vao;
+       GLuint buffers[2];
+
+};
+
+}
+
+#endif