diff options
-rw-r--r-- | lib/glMappedBufferWriter.cpp | 4 | ||||
-rw-r--r-- | lib/glMappedBufferWriter.h | 78 |
2 files changed, 82 insertions, 0 deletions
diff --git a/lib/glMappedBufferWriter.cpp b/lib/glMappedBufferWriter.cpp new file mode 100644 index 0000000..cc3c413 --- /dev/null +++ b/lib/glMappedBufferWriter.cpp @@ -0,0 +1,4 @@ +#include "glMappedBufferWriter.h" +#include <iterator> + +static_assert(std::weakly_incrementable<glMappedBufferWriter<int>>); diff --git a/lib/glMappedBufferWriter.h b/lib/glMappedBufferWriter.h new file mode 100644 index 0000000..f97d7e1 --- /dev/null +++ b/lib/glMappedBufferWriter.h @@ -0,0 +1,78 @@ +#pragma once + +#include "special_members.h" +#include <cstddef> +#include <glad/gl.h> +#include <utility> + +template<typename T> class glMappedBufferWriter { +public: + using difference_type = std::ptrdiff_t; + + glMappedBufferWriter(GLenum target, GLuint buffer, size_t count, GLenum usage = GL_STATIC_DRAW) : + target {target}, data {[&]() { + glBindBuffer(target, buffer); + glBufferData(target, static_cast<GLsizeiptr>(sizeof(T) * count), nullptr, usage); + return static_cast<T *>(glMapBuffer(target, GL_WRITE_ONLY)); + }()} + { + } + + ~glMappedBufferWriter() + { + if (target) { + glUnmapBuffer(target); + } + } + + glMappedBufferWriter(glMappedBufferWriter && other) noexcept : + target {std::exchange(other.target, 0)}, data {std::exchange(other.data, nullptr)} + { + } + + glMappedBufferWriter & + operator=(glMappedBufferWriter && other) noexcept + { + if (target) { + glUnmapBuffer(target); + } + target = std::exchange(other.target, 0); + data = std::exchange(other.data, nullptr); + return *this; + } + + NO_COPY(glMappedBufferWriter); + + glMappedBufferWriter & + operator++() + { + data++; + return *this; + } + + glMappedBufferWriter & + operator++(int) + { + glMappedBufferWriter rtn {data}; + data++; + return rtn; + } + + T & + operator*() + { + return *data; + } + + T * + operator->() const + { + return data; + } + +private: + explicit glMappedBufferWriter(T * data) : target {0}, data {data} { } + + GLenum target; + T * data; +}; |