From c002f3fcaa5b7fb5ed0061b62db2a08731c4a14a Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Mon, 9 Jun 2025 22:07:21 -0400 Subject: [PATCH] funny code --- .idea/vcs.xml | 5 ---- CMakeLists.txt | 2 +- include/vbo.h | 67 +++++++++++++++++++++++++++++++++++++++++--------- src/vbo.cpp | 19 +++++++++----- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index efc4599..4612212 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -4,23 +4,18 @@ - - - - - diff --git a/CMakeLists.txt b/CMakeLists.txt index a12bd91..76081bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(gpu-particles VERSION 0.0.10) +project(gpu-particles VERSION 0.0.11) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/vbo.h b/include/vbo.h index b7dcfa1..bb35434 100644 --- a/include/vbo.h +++ b/include/vbo.h @@ -30,6 +30,10 @@ namespace blt::gfx namespace detail { + /** + * So long as this class is called from vbo.bind(), it is always valid to chain any internal functions. + * This system is designed to be foolproof, so don't get too clever + */ class vbo_context_t { public: @@ -47,27 +51,45 @@ namespace blt::gfx vbo_context_t& unbind(); - vbo_context_t& reserve(GLsizeiptr size, GLint mem_type); + /** + * Reserves a chunk of GPU memory for future use + */ + vbo_context_t& resize(GLsizeiptr size, GLint mem_type); - vbo_context_t& reserve(const size_t size, const GLint mem_type) + /** + * Reserves a chunk of GPU memory for future use + */ + vbo_context_t& resize(const size_t size, const GLint mem_type) { - return reserve(static_cast(size), mem_type); + return resize(static_cast(size), mem_type); } - vbo_context_t& upload(size_t size, void* ptr, GLint mem_type); + /** + * Uploads a chunk of memory to the GPU. If the existing VBO has enough space, the memory will be reused. + */ + vbo_context_t& upload(size_t size, const void* ptr, GLint mem_type); - template + /** + * Uploads a chunk of memory to the GPU. If the existing VBO has enough space, the memory will be reused. + */ + template , bool> = true> vbo_context_t& upload(const size_t size, T* ptr, const GLint mem_type) { return upload(size, static_cast(ptr), mem_type); } + /** + * Updates an internal segment of the VBO. This function will never reallocate. + */ vbo_context_t& update(size_t offset, size_t size, const void* ptr); - template - vbo_context_t& update(size_t offset, const size_t size, T* ptr) + /** + * Updates an internal segment of the VBO. This function will never reallocate. + */ + template , bool> = true> + vbo_context_t& update(const size_t offset, const size_t size, T* ptr) { - return upload(offset, size, static_cast(ptr)); + return update(offset, size, static_cast(ptr)); } private: @@ -102,12 +124,26 @@ namespace blt::gfx return *this; } + /** + * Changes the internal buffer type of this VBO + */ GLuint change_type(const GLuint type) { return std::exchange(this->buffer_type, type); } - [[nodiscard]] auto bind(); + /** + * This function binds the VBO to the current buffer_type slot and returns an object which allows you to modify or use this VBO. + * This allows you to use the VBO without worrying about whether an operation is valid in this context. + * As so long as you use this object in line, or without binding other VBOs to the same buffer_type + * (violating the contracts this function attempts to create) then all functions on the associated object are valid to call. + */ + [[nodiscard]] detail::vbo_context_t bind(); + + [[nodiscard]] auto native_handle() const + { + return vboID; + } ~unique_vbo_t() { @@ -139,8 +175,17 @@ namespace blt::gfx class unique_ubo_t : public unique_vbo_t { public: - unique_ubo_t(): unique_vbo_t{GL_UNIFORM_BUFFER} - {} + explicit unique_ubo_t(const i32 location): unique_vbo_t{GL_UNIFORM_BUFFER} + {set_location(location);} + + void set_location(i32 new_location); + + [[nodiscard]] i32 get_location() const + { + return location; + } + private: + i32 location = 0; }; } diff --git a/src/vbo.cpp b/src/vbo.cpp index 92c9822..64f2da2 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -26,17 +26,17 @@ namespace blt::gfx vbo_context_t& vbo_context_t::bind() { BLT_CONTRACT(vbo.vboID, "Expected VBO to have an assoicated VBO ID!"); - glBindBuffer(vbo.type, *vbo.vboID); + glBindBuffer(vbo.buffer_type, *vbo.vboID); return *this; } vbo_context_t& vbo_context_t::unbind() { - glBindBuffer(vbo.type, 0); + glBindBuffer(vbo.buffer_type, 0); return *this; } - vbo_context_t& vbo_context_t::reserve(const GLsizeiptr size, const GLint mem_type) + vbo_context_t& vbo_context_t::resize(const GLsizeiptr size, const GLint mem_type) { vbo.size = size; vbo.memory_type = mem_type; @@ -44,9 +44,9 @@ namespace blt::gfx return *this; } - vbo_context_t& vbo_context_t::upload(const size_t size, void* ptr, const GLint mem_type) + vbo_context_t& vbo_context_t::upload(const size_t size, const void* ptr, const GLint mem_type) { - if (mem_type != vbo.memory_type || vbo.size < size) + if (mem_type != vbo.memory_type || static_cast(vbo.size) < size) { vbo.size = static_cast(size); vbo.memory_type = mem_type; @@ -65,9 +65,16 @@ namespace blt::gfx } } - auto unique_vbo_t::bind() + detail::vbo_context_t unique_vbo_t::bind() { BLT_CONTRACT(glfwGetCurrentContext() != nullptr, "Expected active OpenGL context!"); return detail::vbo_context_t{*this}; } + + void unique_ubo_t::set_location(const i32 new_location) + { + BLT_CONTRACT(native_handle().has_value(), "Expected UBO to have an associated buffer! (You are probably calling this on a moved-from value)"); + location = new_location; + glBindBufferBase(GL_UNIFORM_BUFFER, location, *native_handle()); + } }