#include namespace nb { const ConstantMap BufferTypes({ {GL_ARRAY_BUFFER, "GL_ARRAY_BUFFER"}, {GL_ELEMENT_ARRAY_BUFFER, "GL_ELEMENT_BUFFER"} }); using BufferErrorCodes = BufferError::Codes; const std::string BufferError::type = "nb::BufferError"; const ErrorCodeMap BufferError::ErrorMessages = { { BufferErrorCodes::UNDEFINED, "Error" }, { BufferErrorCodes::DATA_OVERFLOW, "Attempting buffer overflow" }, {BufferErrorCodes::DATA_ERROR, "Invalid memory operation"} }; Buffer::Buffer(Buffer&& rval) : Target(rval.Target) { *this = std::move(rval); } Buffer& Buffer::operator=(Buffer&& rhs) { if (Target != rhs.Target) { auto targ_name = BufferTypes[Target]; THROW(OpenGLObjectError( OpenGLObjectError::Codes::INVALID_OBJECT, "w/ BufferType "+targ_name+" != BufferType "+BufferTypes[Target] )); } OpenGLObject::operator=(std::move(rhs)); _usage = rhs._usage; _size = rhs._size; rhs._usage = GL_STATIC_DRAW; rhs._size = 0; return *this; } GLenum Buffer::usage() const { return _usage; } size_t Buffer::size() const { return _size; } ByteVector Buffer::data() const { bind(); ByteVector ret(_size); OPENGL_CALL(glGetBufferSubData(Target, 0, _size, ret.data())); return ret; } void Buffer::data(const void* data_, size_t size_, GLenum usage_) { declare(); OPENGL_CALL(glBufferData(Target, size_, data_, usage_)); _size = size_; _usage = usage_; } void Buffer::data(const ByteVector& data_, GLenum usage_) { declare(); data(data_.data(), data_.size(), usage_); } void Buffer::subdata(const void* data_, size_t size_, GLintptr offset_) { bind(); if (offset_+size_ <= _size) { THROW(BufferError(BufferError::Codes::DATA_OVERFLOW)); } OPENGL_CALL(glBufferSubData(Target, offset_, size_, data_)); } void Buffer::subdata(const ByteVector& data_, GLintptr offset_) { bind(); size_t size_ = data_.size(); subdata(data_.data(), size_); } ElementBuffer::ElementBuffer() : Buffer(GL_ELEMENT_ARRAY_BUFFER) {} ByteVector ElementBuffer::data() const { return data(); } size_t ElementBuffer::size() const { return _size / _typeSize; } size_t ElementBuffer::typeSize() const { return _typeSize; } GLenum ElementBuffer::glslType() const { return _glslType; } template void ElementBuffer::data(const std::vector& data, GLenum usage); template void ElementBuffer::data(const std::vector& data, GLenum usage); template void ElementBuffer::data(const std::vector& data, GLenum usage); template void ElementBuffer::data(const uint8_t* const data, size_t size, GLenum usage); template void ElementBuffer::data(const uint16_t* const data, size_t size, GLenum usage); template void ElementBuffer::data(const uint32_t* const data, size_t size, GLenum usage); template void ElementBuffer::subdata(const uint8_t* const data, size_t size, size_t offset=0); template void ElementBuffer::subdata(const uint16_t* const data, size_t size, size_t offset=0); template void ElementBuffer::subdata(const uint32_t* const data, size_t size, size_t offset=0); template void ElementBuffer::subdata(const std::vector& data, size_t offset=0); template void ElementBuffer::subdata(const std::vector& data, size_t offset=0); template void ElementBuffer::subdata(const std::vector& data, size_t offset=0); }