diff --git a/include/blt/gfx/loader/obj_loader.h b/include/blt/gfx/loader/obj_loader.h deleted file mode 100644 index ad75b50..0000000 --- a/include/blt/gfx/loader/obj_loader.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * - * Copyright (C) 2024 Brett Terpstra - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef BLT_WITH_GRAPHICS_OBJ_LOADER_H -#define BLT_WITH_GRAPHICS_OBJ_LOADER_H - -#include "blt/math/vectors.h" -#include "blt/std/hashmap.h" -#include -#include -#include - -namespace blt::gfx -{ - - typedef blt::vec3f vertex_t; - typedef blt::vec2f uv_t; - typedef blt::vec3f normal_t; - - class model_data - { - public: - private: - std::vector vertices; - std::vector uvs; - std::vector normals; - }; - - struct face_t - { - std::int32_t vertex, uv, normal; - }; - - static inline bool operator==(const face_t& f1, const face_t& f2) - { - return f1.vertex == f2.vertex && f1.uv == f2.uv && f1.normal == f2.normal; - } - - struct face_hash - { - size_t operator()(const face_t& face) const - { - std::hash hasher; - return hasher(face.vertex) ^ hasher(face.uv) ^ hasher(face.normal); - } - }; - - struct face_eq - { - bool operator()(const face_t& f1, const face_t& f2) const - { - return f1 == f2; - } - }; - - struct constructed_vertex_t - { - vertex_t vertex; - uv_t uv; - normal_t normal; - }; - - struct triangle_t - { - std::int32_t v[3]; - }; - - struct quad_t - { - std::int32_t v[4]; - }; - - struct object_data - { - std::string object_name; - std::vector indices; - }; - - class obj_objects_t - { - private: - std::vector vertex_data_; - std::vector objects_; - public: - obj_objects_t(std::vector&& vertex_data, std::vector&& objects): - vertex_data_(vertex_data), objects_(objects) - {} - - inline const std::vector& vertex_data() - { - return vertex_data_; - }; - - inline const std::vector& objects() - { - return objects_; - }; - }; - - class char_tokenizer; - - class obj_loader - { - private: - std::vector vertices; - std::vector uvs; - std::vector normals; - - // maps between face (constructed vertex) -> vertex indices - HASHMAP vertex_map; - std::vector vertex_data; - object_data current_object; - std::vector data; - private: - bool handle_vertex_and_normals(float x, float y, float z, char type); - - void parse_vertex_line(char_tokenizer& tokenizer); - - void parse_face(char_tokenizer& tokenizer); - - void handle_face_vertex(const std::vector& face_list, std::int32_t* arr); - - public: - obj_objects_t parseFile(std::string_view file); - }; - - obj_objects_t quick_load(std::string_view file); - -} - -#endif //BLT_WITH_GRAPHICS_OBJ_LOADER_H diff --git a/include/blt/gfx/model.h b/include/blt/gfx/model.h index 778a4a3..19814cd 100644 --- a/include/blt/gfx/model.h +++ b/include/blt/gfx/model.h @@ -66,7 +66,8 @@ namespace blt::gfx explicit vbo_t_owner(vbo_t vbo): vbo(vbo) {} - vbo_t* operator->(){ + vbo_t* operator->() + { return &vbo; } @@ -133,6 +134,7 @@ namespace blt::gfx vbo_t element; void handle_vbo(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset); + public: vertex_array(); @@ -156,6 +158,7 @@ namespace blt::gfx * @return a shared pointer to the stored vbo. used for chaining VAOs with multiple shared VBOs */ static_dynamic_array::vbo_type bindVBO(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset); + // same as the other bind method except you provide the shared reference. void bindVBO(const static_dynamic_array::vbo_type& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset); @@ -191,6 +194,11 @@ namespace blt::gfx glBindVertexArray(0); } + static inline std::shared_ptr createSharedVBO(const vbo_t& vbo) + { + return std::make_shared(vbo); + } + ~vertex_array(); }; diff --git a/libraries/BLT b/libraries/BLT index 9147a85..60ec205 160000 --- a/libraries/BLT +++ b/libraries/BLT @@ -1 +1 @@ -Subproject commit 9147a85dc32f06be2a4cfe4e422fdbc52679adc5 +Subproject commit 60ec2051d8422716e1d6fb8354c129731106f7ad diff --git a/src/blt/gfx/loader/obj_loader.cpp b/src/blt/gfx/loader/obj_loader.cpp deleted file mode 100644 index ec9f8a3..0000000 --- a/src/blt/gfx/loader/obj_loader.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * - * Copyright (C) 2024 Brett Terpstra - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include "blt/std/assert.h" -#include "blt/std/utility.h" - -namespace blt::gfx -{ - class char_tokenizer - { - private: - std::string_view string; - std::size_t current_pos = 0; - public: - explicit char_tokenizer(std::string_view view): string(view) - {} - - inline char advance() - { - return string[current_pos++]; - } - - inline bool has_next(size_t offset = 0) - { - return current_pos + offset < string.size(); - } - - inline std::string_view read_fully() - { - return blt::string::trim(string.substr(current_pos)); - } - }; - - template - T get(std::string_view str) - { - T x; - const auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), x); - // probably not needed. - if (ec != std::errc()) - { -// int i; -// const auto [ptr2, ec2] = std::from_chars(str.data(), str.data() + str.size(), i); -// if (ec2 == std::errc()) -// { -// x = static_cast(i); -// } else -// { - BLT_WARN("Unable to parse string '%s' into number!", std::string(str).c_str()); - x = 0; -// } - } - return x; - } - - void obj_loader::parse_vertex_line(char_tokenizer& tokenizer) - { - char type = tokenizer.advance(); - - if (type == 'p') - { - BLT_WARN("Unexpected type '%c' (not supported)", type); - return; - } - - auto elements = blt::string::split(std::string(tokenizer.read_fully()), " "); - BLT_ASSERT(elements.size() >= 2 && "Current line doesn't have enough arguments to process!"); - float x = get(elements[0]), y = get(elements[1]); - if (elements.size() < 3) - { - if (type == 't') - uvs.push_back(uv_t{x, y}); - else - BLT_ERROR("Unable to parse line '%s' type '%c' not recognized for arg count", std::string(tokenizer.read_fully()).c_str(), type); - } else - { - float z = get(elements[2]); - if (!handle_vertex_and_normals(x, y, z, type)) - BLT_ERROR("Unable to parse line '%s' type '%c' not recognized", std::string(tokenizer.read_fully()).c_str(), type); - } - } - - bool obj_loader::handle_vertex_and_normals(float x, float y, float z, char type) - { - if (std::isspace(type)) - { - vertices.push_back(vertex_t{x, y, z}); - } else if (type == 'n') - { - normals.push_back(normal_t{x, y, z}); - } else - return false; - return true; - } - - obj_objects_t quick_load(std::string_view file) - { - return obj_loader().parseFile(file); - } - - obj_objects_t obj_loader::parseFile(std::string_view file) - { - auto lines = blt::fs::getLinesFromFile(std::string(file)); - for (const auto& line : lines) - { - char_tokenizer token(line); - if (!token.has_next() || token.read_fully().empty()) - continue; - switch (token.advance()) - { - case '#': - continue; - case 'f': - parse_face(token); - break; - case 'v': - parse_vertex_line(token); - break; - case 'o': - { - if (!current_object.indices.empty()) - data.push_back(current_object); - current_object = {}; - current_object.object_name = token.read_fully(); - break; - } - case 'm': - { - BLT_TRACE("Material '%s' needs to be loaded!", std::string(token.read_fully()).c_str()); - break; - } - case 'u': - { - BLT_TRACE("Using material '%s'", std::string(token.read_fully()).c_str()); - break; - } - case 's': - BLT_TRACE("Using shading: %s", std::string(token.read_fully()).c_str()); - break; - } - } - data.push_back(current_object); - return {std::move(vertex_data), std::move(data)}; - } - - void obj_loader::parse_face(char_tokenizer& tokenizer) - { - auto faces = blt::string::split(std::string(tokenizer.read_fully()), ' '); - if (faces.size() == 3) - { - triangle_t triangle{}; - handle_face_vertex(faces, triangle.v); - current_object.indices.push_back(triangle); - } else if (faces.size() == 4) - { - quad_t quad{}; - handle_face_vertex(faces, quad.v); - triangle_t t1{}; - triangle_t t2{}; - - for (int i = 0; i < 3; i++) - t1.v[i] = quad.v[i]; - t2.v[0] = quad.v[0]; - t2.v[1] = quad.v[2]; - t2.v[2] = quad.v[3]; - - current_object.indices.push_back(t1); - current_object.indices.push_back(t2); - } else - BLT_WARN("Unsupported vertex count! %d", faces.size()); - } - - void obj_loader::handle_face_vertex(const std::vector& face_list, int32_t* arr) - { - for (const auto& pair : blt::enumerate(face_list)) - { - auto indices = blt::string::split(pair.second, '/'); - BLT_ASSERT(indices.size() == 3 && "Must have vertex, uv, and normal indices!!"); - - auto vi = get(indices[0]); - auto ui = get(indices[1]); - auto ni = get(indices[2]); - - face_t face{vi, ui, ni}; - - auto loc = vertex_map.find(face); - if (loc == vertex_map.end()) - { - auto index = static_cast(vertex_data.size()); - vertex_data.push_back({vertices[vi], uvs[ui], normals[ni]}); - vertex_map.insert({face, index}); - arr[pair.first] = index; - } else - { - arr[pair.first] = loc->second; - } - } - } -} \ No newline at end of file diff --git a/src/blt/gfx/model.cpp b/src/blt/gfx/model.cpp index 1d833bc..fa3c511 100644 --- a/src/blt/gfx/model.cpp +++ b/src/blt/gfx/model.cpp @@ -135,7 +135,7 @@ namespace blt::gfx long offset) { handle_vbo(vbo, attribute_number, coordinate_size, type, stride, offset); - VBOs[attribute_number] = std::make_shared(vbo); + VBOs[attribute_number] = createSharedVBO(vbo); return VBOs[attribute_number]; } diff --git a/tests/src/main.cpp b/tests/src/main.cpp index a29a2c4..8c896b7 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -1,21 +1,19 @@ #include -#include #include -#include #include #include "blt/gfx/imgui/IconsFontAwesome5.h" #include "blt/gfx/renderer/resource_manager.h" #include "blt/gfx/renderer/batch_2d_renderer.h" #include "blt/gfx/renderer/camera.h" -#include +#include blt::gfx::matrix_state_manager global_matrices; blt::gfx::resource_manager resources; blt::gfx::batch_renderer_2d renderer_2d(resources); blt::gfx::first_person_camera camera; -std::vector vao; +std::vector vaos; float x = 0, y = 0, z = 0; float bx = 500, by = 500; @@ -60,11 +58,21 @@ void init() vbo_t vertices_vbo; vertices_vbo.allocate(static_cast(object.vertex_data().size() * sizeof(blt::gfx::constructed_vertex_t)), object.vertex_data().data()); + auto ptr = vertex_array::createSharedVBO(vertices_vbo); for (auto obj : object.objects()) { vbo_t indices_vbo; indices_vbo.allocate(static_cast(obj.indices.size() * sizeof(blt::gfx::triangle_t)), obj.indices.data()); + + auto* vao = new vertex_array(); + vao->bindVBO(ptr, 0, 3, GL_FLOAT, sizeof(float) * (3 + 3 + 2), 0); + vao->bindVBO(ptr, 1, 2, GL_FLOAT, sizeof(float) * (3 + 3 + 2), sizeof(float) * 3); + vao->bindVBO(ptr, 2, 3, GL_FLOAT, sizeof(float) * (3 + 3 + 2), sizeof(float) * (3 + 2)); + + vao->bindElement(indices_vbo); + + vaos.push_back(vao); } global_matrices.create_internals(); @@ -98,6 +106,8 @@ int main() global_matrices.cleanup(); resources.cleanup(); renderer_2d.cleanup(); + for (auto* p : vaos) + delete p; blt::gfx::cleanup(); return 0; }