#pragma once #include #include #include #include #include #include namespace cgl { class VertexArray { GLuint id{}; public: VertexArray() { glCreateVertexArrays(1, &id); } VertexArray(VertexArray &) = delete; VertexArray(VertexArray &&o) noexcept { id = std::exchange(o.id, 0); } ~VertexArray() { glDeleteVertexArrays(1, &id); id = 0; } operator GLuint() const { return id; } void bound(const std::function &action) const { glBindVertexArray(id); action(); glBindVertexArray(0); } template void pointer( GLuint index, const Buffer &buf, unsigned size, GLenum type, bool normalized = false, unsigned stride = 0 ) const { bound([&]() { glEnableVertexAttribArray(index); buf.bound(GL_ARRAY_BUFFER, [&]() { glVertexAttribPointer(index, size, type, normalized, stride, nullptr); }); }); } template void ipointer( GLuint index, const Buffer &buf, unsigned size, GLenum type, unsigned stride = 0 ) const { bound([&]() { glEnableVertexAttribArray(index); buf.bound(GL_ARRAY_BUFFER, [&]() { glVertexAttribIPointer(index, size, type, stride, nullptr); }); }); } }; }