179 lines
4.0 KiB
C++
179 lines
4.0 KiB
C++
#pragma once
|
|
#ifndef _NB_VERTEX_ARRAY
|
|
#define _NB_VERTEX_ARRAY
|
|
|
|
#include "GLLoad.hpp"
|
|
|
|
#include <NBCore/Errors.hpp>
|
|
|
|
#include "Buffers.hpp"
|
|
#include "OGLObjects.hpp"
|
|
|
|
|
|
namespace nb {
|
|
|
|
struct VertexAttributeLayout {
|
|
int32_t offset = 0;
|
|
GLsizei stride = 0;
|
|
GLuint divisor = 0;
|
|
};
|
|
|
|
struct VertexAttribute {
|
|
GLint GLSLSize;
|
|
GLenum GLSLType;
|
|
GLboolean GLSLNormalization;
|
|
VertexAttributeLayout layout;
|
|
};
|
|
|
|
struct VertexAttributePointer;
|
|
|
|
static bool isIndexInVertexAttribute(int i, const VertexAttribute& va) {
|
|
if ((i -= va.layout.offset) < 0) { return false; }
|
|
return (i%va.layout.stride) < GLSLTypeSize(va.GLSLType) * va.GLSLSize;
|
|
}
|
|
|
|
typedef std::vector<VertexAttribute> VertexAttributeList;
|
|
typedef std::vector<VertexAttributePointer> VertexAttributePointerList;
|
|
|
|
class VAOError : public Error<VAOError> {
|
|
using Base = Error<VAOError>;
|
|
|
|
public:
|
|
using Base::Base;
|
|
|
|
enum Codes : unsigned int {
|
|
UNDEFINED, INVALID_ATTRIBUTE, INVALID_VAO
|
|
};
|
|
|
|
static const std::string type;
|
|
static const ErrorCodeMap ErrorMessages;
|
|
};
|
|
|
|
template <bool Immutable=false>
|
|
class VertexBuffer : public ArrayBuffer<false>{
|
|
using Base = ArrayBuffer<false>;
|
|
|
|
public:
|
|
template<typename... Args>
|
|
VertexBuffer(const VertexAttributeList& vas={}, Args... args)
|
|
: attributes(vas) {
|
|
if (sizeof...(Args)) {
|
|
data(args...);
|
|
}
|
|
}
|
|
VertexBuffer(VertexBuffer&& rhs)
|
|
: attributes(rhs.attributes), Base(std::move(rhs)){}
|
|
|
|
|
|
using Base::Target;
|
|
const VertexAttributeList attributes;
|
|
|
|
protected:
|
|
using Base::_usage;
|
|
|
|
};
|
|
|
|
template <>
|
|
class VertexBuffer<true>
|
|
: public virtual VertexBuffer<false>, public virtual ImmutableBuffer<ArrayBuffer<true>> {
|
|
using Base = ArrayBuffer<false>;
|
|
using BufferType = ImmutableBuffer<ArrayBuffer<true>>;
|
|
using BufferType::BufferType;
|
|
|
|
public:
|
|
using Base::Target;
|
|
|
|
};
|
|
|
|
struct VertexAttributePointer {
|
|
VertexAttribute attribute;
|
|
VertexBuffer<false>* buffer;
|
|
GLuint index;
|
|
};
|
|
|
|
class VAO : public OpenGLObject {
|
|
using Base = OpenGLObject;
|
|
using Codes = VAOError::Codes;
|
|
|
|
public:
|
|
using Base::Base;
|
|
VAO() = default;
|
|
VAO(const VertexAttributePointerList&);
|
|
VAO(VAO&&);
|
|
|
|
VAO& operator=(VAO&&);
|
|
|
|
virtual void bind() const override {
|
|
if(_id) {
|
|
glBindVertexArray(_id);
|
|
} else {
|
|
THROW(VAOError(Codes::INVALID_VAO));
|
|
}
|
|
}
|
|
virtual void unbind() const override { glBindVertexArray(0); }
|
|
|
|
VertexAttributePointerList attributes() const;
|
|
VertexAttributePointerList attributes(const VertexAttributePointerList&);
|
|
VertexAttributePointer attr(GLuint) const;
|
|
void enable() const;
|
|
void enable(GLuint) const;
|
|
void disable() const;
|
|
void disable(GLuint) const;
|
|
|
|
protected:
|
|
using Base::_id;
|
|
VertexAttributePointerList _attrs;
|
|
|
|
virtual void remove() override {
|
|
if(_id) {
|
|
disable();
|
|
bind();
|
|
glDeleteVertexArrays(1, &_id);
|
|
_id = 0;
|
|
}
|
|
}
|
|
virtual GLuint declare() override {
|
|
if (!_id) {
|
|
glGenVertexArrays(1, &_id);
|
|
}
|
|
return _id;
|
|
}
|
|
|
|
};
|
|
|
|
class VertexGroup {
|
|
public:
|
|
VertexGroup(VertexGroup&&);
|
|
VertexGroup& operator=(VertexGroup&&);
|
|
|
|
void bind() const {
|
|
_elmt_buf.bind();
|
|
_vao.bind();
|
|
}
|
|
void unbind() const {
|
|
_vao.bind();
|
|
_elmt_buf.unbind();
|
|
}
|
|
|
|
VertexBuffer<false>& buffer(size_t);
|
|
size_t buffer(VertexBuffer<false>&&);
|
|
std::vector<std::shared_ptr<VertexBuffer<false>>> buffers();
|
|
size_t buffers(std::vector<VertexBuffer<false>>&&);
|
|
VertexBuffer<false>&& dropBuffer(size_t);
|
|
|
|
VertexAttributePointer attribute(size_t) const;
|
|
void enableAttr(GLuint);
|
|
void disableAttr(GLuint);
|
|
void enableBuffer(size_t);
|
|
void disableBuffer(size_t);
|
|
void enable();
|
|
void disable();
|
|
|
|
protected:
|
|
std::vector<std::shared_ptr<VertexBuffer<false>>> _vertex_data;
|
|
ElementBuffer<false> _elmt_buf;
|
|
VAO _vao;
|
|
};
|
|
|
|
} // namespace nb
|
|
#endif // _NB_VERTEX_ARRAY
|