diff --git a/include/blt/gfx/model.h b/include/blt/gfx/model.h index 2e07967..1a7c3cd 100644 --- a/include/blt/gfx/model.h +++ b/include/blt/gfx/model.h @@ -36,6 +36,24 @@ namespace blt::gfx std::vector normals; }; + struct vbo_t + { + GLuint bufferID_ = 0; + GLsizeiptr size_ = 0; + + vbo_t(); + + void bind(GLint buffer_type = GL_ARRAY_BUFFER) const; + + void allocate(GLsizeiptr size, GLint buffer_type = GL_ARRAY_BUFFER, GLint memory_type = GL_STATIC_DRAW, void* data = nullptr); + + static void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data, GLint buffer_type = GL_ARRAY_BUFFER); + + void update(GLsizeiptr size, void* data, GLint buffer_type = GL_ARRAY_BUFFER, GLint memory_type = GL_STATIC_DRAW); + + ~vbo_t(); + }; + /** * 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 @@ -44,9 +62,10 @@ namespace blt::gfx { private: static constexpr size_t DATA_SIZE = 8; - typedef std::array array_t; - std::variant data_; + typedef std::array array_t; + std::variant data_; size_t size_ = DATA_SIZE; + size_t max = 0; void swap(); public: @@ -54,26 +73,31 @@ namespace blt::gfx static_dynamic_array(const static_dynamic_array& copy) = delete; - static_dynamic_array(static_dynamic_array&& move) = default; + 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) = default; + static_dynamic_array& operator=(static_dynamic_array&& move) noexcept = default; - GLuint& operator[](size_t index) + vbo_t& operator[](size_t index) { if (index >= size_) swap(); - if (std::holds_alternative(data_)) - return std::get(data_)[index]; + max = std::max(index, max); + if (std::holds_alternative(data_)) + return std::get(data_)[index]; else return std::get(data_)[index]; } + [[nodiscard]] size_t used() const noexcept { + return max; + } + ~static_dynamic_array() { - if (std::holds_alternative(data_)) - delete[] std::get(data_); + if (std::holds_alternative(data_)) + delete[] std::get(data_); } }; @@ -83,25 +107,10 @@ namespace blt::gfx class basic_vertex_array { private: - struct vbo_t - { - GLuint bufferID_ = 0; - GLsizeiptr size_ = 0; - - vbo_t(); - - void bind(GLint buffer_type = GL_ARRAY_BUFFER) const; - - void allocate(GLsizeiptr size, GLint buffer_type = GL_ARRAY_BUFFER, GLint memory_type = GL_STATIC_DRAW, void* data = nullptr); - - static void sub_update(GLsizeiptr offset, GLsizeiptr size, void* data, GLint buffer_type = GL_ARRAY_BUFFER); - - void update(GLsizeiptr size, void* data, GLint buffer_type = GL_ARRAY_BUFFER, GLint memory_type = GL_STATIC_DRAW); - - ~vbo_t(); - }; + GLuint vaoID; + static_dynamic_array VBOs; public: basic_vertex_array(); }; diff --git a/src/blt/gfx/model.cpp b/src/blt/gfx/model.cpp index 92e8499..d3cfb0d 100644 --- a/src/blt/gfx/model.cpp +++ b/src/blt/gfx/model.cpp @@ -23,13 +23,15 @@ namespace blt::gfx void static_dynamic_array::swap() { size_t next_size = blt::mem::next_byte_allocation(size_); + auto* new_data = new GLuint[next_size]; std::memset(new_data, 0, next_size); + if (std::holds_alternative(data_)) { - auto ptr = std::get(data_); + auto* ptr = std::get(data_); std::memcpy(new_data, ptr, size_); - delete ptr; + delete[] ptr; } else { auto data = std::get(data_); std::memcpy(new_data, data.data(), DATA_SIZE); @@ -46,26 +48,26 @@ namespace blt::gfx /* * ----------------------------------- - * basic_vertex_array::vbo_t + * vbo_t * ----------------------------------- */ - basic_vertex_array::vbo_t::vbo_t() + vbo_t::vbo_t() { glGenBuffers(1, &bufferID_); } - basic_vertex_array::vbo_t::~vbo_t() + vbo_t::~vbo_t() { glDeleteBuffers(1, &bufferID_); } - void basic_vertex_array::vbo_t::allocate(GLsizeiptr size, GLint buffer_type, GLint memory_type, void* data) + void vbo_t::allocate(GLsizeiptr size, GLint buffer_type, GLint memory_type, void* data) { size_ = size; glBufferData(buffer_type, size, data, memory_type); } - void blt::gfx::basic_vertex_array::vbo_t::update(GLsizeiptr size, void* data, GLint buffer_type, GLint memory_type) + void vbo_t::update(GLsizeiptr size, void* data, GLint buffer_type, GLint memory_type) { if (size <= size_) sub_update(0, size, data, buffer_type);