/* * * Copyright (C) 2023 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_MODEL_H #define BLT_WITH_GRAPHICS_MODEL_H #include #include #include #include #include #include namespace blt::gfx { class model_data { public: private: std::vector vertices; std::vector uvs; std::vector normals; }; struct vbo_t { GLuint bufferID_ = 0; GLsizeiptr size_ = 0; GLint buffer_type; GLint memory_type; void create(GLint type); void bind() const; void allocate(GLsizeiptr size, GLint memory_type = GL_STATIC_DRAW, void* data = nullptr); void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data); void update(GLsizeiptr size, void* data); void destroy(); }; /** * Since most VAOs will not use more than 8 VBOs it makes no sense to heap allocate memory to store them * This class is used to make that easier to handle */ class static_dynamic_array { private: static constexpr size_t DATA_SIZE = 8; typedef std::array array_t; std::variant data_; size_t size_ = DATA_SIZE; size_t max = 0; void swap(); public: static_dynamic_array(); static_dynamic_array(const static_dynamic_array& copy) = delete; static_dynamic_array(static_dynamic_array&& move) noexcept = default; static_dynamic_array& operator=(const static_dynamic_array& copy) = delete; static_dynamic_array& operator=(static_dynamic_array&& move) noexcept = default; vbo_t& operator[](size_t index); [[nodiscard]] inline size_t used() const noexcept { return max; } ~static_dynamic_array() { if (std::holds_alternative(data_)) delete[] std::get(data_); } }; /** * basic VAO class. */ class basic_vertex_array { private: GLuint vaoID; static_dynamic_array VBOs; HASHSET used_attributes; vbo_t element; public: basic_vertex_array(); basic_vertex_array(const basic_vertex_array&) = delete; basic_vertex_array(basic_vertex_array&&) = delete; basic_vertex_array& operator=(const basic_vertex_array&) = delete; basic_vertex_array& operator=(basic_vertex_array&&) = delete; /** * This function takes ownership of the underlying VBO (GPU side). It will be freed when the basic vertex array is deleted * @param vbo vbo to bind to this attribute * @param attribute_number attribute number to bind to * @param coordinate_size size of the data (number of * @param type type of data * @param stride how many bytes this data takes (for the entire per-vertex data structure) 0 will assume packed data * @param offset offset into the data structure to where the data is stored */ void bindVBO(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset); /** * Returns a non-owning reference to a vbo allowing for updating the VBO * The VBO is considered invalid if its ID is 0 */ inline vbo_t& operator[](size_t index) { return VBOs[index]; } inline void bind() { glBindVertexArray(vaoID); } ~basic_vertex_array(); }; } #endif //BLT_WITH_GRAPHICS_MODEL_H