#include "../graphics/gl_traits.hpp" namespace blank { template VertexArray::VertexArray() noexcept : idx_count(0) , idx_type(GL_UNSIGNED_INT) { glGenVertexArrays(1, &array_id); glGenBuffers(N, attr_id); } template VertexArray::~VertexArray() noexcept { if (array_id != 0) { glDeleteBuffers(N, attr_id); glDeleteVertexArrays(1, &array_id); } } template VertexArray::VertexArray(VertexArray &&other) noexcept : array_id(other.array_id) , idx_count(other.idx_count) , idx_type(other.idx_type) { other.array_id = 0; for (std::size_t i = 0; i < N; ++i) { attr_id[i] = other.attr_id[i]; other.attr_id[i] = 0; } } template VertexArray &VertexArray::operator =(VertexArray &&other) noexcept { std::swap(array_id, other.array_id); for (std::size_t i = 0; i < N; ++i) { std::swap(attr_id[i], other.attr_id[i]); } idx_count = other.idx_count; idx_type = other.idx_type; return *this; } template void VertexArray::Bind() const noexcept { glBindVertexArray(array_id); } template template void VertexArray::PushAttribute(std::size_t which, const std::vector &data, bool normalized) noexcept { BindAttribute(which); AttributeData(data); EnableAttribute(which); AttributePointer(which, normalized); } template void VertexArray::BindAttribute(std::size_t i) const noexcept { assert(i < NUM_ATTRS && "vertex attribute ID out of bounds"); glBindBuffer(GL_ARRAY_BUFFER, attr_id[i]); } template void VertexArray::EnableAttribute(std::size_t i) noexcept { assert(i < NUM_ATTRS && "vertex attribute ID out of bounds"); glEnableVertexAttribArray(i); } template template void VertexArray::AttributeData(const std::vector &buf) noexcept { glBufferData(GL_ARRAY_BUFFER, buf.size() * sizeof(T), buf.data(), GL_STATIC_DRAW); } template template void VertexArray::AttributePointer(std::size_t which, bool normalized) noexcept { glVertexAttribPointer( which, // program location gl_traits::size, // element size gl_traits::type, // element type normalized, // normalize to [-1,1] or [0,1] for unsigned types 0, // stride nullptr // offset ); } template template void VertexArray::PushIndices(std::size_t which, const std::vector &indices) noexcept { BindIndex(which); IndexData(indices); } template void VertexArray::BindIndex(std::size_t i) const noexcept { assert(i < NUM_ATTRS && "element index ID out of bounds"); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, attr_id[i]); } template template void VertexArray::IndexData(const std::vector &buf) noexcept { glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.size() * sizeof(T), buf.data(), GL_STATIC_DRAW); idx_count = buf.size(); idx_type = gl_traits::type; } template void VertexArray::DrawLineElements() const noexcept { Bind(); glDrawElements( GL_LINES, // how idx_count, // count idx_type, // type nullptr // offset ); } template void VertexArray::DrawTriangleElements() const noexcept { Bind(); glDrawElements( GL_TRIANGLES, // how idx_count, // count idx_type, // type nullptr // offset ); } }