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 <variant>
#include <array>
#include <blt/std/hashmap.h>
namespace blt::gfx
{
@ -40,16 +41,18 @@ namespace blt::gfx
{
GLuint bufferID_ = 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();
};
@ -68,6 +71,7 @@ namespace blt::gfx
size_t max = 0;
void swap();
public:
static_dynamic_array();
@ -79,18 +83,10 @@ namespace blt::gfx
static_dynamic_array& operator=(static_dynamic_array&& move) noexcept = default;
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];
}
vbo_t& operator[](size_t index);
[[nodiscard]] size_t used() const noexcept {
[[nodiscard]] inline size_t used() const noexcept
{
return max;
}
@ -107,12 +103,47 @@ namespace blt::gfx
class basic_vertex_array
{
private:
GLuint vaoID;
static_dynamic_array VBOs;
HASHSET<GLuint> 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();
};
}

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

View File

@ -45,14 +45,26 @@ namespace blt::gfx
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
* -----------------------------------
*/
void vbo_t::create()
void vbo_t::create(GLint type)
{
glGenBuffers(1, &bufferID_);
buffer_type = type;
}
void vbo_t::destroy()
@ -60,27 +72,28 @@ namespace blt::gfx
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;
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_)
sub_update(0, size, data, buffer_type);
sub_update(0, size, data);
else
allocate(size, buffer_type, memory_type, data);
allocate(size, memory_type, data);
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);
}
void vbo_t::bind(GLint buffer_type) const
void vbo_t::bind() const
{
glBindBuffer(buffer_type, bufferID_);
}
@ -95,4 +108,28 @@ namespace blt::gfx
{
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;
}
}