226 lines
5.3 KiB
C++
226 lines
5.3 KiB
C++
#include "VertexArray.hpp"
|
|
|
|
namespace nb {
|
|
|
|
using VAOErrorCodes = VAOError::Codes;
|
|
const std::string VAOError::type = "nb::VAOError";
|
|
const ErrorCodeMap VAOError::ErrorMessages = {
|
|
{ VAOErrorCodes::UNDEFINED, "Error" },
|
|
{ VAOErrorCodes::INVALID_ATTRIBUTE, "Targeting invalid attribute"},
|
|
{ VAOErrorCodes::INVALID_VAO, "Targeting invalid VAO" }
|
|
};
|
|
|
|
VAO::VAO(const VertexAttributePointerList& attr_ptrs) {
|
|
attributes(attr_ptrs);
|
|
}
|
|
|
|
VAO::VAO(VAO&& other) {
|
|
*this = std::move(other);
|
|
}
|
|
|
|
VAO& VAO::operator=(VAO&& rhs) {
|
|
_id = rhs._id;
|
|
_attrs = rhs._attrs;
|
|
|
|
rhs._id = 0;
|
|
rhs._attrs = {};
|
|
|
|
return *this;
|
|
}
|
|
|
|
VertexAttributePointerList VAO::attributes() const {
|
|
return _attrs;
|
|
}
|
|
|
|
VertexAttributePointerList VAO::attributes(const VertexAttributePointerList& attrs_) {
|
|
declare();
|
|
disable();
|
|
_attrs = attrs_;
|
|
bind();
|
|
for (auto attr_ptr : attrs_) {
|
|
attr_ptr.buffer->bind();
|
|
GLuint idx = attr_ptr.index;
|
|
glVertexAttribPointer(
|
|
idx,
|
|
attr_ptr.attribute.GLSLSize,
|
|
attr_ptr.attribute.GLSLType,
|
|
attr_ptr.attribute.GLSLNormalization,
|
|
attr_ptr.attribute.layout.stride,
|
|
(void*)attr_ptr.attribute.layout.offset
|
|
);
|
|
glEnableVertexAttribArray(idx);
|
|
}
|
|
unbind();
|
|
return _attrs;
|
|
}
|
|
|
|
VertexAttributePointer VAO::attr(GLuint idx) const {
|
|
for (auto attr_ptr : _attrs) {
|
|
if (idx == attr_ptr.index) {
|
|
return attr_ptr;
|
|
}
|
|
}
|
|
THROW(BufferError(Codes::INVALID_ATTRIBUTE));
|
|
}
|
|
|
|
void VAO::enable() const {
|
|
if (_id) {
|
|
bind();
|
|
for(auto attr_ptr : _attrs) {
|
|
glEnableVertexAttribArray(attr_ptr.index);
|
|
}
|
|
unbind();
|
|
}
|
|
}
|
|
|
|
void VAO::enable(GLuint idx) const {
|
|
if(_id) {
|
|
bind();
|
|
glEnableVertexAttribArray(attr(idx).index);
|
|
unbind();
|
|
}
|
|
}
|
|
|
|
void VAO::disable() const {
|
|
if(_id) {
|
|
bind();
|
|
for(auto attr_ptr : _attrs) {
|
|
glDisableVertexAttribArray(attr_ptr.index);
|
|
}
|
|
unbind();
|
|
}
|
|
}
|
|
|
|
void VAO::disable(GLuint idx) const {
|
|
if(_id) {
|
|
bind();
|
|
glDisableVertexAttribArray(attr(idx).index);
|
|
unbind();
|
|
}
|
|
}
|
|
|
|
VertexGroup::VertexGroup(VertexGroup&& other) {
|
|
*this = std::move(other);
|
|
}
|
|
|
|
VertexGroup& VertexGroup::operator=(VertexGroup&& rhs) {
|
|
_vertex_data = rhs._vertex_data;
|
|
_elmt_buf = std::move(rhs._elmt_buf);
|
|
_vao = std::move(rhs._vao);
|
|
|
|
rhs._vertex_data = {};
|
|
rhs._elmt_buf = ElementBuffer<false>();
|
|
rhs._vao = VAO();
|
|
|
|
return *this;
|
|
}
|
|
|
|
size_t VertexGroup::buffer(VertexBuffer<false>&& buf_) {
|
|
_vertex_data.emplace_back(
|
|
std::make_shared<VertexBuffer<false>>(std::move(buf_))
|
|
);
|
|
VertexBuffer<false>* buf_ptr = _vertex_data.back().get();
|
|
VertexAttributePointerList attrs = _vao.attributes();
|
|
GLuint idx = attrs.size();
|
|
for (auto attr : buf_ptr->attributes) {
|
|
attrs.emplace_back(
|
|
VertexAttributePointer{attr, buf_ptr,idx}
|
|
);
|
|
idx++;
|
|
}
|
|
_vao.attributes(attrs);
|
|
return _vertex_data.size();
|
|
}
|
|
|
|
VertexBuffer<false>& VertexGroup::buffer(size_t idx) {
|
|
return *_vertex_data[idx];
|
|
}
|
|
|
|
std::vector<std::shared_ptr<VertexBuffer<false>>> VertexGroup::buffers() {
|
|
return _vertex_data;
|
|
}
|
|
|
|
size_t VertexGroup::buffers(std::vector<VertexBuffer<false>>&& bufs_) {
|
|
_vertex_data.clear();
|
|
for (auto& buf : bufs_) {
|
|
_vertex_data.emplace_back(
|
|
std::make_shared<VertexBuffer<false>>(std::move(buf))
|
|
);
|
|
}
|
|
VertexAttributePointerList attr_ptrs;
|
|
GLuint idx = 0;
|
|
for (auto buf : _vertex_data) {
|
|
for (auto attr : buf->attributes) {
|
|
attr_ptrs.emplace_back(
|
|
VertexAttributePointer{attr, buf.get(), idx}
|
|
);
|
|
idx++;
|
|
}
|
|
}
|
|
_vao.attributes(attr_ptrs);
|
|
return _vertex_data.size();
|
|
}
|
|
|
|
VertexBuffer<false>&& VertexGroup::dropBuffer(size_t idx) {
|
|
if (idx >= _vertex_data.size()) {
|
|
THROW(BufferError(BufferError::Codes::INVALID_BUFFER));
|
|
}
|
|
std::vector<VertexBuffer<false>> tmp;
|
|
std::shared_ptr<VertexBuffer<false>> ret_ptr;
|
|
size_t i = 0;
|
|
for (auto buf : _vertex_data) {
|
|
if (i == idx) {
|
|
ret_ptr = std::make_shared<VertexBuffer<false>>(std::move(tmp[idx]));
|
|
} else {
|
|
tmp.emplace_back(std::move(*buf));
|
|
}
|
|
i++;
|
|
}
|
|
buffers(std::move(tmp));
|
|
return std::move(*ret_ptr);
|
|
}
|
|
|
|
VertexAttributePointer VertexGroup::attribute(size_t idx_) const {
|
|
return _vao.attr(idx_);
|
|
}
|
|
|
|
void VertexGroup::enableAttr(GLuint idx) {
|
|
bind();
|
|
_vao.enable(idx);
|
|
unbind();
|
|
}
|
|
|
|
void VertexGroup::disableAttr(GLuint idx) {
|
|
bind();
|
|
_vao.disable(idx);
|
|
unbind();
|
|
}
|
|
|
|
void VertexGroup::disableBuffer(size_t idx) {
|
|
auto buf_ptr = _vertex_data[idx].get();
|
|
bind();
|
|
for (auto attr : _vao.attributes()) {
|
|
if (attr.buffer == buf_ptr) {
|
|
_vao.disable(attr.index);
|
|
}
|
|
}
|
|
unbind();
|
|
}
|
|
|
|
void VertexGroup::enableBuffer(size_t idx) {
|
|
auto buf_ptr = _vertex_data[idx].get();
|
|
bind();
|
|
for (auto attr : _vao.attributes()) {
|
|
if (attr.buffer == buf_ptr) {
|
|
_vao.enable(attr.index);
|
|
}
|
|
}
|
|
unbind();
|
|
}
|
|
|
|
void VertexGroup::enable() { _vao.enable(); }
|
|
|
|
void VertexGroup::disable() { _vao.disable(); }
|
|
|
|
} // namespace nb
|