main
Brett 2023-12-28 13:05:04 -05:00
parent bc14d16db2
commit 002f5c2ae8
3 changed files with 95 additions and 27 deletions

View File

@ -24,6 +24,7 @@
#include <blt/gfx/gl_includes.h> #include <blt/gfx/gl_includes.h>
#include <variant> #include <variant>
#include <array> #include <array>
#include <blt/std/hashmap.h>
namespace blt::gfx namespace blt::gfx
{ {
@ -40,16 +41,18 @@ namespace blt::gfx
{ {
GLuint bufferID_ = 0; GLuint bufferID_ = 0;
GLsizeiptr size_ = 0; GLsizeiptr size_ = 0;
GLint buffer_type;
GLint memory_type;
void create(); void create(GLint type);
void bind(GLint buffer_type = GL_ARRAY_BUFFER) const; void bind() const;
void allocate(GLsizeiptr size, GLint buffer_type = GL_ARRAY_BUFFER, GLint memory_type = GL_STATIC_DRAW, void* data = nullptr); void allocate(GLsizeiptr size, 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 sub_update(GLsizeiptr offset, GLsizeiptr size, void* data);
void update(GLsizeiptr size, void* data, GLint buffer_type = GL_ARRAY_BUFFER, GLint memory_type = GL_STATIC_DRAW); void update(GLsizeiptr size, void* data);
void destroy(); void destroy();
}; };
@ -68,6 +71,7 @@ namespace blt::gfx
size_t max = 0; size_t max = 0;
void swap(); void swap();
public: public:
static_dynamic_array(); static_dynamic_array();
@ -79,18 +83,10 @@ namespace blt::gfx
static_dynamic_array& operator=(static_dynamic_array&& move) noexcept = default; static_dynamic_array& operator=(static_dynamic_array&& move) noexcept = default;
vbo_t& operator[](size_t index) vbo_t& operator[](size_t index);
{
if (index >= size_)
swap();
max = std::max(index, max);
if (std::holds_alternative<vbo_t*>(data_))
return std::get<vbo_t*>(data_)[index];
else
return std::get<array_t>(data_)[index];
}
[[nodiscard]] size_t used() const noexcept { [[nodiscard]] inline size_t used() const noexcept
{
return max; return max;
} }
@ -107,12 +103,47 @@ namespace blt::gfx
class basic_vertex_array class basic_vertex_array
{ {
private: private:
GLuint vaoID; GLuint vaoID;
static_dynamic_array VBOs; static_dynamic_array VBOs;
HASHSET<GLuint> used_attributes;
vbo_t element;
public: public:
basic_vertex_array(); 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();
}; };
} }

@ -1 +1 @@
Subproject commit b135e5b915e0efaae2f8d9dc30d4752726b74bb4 Subproject commit 5ae17f4a86a021fb914f0c17b116dc511e5f3f93

View File

@ -45,14 +45,26 @@ namespace blt::gfx
std::memset(ptr.data(), 0, DATA_SIZE); std::memset(ptr.data(), 0, DATA_SIZE);
} }
vbo_t& static_dynamic_array::operator[](size_t index)
{
if (index >= size_)
swap();
max = std::max(index, max);
if (std::holds_alternative<vbo_t*>(data_))
return std::get<vbo_t*>(data_)[index];
else
return std::get<array_t>(data_)[index];
}
/* /*
* ----------------------------------- * -----------------------------------
* vbo_t * vbo_t
* ----------------------------------- * -----------------------------------
*/ */
void vbo_t::create() void vbo_t::create(GLint type)
{ {
glGenBuffers(1, &bufferID_); glGenBuffers(1, &bufferID_);
buffer_type = type;
} }
void vbo_t::destroy() void vbo_t::destroy()
@ -60,27 +72,28 @@ namespace blt::gfx
glDeleteBuffers(1, &bufferID_); glDeleteBuffers(1, &bufferID_);
} }
void vbo_t::allocate(GLsizeiptr size, GLint buffer_type, GLint memory_type, void* data) void vbo_t::allocate(GLsizeiptr size, GLint mem_type, void* data)
{ {
size_ = size; size_ = size;
glBufferData(buffer_type, size, data, memory_type); glBufferData(buffer_type, size, data, mem_type);
memory_type = mem_type;
} }
void vbo_t::update(GLsizeiptr size, void* data, GLint buffer_type, GLint memory_type) void vbo_t::update(GLsizeiptr size, void* data)
{ {
if (size <= size_) if (size <= size_)
sub_update(0, size, data, buffer_type); sub_update(0, size, data);
else else
allocate(size, buffer_type, memory_type, data); allocate(size, memory_type, data);
size_ = size; size_ = size;
} }
void vbo_t::sub_update(GLsizeiptr offset, GLsizeiptr size, void* data, GLint buffer_type) void vbo_t::sub_update(GLsizeiptr offset, GLsizeiptr size, void* data)
{ {
glBufferSubData(buffer_type, offset, size, data); glBufferSubData(buffer_type, offset, size, data);
} }
void vbo_t::bind(GLint buffer_type) const void vbo_t::bind() const
{ {
glBindBuffer(buffer_type, bufferID_); glBindBuffer(buffer_type, bufferID_);
} }
@ -95,4 +108,28 @@ namespace blt::gfx
{ {
glGenVertexArrays(1, &vaoID); glGenVertexArrays(1, &vaoID);
} }
basic_vertex_array::~basic_vertex_array()
{
// free all VBOs
for (size_t i = 0; i < VBOs.used(); i++)
if (VBOs[i].bufferID_)
VBOs[i].destroy();
// then free the vertex array
glDeleteVertexArrays(1, &vaoID);
}
void basic_vertex_array::bindVBO(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
{
used_attributes.insert(attribute_number);
bind();
vbo.bind();
glVertexAttribPointer(
attribute_number, coordinate_size, type, GL_FALSE, stride < 0 ? 0 : stride, (void*) offset
);
glEnableVertexAttribArray(attribute_number);
VBOs[attribute_number] = vbo;
}
} }