summary refs log tree commit diff
path: root/src/GFX/Mesh.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GFX/Mesh.cpp')
-rw-r--r--src/GFX/Mesh.cpp75
1 files changed, 70 insertions, 5 deletions
diff --git a/src/GFX/Mesh.cpp b/src/GFX/Mesh.cpp
index c45b5c9..0633e11 100644
--- a/src/GFX/Mesh.cpp
+++ b/src/GFX/Mesh.cpp
@@ -2,12 +2,77 @@
 
 namespace MC::GFX {
 
-const std::vector<U32>& Mesh::indices() const {
-    return m_indices;
+USize Mesh::size() const {
+    return m_indices.size();
 }
 
-const std::vector<Mesh::Attribute>& Mesh::attributes() const {
-    return m_attributes;
+void Mesh::bind() {
+    if (!m_vao.has_value()) upload();
+
+    glBindVertexArray(m_vao.value());
+    for (Int i = 0; i < m_attributes.size(); i++) {
+        glEnableVertexAttribArray(i);
+    }
+}
+
+void Mesh::unbind() const {
+    glBindVertexArray(0);
+    for (Int i = 0; i < m_attributes.size(); i++) {
+        glDisableVertexAttribArray(i);
+    }
+}
+
+void Mesh::upload() {
+    auto vao = create_vao();
+    if (!m_indices.empty()) {
+        store_indices(m_indices.data(), m_indices.size());
+    }
+
+    Int attribute_index = 0;
+    for (const auto& attribute : m_attributes) {
+        store_in_attribute_list(
+            attribute_index++,
+            attribute.attribute_size,
+            attribute.type_size,
+            attribute.data,
+            attribute.data_size
+        );
+    }
+    unbind_vao();
+
+    m_vao = {vao};
+}
+
+GLuint Mesh::create_vao() {
+    GLuint vao;
+    glGenVertexArrays(1, &vao);
+    glBindVertexArray(vao);
+
+    return vao;
 }
 
-}
\ No newline at end of file
+void Mesh::unbind_vao() {
+    glBindVertexArray(0);
+}
+
+void Mesh::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 Mesh::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);
+}
+
+}