Skip to content

Instantly share code, notes, and snippets.

@qookei
Created June 28, 2020 19:12
Show Gist options
  • Save qookei/3f028ba5cdbb2a4b5efd948d8294016a to your computer and use it in GitHub Desktop.
Save qookei/3f028ba5cdbb2a4b5efd948d8294016a to your computer and use it in GitHub Desktop.
#pragma once
#include <epoxy/gl.h>
#include <cassert>
#include <memory>
#include <numeric>
#include <type_traits>
template <GLenum Type, typename Ptr = void *>
struct buffer {
friend void swap(buffer &a, buffer &b) {
using std::swap;
swap(a.id_, b.id_);
swap(a.size_, b.size_);
swap(a.buffer_ptr_, b.buffer_ptr_);
swap(a.usage_, b.usage_);
}
buffer()
:id_{0}, size_{0}, buffer_ptr_{nullptr} {}
~buffer() {
if (buffer_ptr_)
unmap();
glDeleteBuffers(1, &id_);
}
buffer(const buffer &other) = delete;
buffer(buffer &&other)
:id_{0}, size_{0}, buffer_ptr_{nullptr} {
swap(*this, other);
}
buffer &operator=(const buffer &other) = delete;
buffer &operator=(buffer &&other) {
swap(*this, other);
return *this;
}
void bind() {
assert(id_);
glBindBuffer(Type, id_);
}
void unbind() {
glBindBuffer(Type, 0);
}
void generate() {
glGenBuffers(1, &id_);
}
Ptr map() {
bind();
buffer_ptr_ = static_cast<Ptr>(glMapBuffer(Type, GL_READ_WRITE));
unbind();
assert(buffer_ptr_);
return buffer_ptr_;
}
void store(const void *data, size_t offset, size_t size) {
if (!data) {
fmt::print("buffer::store: data = nullptr!\n");
return;
}
if (size_ < (size + offset)) {
fmt::print("buffer::store: buffer overrun, buffer size = {}, store size = {}, store offset = {}", size_, size, offset);
abort();
}
bind();
glBufferSubData(Type, offset, size, data);
unbind();
}
void unmap() {
bind();
glUnmapBuffer(Type);
unbind();
buffer_ptr_ = nullptr;
}
size_t size() const {
return size_;
}
Ptr mapped_buffer() {
return buffer_ptr_;
}
void store_regenerate(const void *data, size_t size, GLenum usage) {
if (size_ == size) {
store(data, 0, size);
return;
}
size_ = size;
bind();
glBufferData(Type, size_, data, usage);
unbind();
}
GLuint id() const {
return id_;
}
private:
GLuint id_;
size_t size_;
Ptr buffer_ptr_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment