- More buffer functions

This commit is contained in:
2025-08-03 02:10:27 -04:00
parent 5e04eb0ca6
commit 9dc9ed4ed1
2 changed files with 80 additions and 14 deletions

View File

@@ -31,6 +31,9 @@ namespace gl
template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV = false> template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV = false>
class buffer { class buffer {
// HELPER FUNCTIONS ====================================================================================================
private: private:
static constexpr GLenum get_mutable_traits() { static constexpr GLenum get_mutable_traits() {
GLenum res; GLenum res;
@@ -56,6 +59,9 @@ private:
return res; return res;
} }
// CONSTANTS ===========================================================================================================
public: public:
static constexpr GLenum type = TypeV; static constexpr GLenum type = TypeV;
static constexpr GLboolean immutable = ImmutableV; static constexpr GLboolean immutable = ImmutableV;
@@ -72,7 +78,10 @@ public:
static_assert(not persistent or persistent == mapped); static_assert(not persistent or persistent == mapped);
static_assert(not coherent or coherent == persistent); static_assert(not coherent or coherent == persistent);
constexpr buffer(void* data, GLsizeiptr size)
// CONSTRUCTORS & ASSIGNMENT ===========================================================================================
constexpr buffer(const void* data, GLsizeiptr size)
: _handle() : _handle()
, _size(size) { , _size(size) {
glGenBuffers(1, &_handle); glGenBuffers(1, &_handle);
@@ -87,7 +96,8 @@ public:
constexpr buffer(buffer&& buff) noexcept constexpr buffer(buffer&& buff) noexcept
: _handle(buff) : _handle(buff)
, _size(buff._size) { , _size(buff._size)
, _mapping(nullptr) {
} }
constexpr buffer(const buffer&) = delete; constexpr buffer(const buffer&) = delete;
@@ -99,6 +109,9 @@ public:
return *this; return *this;
} }
// OBJECT FUNCTIONS ====================================================================================================
constexpr void start() const { constexpr void start() const {
glBindBuffer(type, _handle); glBindBuffer(type, _handle);
} }
@@ -107,14 +120,38 @@ public:
glBindBuffer(type, NULL); glBindBuffer(type, NULL);
} }
constexpr void clear(GLsizeiptr size, GLintptr offset = 0, const void* data = nullptr, GLenum data_type = BYTE, GLenum format = R, GLenum internal = R8) {
// BASIC BUFFER FUNCTIONS ==============================================================================================
constexpr void* map(GLbitfield access, GLsizeiptr size, GLintptr offset = 0) {
if (_mapping) {
return _mapping;
}
offset = max(offset, GLintptr(0));
size = size < 0 ? _size : size;
size = min(size, _size - offset);
if (size <= 0) return nullptr;
return _mapping = glMapBufferRange(type, offset, size, _mapflags = access);
}
constexpr void unmap() {
glUnmapBuffer(type);
_mapping = nullptr;
}
constexpr void clear(GLsizeiptr size = -1, GLintptr offset = 0, const void* data = nullptr, GLenum data_type = BYTE, GLenum format = R, GLenum internal = R8) {
offset = max(offset, GLintptr(0));
size = size < 0 ? _size : size;
size = min(size, _size - offset); size = min(size, _size - offset);
if (size <= 0) return; if (size <= 0) return;
glClearBufferSubData(type, internal, offset, size, format, type, data); glClearBufferSubData(type, internal, offset, size, format, type, data);
} }
template<GLenum OTypeV, GLbitfield OFlagsV, GLboolean OImmutableV> template<GLenum OTypeV, GLbitfield OFlagsV, GLboolean OImmutableV>
constexpr void copy(const buffer<OTypeV, OFlagsV, OImmutableV>& cpy, GLsizeiptr size, GLintptr write_offset = 0, GLintptr read_offset = 0) { constexpr void copy(const buffer<OTypeV, OFlagsV, OImmutableV>& cpy, GLsizeiptr size = -1, GLintptr write_offset = 0, GLintptr read_offset = 0) {
write_offset = max(write_offset, GLintptr(0));
read_offset = max(read_offset, GLintptr(0));
size = size < 0 ? _size : size;
size = fennec::min(size, cpy._size - read_offset); size = fennec::min(size, cpy._size - read_offset);
size = fennec::min(size, _size - write_offset); size = fennec::min(size, _size - write_offset);
if (size <= 0) return; if (size <= 0) return;
@@ -125,21 +162,42 @@ public:
glBindBuffer(COPY_WRITE, NULL); glBindBuffer(COPY_WRITE, NULL);
} }
constexpr void write(const void* data, GLsizeiptr size, GLintptr offset = 0) { constexpr void write(const void* data, GLsizeiptr size = -1, GLintptr offset = 0) {
static_assert(dynamic or persistent and not (client or coherent)); static_assert(dynamic or persistent and not (client or coherent));
offset = max(offset, GLintptr(0));
size = size < 0 ? _size : size;
size = min(size, _size - offset); size = min(size, _size - offset);
if (size <= 0) return;
glBufferSubData(type, offset, size, data); glBufferSubData(type, offset, size, data);
} }
constexpr void resize() constexpr void flush(GLsizeiptr size = -1, GLintptr offset = 0) {
if (not _mapping) return;
if (not (_mapflags & EXPLICIT_FLUSH)) return;
offset = max(offset, GLintptr(0));
size = size < 0 ? _size : size;
size = min(size, _size - offset);
if (size <= 0) return;
glFlushMappedBufferRange(type, offset, size);
}
constexpr void map() {
// TYPED FUNCTIONS =====================================================================================================
template<typename TypeT>
constexpr TypeT* map(GLbitfield access, GLsizeiptr n, GLintptr offset = 0) {
return static_cast<TypeT*>(map(access, n * sizeof(TypeT), offset * sizeof(TypeT)));
}
constexpr void clear(float x, GLsizeiptr n, GLintptr offset = 0) {
clear(n * sizeof(float), offset * sizeof(float), &x, FLOAT, R, R32F);
} }
private: private:
GLuint _handle; GLuint _handle;
GLsizeiptr _size; GLsizeiptr _size;
void* _mapping;
GLbitfield _mapflags;
}; };
} }

View File

@@ -43,13 +43,19 @@ enum buffer_ : GLenum {
}; };
enum buffer_flag_ : GLbitfield { enum buffer_flag_ : GLbitfield {
NONE = 0, READ = GL_MAP_READ_BIT,
READ = GL_MAP_READ_BIT, WRITE = GL_MAP_WRITE_BIT,
WRITE = GL_MAP_WRITE_BIT, DYNAMIC = GL_DYNAMIC_STORAGE_BIT,
DYNAMIC = GL_DYNAMIC_STORAGE_BIT, PERSISTENT = GL_MAP_PERSISTENT_BIT,
PERSISTENT = GL_MAP_PERSISTENT_BIT, COHERENT = GL_MAP_COHERENT_BIT,
COHERENT = GL_MAP_COHERENT_BIT, CLIENT = GL_CLIENT_STORAGE_BIT,
CLIENT = GL_CLIENT_STORAGE_BIT, EXPLICIT_FLUSH = GL_MAP_FLUSH_EXPLICIT_BIT,
};
enum access_ : GLbitfield {
READ_ONLY = GL_READ_ONLY,
WRITE_ONLY = GL_WRITE_ONLY,
READ_WRITE = GL_READ_WRITE,
}; };
enum type_ : GLenum { enum type_ : GLenum {
@@ -57,12 +63,14 @@ enum type_ : GLenum {
BVEC2 = GL_BOOL_VEC2, BVEC2 = GL_BOOL_VEC2,
BVEC3 = GL_BOOL_VEC3, BVEC3 = GL_BOOL_VEC3,
BVEC4 = GL_BOOL_VEC4, BVEC4 = GL_BOOL_VEC4,
BYTE = GL_BYTE, BYTE = GL_BYTE,
SHORT = GL_SHORT, SHORT = GL_SHORT,
INT = GL_INT, INT = GL_INT,
IVEC2 = GL_INT_VEC2, IVEC2 = GL_INT_VEC2,
IVEC3 = GL_INT_VEC3, IVEC3 = GL_INT_VEC3,
IVEC4 = GL_INT_VEC4, IVEC4 = GL_INT_VEC4,
UBYTE = GL_UNSIGNED_BYTE, UBYTE = GL_UNSIGNED_BYTE,
USHORT = GL_UNSIGNED_SHORT, USHORT = GL_UNSIGNED_SHORT,
UINT = GL_UNSIGNED_INT, UINT = GL_UNSIGNED_INT,