#include #include "Binder.hpp" #include "Mesh.hpp" namespace MC::GFX { BindableMesh Binder::load(const Mesh& mesh) { auto vao = create_vao(); if (!mesh.indices().empty()) { store_indices(mesh.indices().data(), mesh.indices().size()); } Int attribute_index = 0; for (const auto& attribute : mesh.attributes()) { store_in_attribute_list( attribute_index++, attribute.attribute_size, attribute.type_size, attribute.data, attribute.data_size ); } unbind_vao(); return {vao, mesh.indices().size(), mesh.attributes().size()}; } U32 Binder::create_vao() { GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); return vao; } void Binder::unbind_vao() { glBindVertexArray(0); } void Binder::store_indices(const U32* indices, USize indices_size) { GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size * sizeof(U32), indices, GL_STATIC_DRAW); } void Binder::store_in_attribute_list(U32 attribute, Int attribute_size, Int type_size, const void* data, long data_size) { assert(type_size == sizeof(F32)); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, data_size * attribute_size * type_size, data, GL_STATIC_DRAW); glVertexAttribPointer(attribute, attribute_size, GL_FLOAT, GL_FALSE, attribute_size * type_size, nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); } void BindableMesh::bind() const { glBindVertexArray(m_vao); for (Int i = 0; i < m_attribute_count; i++) { glEnableVertexAttribArray(i); } } void BindableMesh::unbind() const { glBindVertexArray(0); for (Int i = 0; i < m_attribute_count; i++) { glDisableVertexAttribArray(i); } } Bool BindableMesh::has_indices() const { return m_has_indices; } USize BindableMesh::size() const { return m_vertex_count; } }