#include #include "Binder.hpp" #include "Mesh.hpp" namespace MC::GFX { BindableMesh Binder::load(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()}; } uint32_t Binder::create_vao() { GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); return static_cast(vao); } void Binder::unbind_vao() { glBindVertexArray(0); } void Binder::store_indices(uint32_t* indices, size_t indices_size) { GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size * sizeof(float), indices, GL_STATIC_DRAW); } void Binder::store_in_attribute_list(uint32_t attribute, int attribute_size, int type_size, void* data, long data_size) { assert(type_size == sizeof(float)); 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; } size_t BindableMesh::size() const { return m_vertex_count; } }