- More buffer functions
This commit is contained in:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user