Project restructure
This commit is contained in:
@@ -0,0 +1,367 @@
|
||||
#pragma once
|
||||
#ifndef _NB_BUFFER
|
||||
#define _NB_BUFFER
|
||||
|
||||
#include "GLLoad.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "NBCore/Errors.hpp"
|
||||
#include "NBCore/Types.hpp"
|
||||
|
||||
namespace nb {
|
||||
|
||||
typedef std::vector<unsigned char> RawVec;
|
||||
|
||||
static uint8_t GLSLTypeSize(GLenum type) {
|
||||
switch(type) {
|
||||
case GL_SHORT:
|
||||
case GL_UNSIGNED_SHORT:
|
||||
case GL_HALF_FLOAT:
|
||||
return 2;
|
||||
break;
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_FLOAT:
|
||||
return 4;
|
||||
break;
|
||||
case GL_DOUBLE:
|
||||
return 8;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct VertexAttributePointer {
|
||||
GLuint buffer = 0;
|
||||
int32_t offset = 0;
|
||||
GLsizei stride = -1;
|
||||
GLuint divisor = 0;
|
||||
};
|
||||
|
||||
struct VertexAttribute {
|
||||
GLint GLSLSize;
|
||||
GLenum GLSLType;
|
||||
GLboolean GLSLNormalization;
|
||||
VertexAttributePointer ptr;
|
||||
};
|
||||
|
||||
static bool isIndexInVertexAttribute(int i, const VertexAttribute& va) {
|
||||
if ((i -= va.ptr.offset) < 0) { return false; }
|
||||
return (i%va.ptr.stride) < GLSLTypeSize(va.GLSLType) * va.GLSLSize;
|
||||
}
|
||||
|
||||
typedef std::vector<VertexAttribute> VertexAttributeList;
|
||||
|
||||
template<typename T>
|
||||
RawVec vectorToRaw(const std::vector<T>& vec) {
|
||||
unsigned int num_bytes = vec.size() * sizeof(T);
|
||||
RawVec ret(num_bytes);
|
||||
memcpy(ret.data(), vec.data(), num_bytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
RawVec concatVectorsToRaw(const std::vector<T>& vec1, const std::vector<S>& vec2) {
|
||||
RawVec vec1_raw = vectorToRaw<T>(vec1);
|
||||
RawVec vec2_raw = vectorToRaw<S>(vec2);
|
||||
unsigned int vec1_raw_size = vec1_raw.size();
|
||||
unsigned int vec2_raw_size = vec2_raw.size();
|
||||
RawVec ret(vec1_raw_size + vec2_raw_size);
|
||||
memcpy(ret.data(), vec1_raw.data(), vec1_raw_size);
|
||||
memcpy(ret.data() + vec1_raw_size, vec2_raw.data(), vec2_raw_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> rawToVector(const RawVec& vec) {
|
||||
if (vec.size() % sizeof(T) != 0) {
|
||||
throw std::runtime_error("Data size does not align to std::vector<" + std::string(typeid(T).name()) + ">.");
|
||||
}
|
||||
unsigned int num_elmts = vec.size() / sizeof(T);
|
||||
std::vector<T> ret(num_elmts);
|
||||
memcpy(ret.data(), vec.data(), vec.size());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
class BufferError : public std::runtime_error {
|
||||
public:
|
||||
const bool error;
|
||||
BufferError(const std::string& msg, const std::string& file="", int line=-1)
|
||||
: std::runtime_error(NB::formatDebugString(msg, file, line)), error(true) {}
|
||||
BufferError(bool isError=true) : std::runtime_error(""), error(isError) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename ObjectType>
|
||||
class OpenGLObject {
|
||||
public:
|
||||
OpenGLObject(OpenGLObject&&) = default;
|
||||
OpenGLObject& operator=(OpenGLObject&&) = default;
|
||||
~OpenGLObject() { remove(); }
|
||||
|
||||
virtual void bind() const = 0;
|
||||
virtual void unbind() const = 0;
|
||||
virtual bool isInitialized() const = 0;
|
||||
GLuint id() const { return _id; }
|
||||
|
||||
protected:
|
||||
OpenGLObject() = default;
|
||||
OpenGLObject(const OpenGLObject&) = delete;
|
||||
OpenGLObject& operator=(const OpenGLObject&) = delete;
|
||||
|
||||
virtual void remove() const = 0;
|
||||
|
||||
GLuint _id;
|
||||
};
|
||||
|
||||
class VAO : public virtual OpenGLObject<VAO> {
|
||||
public:
|
||||
using Base = OpenGLObject<VAO>;
|
||||
using Base::Base;
|
||||
|
||||
VAO() { glGenVertexArrays(1, &_id); }
|
||||
|
||||
void bind() const { glBindVertexArray(_id); }
|
||||
void unbind() const { glBindVertexArray(0); }
|
||||
|
||||
|
||||
protected:
|
||||
using Base::_id;
|
||||
const
|
||||
|
||||
void remove() { glDeleteVertexArrays(1, &_id); }
|
||||
|
||||
};
|
||||
|
||||
template <typename BufferType>
|
||||
class Buffer : public virtual OpenGLObject<Buffer<BufferType>> {
|
||||
public:
|
||||
using Base = OpenGLObject<Buffer>;
|
||||
using Base::Base;
|
||||
|
||||
Buffer(GLenum usage_ = GL_STATIC_DRAW) : usage(usage_) { glGenBuffers(1, &_id); }
|
||||
|
||||
void bind() const { glBindBuffer(GLTarget, _id); }
|
||||
void unbind() const { glBindBuffer(GLTarget, 0); }
|
||||
void data(void* data_, size_t size) const { glBufferData(GLTarget, size, data_, usage); }
|
||||
void data(nb::ByteVector& data_) const { glBufferData(GLTarget, data_.size(), data_.data(), usage); }
|
||||
void invalidate() const { glInvalidateBufferData(_id); }
|
||||
|
||||
|
||||
const GLenum GLTarget = BufferType::GLTarget;
|
||||
GLenum usage;
|
||||
|
||||
protected:
|
||||
using Base::_id;
|
||||
void remove() { glDeleteBuffers(1, &_id); }
|
||||
|
||||
};
|
||||
|
||||
class VertexBuffer : public virtual Buffer<VertexBuffer> {
|
||||
public:
|
||||
|
||||
static const GLenum GLTarget = GL_ARRAY_BUFFER;
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
class ElementBuffer : public virtual Buffer<ElementBuffer> {
|
||||
public:
|
||||
|
||||
static const GLenum GLTarget = GL_ELEMENT_ARRAY_BUFFER;
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
class Buffer : public OpenGLObject {
|
||||
public:
|
||||
Buffer(
|
||||
GLenum buffer_type,
|
||||
GLenum usage=GL_STATIC_DRAW
|
||||
) : _type(buffer_type), _usage(usage) {
|
||||
glGenBuffers(1, &_id);
|
||||
}
|
||||
Buffer(
|
||||
const RawVec& init_data,
|
||||
GLenum buffer_type,
|
||||
GLenum usage=GL_STATIC_DRAW
|
||||
) : _type{buffer_type}, _usage{usage} { data(init_data); }
|
||||
Buffer(
|
||||
unsigned int size,
|
||||
GLenum buffer_type,
|
||||
GLenum usage=GL_STATIC_DRAW
|
||||
) : Buffer(RawVec(size), buffer_type, usage) {}
|
||||
|
||||
Buffer(Buffer&& rhs) { *this = std::move(rhs); }
|
||||
Buffer& operator=(Buffer&& rhs) {
|
||||
remove();
|
||||
_usage = rhs._usage;
|
||||
_id = rhs._id;
|
||||
rhs._id = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLenum usage() const { return _usage; }
|
||||
unsigned int id() const { return _id; }
|
||||
GLuint size() const { return _size; }
|
||||
bool isInitialized() const override { return _id && glIsBuffer(_id) && bool(_size); }
|
||||
RawVec data() const {
|
||||
RawVec ret(_size);
|
||||
bind();
|
||||
glGetBufferSubData(_type, 0, _size, ret.data());
|
||||
return ret;
|
||||
}
|
||||
void bind() const override { glBindBuffer(_type, _id); }
|
||||
void unbind() const override { glBindBuffer(_type, 0); }
|
||||
|
||||
GLenum usage(GLenum usage) {
|
||||
_usage=usage;
|
||||
data(data());
|
||||
return _usage;
|
||||
}
|
||||
void data(const RawVec& set_data) {
|
||||
if (!glfwGetCurrentContext()) {
|
||||
THROW_BUFFER_ERROR("No OpenGL context.");
|
||||
}
|
||||
bind();
|
||||
glBufferData(_type, set_data.size(), set_data.data(), _usage);
|
||||
_size = set_data.size();
|
||||
}
|
||||
void data(const RawVec& newData, unsigned int offset) {
|
||||
if (newData.size()+offset > _size) {
|
||||
THROW_BUFFER_ERROR("Attempting to overflow buffer of capacity " + std::to_string(_size) + ".");
|
||||
}
|
||||
bind();
|
||||
glBufferSubData(_type, offset, newData.size(), newData.data());
|
||||
}
|
||||
void data(void* src, unsigned int offset, unsigned int size) {
|
||||
if (size+offset > _size) {
|
||||
THROW_BUFFER_ERROR("Attempting to overflow buffer of capacity " + std::to_string(_size) + ".");
|
||||
}
|
||||
bind();
|
||||
glBufferSubData(_type, offset, size, src);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void remove() const override {
|
||||
unbind();
|
||||
if (_id) { glDeleteBuffers(1, &_id); }
|
||||
}
|
||||
|
||||
using OpenGLObject::_id;
|
||||
GLenum _type;
|
||||
GLenum _usage;
|
||||
unsigned int _size = 0;
|
||||
};
|
||||
|
||||
|
||||
class Texture : public OpenGLObject {
|
||||
public:
|
||||
Texture(GLenum tar=GL_TEXTURE_2D) : _target(tar) { glGenTextures(1, &_id); }
|
||||
|
||||
Texture(Texture&& rhs) { *this=std::move(rhs); }
|
||||
Texture& operator=(Texture&& rhs) {
|
||||
_target = rhs._target;
|
||||
_id = rhs._id;
|
||||
rhs._id = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void bind() const override { glBindTexture(_target, _id); }
|
||||
void unbind() const override { glBindTexture(_target, 0); }
|
||||
bool isInitialized() const override { return _id && glIsTexture(_id); }
|
||||
|
||||
protected:
|
||||
using OpenGLObject::_id;
|
||||
GLenum _target;
|
||||
};
|
||||
|
||||
class Framebuffer : public OpenGLObject {
|
||||
public:
|
||||
|
||||
Framebuffer(GLenum tar=GL_FRAMEBUFFER) : _target(tar) { glGenFramebuffers(1, &_id); }
|
||||
|
||||
Framebuffer(Framebuffer&& rhs) { *this=std::move(rhs); }
|
||||
Framebuffer& operator=(Framebuffer&& rhs) {
|
||||
remove();
|
||||
_target = rhs._target;
|
||||
_id = rhs._id;
|
||||
rhs._id = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void bind() const override { glBindFramebuffer(_target, _id); }
|
||||
void unbind() const override { glBindFramebuffer(_target, 0); }
|
||||
bool isInitialized() const override { return _id && glIsFramebuffer(_id); }
|
||||
GLenum status() const {
|
||||
bind();
|
||||
return glCheckFramebufferStatus(_target);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual void remove() const override {
|
||||
unbind();
|
||||
if (_id) { glDeleteFramebuffers(1, &_id); }
|
||||
}
|
||||
using OpenGLObject::_id;
|
||||
GLenum _target;
|
||||
};
|
||||
|
||||
class Renderbuffer : public OpenGLObject {
|
||||
public:
|
||||
Renderbuffer(unsigned int x, unsigned int y, GLenum format=GL_RGBA32F, unsigned int multi=0) : Renderbuffer() {
|
||||
storage(x, y, format, multi);
|
||||
}
|
||||
Renderbuffer() { glGenRenderbuffers(1, &_id); }
|
||||
|
||||
|
||||
Renderbuffer(Renderbuffer&& rhs) { *this = std::move(rhs); }
|
||||
Renderbuffer& operator=(Renderbuffer&& rhs) {
|
||||
_format = rhs._format;
|
||||
_id = rhs._id;
|
||||
rhs._id = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void bind() const override { glBindRenderbuffer(GL_RENDERBUFFER, _id); }
|
||||
virtual void unbind() const override { glBindRenderbuffer(GL_RENDERBUFFER, _id); }
|
||||
virtual bool isInitialized() const override { return _id && glIsRenderbuffer(_id); }
|
||||
|
||||
void storage(unsigned int x, unsigned int y, GLenum format=GL_RGBA32F, unsigned int multi=0) {
|
||||
_sizex = x;
|
||||
_sizey = y;
|
||||
_format = format;
|
||||
_multisample = multi;
|
||||
bind();
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, _multisample, _format, _sizex, _sizey);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual void remove() const override {
|
||||
unbind();
|
||||
if (_id) { glDeleteRenderbuffers(1, &_id); }
|
||||
}
|
||||
|
||||
using OpenGLObject::_id;
|
||||
GLenum _format;
|
||||
unsigned int _sizex{0};
|
||||
unsigned int _sizey{0};
|
||||
unsigned int _multisample{0};
|
||||
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
} // namespace NB
|
||||
#endif // _NB_BUFFER
|
||||
@@ -0,0 +1,151 @@
|
||||
#pragma once
|
||||
#ifndef _NB_CAMERA
|
||||
#define _NB_CAMERA
|
||||
|
||||
#include <GLLoad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_inverse.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
namespace NB {
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
typedef glm::vec3 Vec3;
|
||||
typedef glm::mat4 Mat4;
|
||||
|
||||
enum CameraTypeEnum : unsigned char {
|
||||
None,
|
||||
Orthographic,
|
||||
Perspective
|
||||
};
|
||||
|
||||
const CameraTypeEnum CameraType = CameraTypeEnum::None;
|
||||
|
||||
static Vec3 normCross(const Vec3&, const Vec3&);
|
||||
static Vec3 transformVec(const Mat4&, const Vec3&);
|
||||
|
||||
Camera(
|
||||
const Vec3& pos=Vec3(0.0f, 0.0f, -1.0f),
|
||||
const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f),
|
||||
const Vec3& up =Vec3(0.0f, 1.0f, 0.0f)
|
||||
);
|
||||
|
||||
|
||||
Vec3 getPos() const;
|
||||
Vec3 getTarget() const;
|
||||
Vec3 getDirection() const;
|
||||
Vec3 getWorldUp() const;
|
||||
Vec3 getUp() const;
|
||||
Vec3 getRight() const;
|
||||
Mat4 getViewMatrix() const;
|
||||
Mat4 getProjectionMatrix() const;
|
||||
Mat4 getFlattenedMatrices() const;
|
||||
bool isUpLocked() const;
|
||||
|
||||
void setProjection(const Mat4&);
|
||||
void setPos(const Vec3&);
|
||||
void setTarget(const Vec3&);
|
||||
void setDirection(const Vec3&);
|
||||
void setWorldUp(const Vec3&);
|
||||
void lockToWorldUp(bool lock);
|
||||
void resetUp();
|
||||
void addPos(const Vec3&);
|
||||
void panPos(const Vec3&);
|
||||
void panPosRelative(const Vec3&);
|
||||
void addTarget(const Vec3&);
|
||||
void roll(float);
|
||||
void pitch(float);
|
||||
void yaw(float);
|
||||
|
||||
protected:
|
||||
Vec3 _pos;
|
||||
Vec3 _tar;
|
||||
Vec3 _dir;
|
||||
Vec3 _world_up;
|
||||
Vec3 _up;
|
||||
Vec3 _right;
|
||||
Mat4 _view;
|
||||
Mat4 _proj;
|
||||
bool _lock_world_up = true;
|
||||
|
||||
void _calcLook();
|
||||
|
||||
};
|
||||
|
||||
class OrthographicCamera : public Camera {
|
||||
public:
|
||||
const CameraTypeEnum CameraType = CameraTypeEnum::Orthographic;
|
||||
|
||||
OrthographicCamera(
|
||||
const Vec3& pos=Vec3(0.0f, 0.0f, -1.0f),
|
||||
const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f),
|
||||
const Vec3& up =Vec3(0.0f, 1.0f, 0.0f),
|
||||
float left = -1.0f,
|
||||
float right = 1.0f,
|
||||
float bottom = -1.0f,
|
||||
float top = 1.0f,
|
||||
float near = 0.001f,
|
||||
float far = 1.0f
|
||||
);
|
||||
|
||||
float getLeftPlane() const;
|
||||
float getRightPlane() const;
|
||||
float getBottomPlane() const;
|
||||
float getTopPlane() const;
|
||||
float getNearPlane() const;
|
||||
float getFarPlane() const;
|
||||
|
||||
void setLeftPlane(float);
|
||||
void setRightPlane(float);
|
||||
void setBottomPlane(float);
|
||||
void setTopPlane(float);
|
||||
void setNearPlane(float);
|
||||
void setFarPlane(float);
|
||||
void setOrthographicProjection(float left=-1.0, float right=1.0, float bottom=-1.0, float top=1.0, float near=.001, float far=1.0);
|
||||
void setViewingVolume(float width, float height, float depth);
|
||||
|
||||
protected:
|
||||
float _leftPlane, _rightPlane, _topPlane, _bottomPlane, _nearPlane, _farPlane;
|
||||
|
||||
void _calcView();
|
||||
using Camera::setProjection;
|
||||
|
||||
};
|
||||
|
||||
class PerspectiveCamera : public Camera {
|
||||
public:
|
||||
const CameraTypeEnum CameraType = CameraTypeEnum::Perspective;
|
||||
|
||||
PerspectiveCamera(
|
||||
const Vec3& pos=Vec3(0.0f, 0.0f, -1.0f),
|
||||
const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f),
|
||||
const Vec3& up =Vec3(0.0f, 1.0f, 0.0f),
|
||||
float fov = 45.0f,
|
||||
float aspectRatio = 1.0f,
|
||||
float near = 0.001f,
|
||||
float far = 1.0f
|
||||
);
|
||||
|
||||
float getFOV() const;
|
||||
float getAspectRatio() const;
|
||||
float getNearPlane() const;
|
||||
float getFarPlane() const;
|
||||
|
||||
void setFOV(float);
|
||||
void setAspectRatio(float);
|
||||
void setNearPlane(float);
|
||||
void setFarPlane(float);
|
||||
void setPerspectiveProjection(float fov=45, float aspectRatio=1.0f, float near=0.001f, float far=1.0f);
|
||||
|
||||
protected:
|
||||
float _fov, _ratio, _nearPlane, _farPlane;
|
||||
|
||||
void _calcView();
|
||||
using Camera::setProjection;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // _NB_CAMERA
|
||||
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
#ifndef _NB_DRAW
|
||||
#define _NB_DRAW
|
||||
|
||||
#include <GLLoad.h>
|
||||
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Buffers.h"
|
||||
#include "Shader.h"
|
||||
#include "VAOManager.hpp"
|
||||
|
||||
#define THROW_DRAW_ERROR(msg) throw DrawError(msg, __FILE__, __LINE__);
|
||||
|
||||
namespace NB{
|
||||
|
||||
class DrawError : public std::runtime_error {
|
||||
public:
|
||||
DrawError(const std::string&, const std::string& file="", int line=-1);
|
||||
};
|
||||
|
||||
uint8_t VerticesFromPrimitives(GLenum, unsigned int num_prims=1);
|
||||
|
||||
uint8_t PrimitivesFromVertices(GLenum, unsigned int);
|
||||
|
||||
void copyVertexAttribute(const VertexAttribute&, VertexAttribute&);
|
||||
|
||||
class DrawBuffer {
|
||||
public:
|
||||
typedef std::shared_ptr<Buffer> BufferManagerPointer;
|
||||
DrawBuffer(VertexAttributeList, GLenum prim_type=GL_TRIANGLES);
|
||||
//DrawBuffer(std::initializer_list<VertexAttribute>, std::initializer_list<VertexAttributePointer>);
|
||||
|
||||
unsigned int vertSize() const;
|
||||
const std::shared_ptr<ShaderProgram> shader() const;
|
||||
unsigned int elementBufferID() const;
|
||||
unsigned int vertexBufferID() const;
|
||||
virtual void draw() const;
|
||||
RawVec vertAttrData(unsigned int);
|
||||
|
||||
VertexAttributeList changeVertLayout(unsigned int, VertexAttributePointer);
|
||||
RawVec vertAttrData(unsigned int, const RawVec&);
|
||||
virtual void elementData(const std::vector<unsigned int>&);
|
||||
virtual void elementData(unsigned int);
|
||||
virtual void elementData(const std::vector<unsigned int>&, unsigned int offset);
|
||||
virtual void vertexData(const RawVec&);
|
||||
virtual void vertexData(unsigned int num_verts);
|
||||
virtual void vertexData(const RawVec&, unsigned int offset);
|
||||
|
||||
BufferManagerPointer _vert_data;
|
||||
BufferManagerPointer _elmt_data;
|
||||
VAOManager _VAO;
|
||||
const GLenum _gl_primitive_type=0;
|
||||
virtual VertexAttributeList defaultVAO(VertexAttributeList);
|
||||
|
||||
unsigned int _num_verts, _num_prims;
|
||||
protected:
|
||||
};
|
||||
|
||||
class DrawInstanceBuffer : public DrawBuffer {
|
||||
public:
|
||||
DrawInstanceBuffer(VertexAttributeList, VertexAttributeList, GLenum primt_type=GL_TRIANGLES);
|
||||
|
||||
unsigned int instSize() const;
|
||||
unsigned int instanceBufferID() const;
|
||||
virtual void draw() const override;
|
||||
|
||||
VertexAttributeList changeInstanceLayout(unsigned int, VertexAttributePointer);
|
||||
virtual void instanceData(const RawVec&);
|
||||
virtual void instanceData(unsigned int);
|
||||
virtual void instanceData(const RawVec&, unsigned int offset);
|
||||
|
||||
BufferManagerPointer _inst_data;
|
||||
virtual VertexAttributeList defaultVAO(VertexAttributeList);
|
||||
unsigned int _num_inst;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#ifndef _NB_OPENGL_LOADER
|
||||
#define _NB_OPENGL_LOADER
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace NB {
|
||||
|
||||
static unsigned int __NB_GL_DEBUG_ERROR_CODE__;
|
||||
|
||||
static std::string formatDebugString(const std::string& msg, const std::string& file="", int line=-1) {
|
||||
std::string ret = "";
|
||||
if (file != "") {
|
||||
ret += "In file " + file;
|
||||
if (line >= 0) {
|
||||
ret += " at line " + std::to_string(line);
|
||||
}
|
||||
ret += ":\n\t";
|
||||
}
|
||||
return ret + msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define NB_GL_DEBUG_THROW(cmd, when) while(NB::__NB_GL_DEBUG_ERROR_CODE__=glGetError()){\
|
||||
std::cout << "[GL ERROR]: " << NB::__NB_GL_DEBUG_ERROR_CODE__;\
|
||||
std::cout << " " << when << " " << cmd << "\n";\
|
||||
}
|
||||
#define NB_GL_DEBUG(cmd) NB_GL_DEBUG_THROW(#cmd, "before"); cmd; NB_GL_DEBUG_THROW(#cmd, "after");
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#ifndef _NB_VAO_MANAGER
|
||||
#define _NB_VAO_MANAGER
|
||||
|
||||
#include <GLLoad.h>
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "Buffers.h"
|
||||
|
||||
#define THROW_VAO_ERROR(msg) throw VAOError(msg, __FILE__, __LINE__);
|
||||
|
||||
namespace NB {
|
||||
|
||||
class VAOError : public std::runtime_error {
|
||||
public:
|
||||
const bool error;
|
||||
VAOError(const std::string& msg, const std::string& file="", int line=-1)
|
||||
: std::runtime_error(NB::formatDebugString(msg, file, line)), error(true) {}
|
||||
VAOError(bool isError=true) : std::runtime_error(""), error(isError) {}
|
||||
};
|
||||
|
||||
class VAOManager : public OpenGLObject {
|
||||
public:
|
||||
typedef std::shared_ptr<Buffer> BufferManagerPointer;
|
||||
//typedef BufferManager BufferManagerPointer;
|
||||
|
||||
VAOManager();
|
||||
VAOManager(
|
||||
std::vector<BufferManagerPointer>,
|
||||
BufferManagerPointer elmt_buf = nullptr,
|
||||
const VertexAttributeList& vert_attrs = {}
|
||||
);
|
||||
VAOManager(
|
||||
BufferManagerPointer vert_bufs,
|
||||
BufferManagerPointer elmt_buf = nullptr,
|
||||
const VertexAttributeList& vert_attrs = {}
|
||||
) : VAOManager(std::vector<BufferManagerPointer>(1, vert_bufs), elmt_buf, vert_attrs) {}
|
||||
|
||||
VAOManager(VAOManager&& rhs);
|
||||
VAOManager& operator=(VAOManager&& rhs);
|
||||
|
||||
VertexAttributeList getLayout() const;
|
||||
GLuint id() const;
|
||||
unsigned int vertSize(GLuint) const;
|
||||
std::vector<BufferManagerPointer> getVertexBuffers() const;
|
||||
bool isInitialized() const override;
|
||||
RawVec attributeData(unsigned int);
|
||||
|
||||
RawVec attributeData(unsigned int, const RawVec&);
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
void addVBO(BufferManagerPointer);
|
||||
void changeEBO(BufferManagerPointer);
|
||||
VertexAttributeList addVertexAttributes(const VertexAttributeList&);
|
||||
VertexAttributeList addVertexAttributes(VertexAttribute);
|
||||
VertexAttributeList generate();
|
||||
VertexAttributeList generate(VertexAttributeList);
|
||||
VertexAttributeList changeLayout(unsigned int, VertexAttributePointer);
|
||||
|
||||
VAOError checkValid(const VertexAttributeList&);
|
||||
|
||||
private:
|
||||
void remove() const override;
|
||||
|
||||
using OpenGLObject::_id;
|
||||
std::map<GLuint, BufferManagerPointer> _vert_buffers;
|
||||
BufferManagerPointer _elmt_buffer = nullptr;
|
||||
VertexAttributeList _vert_attrs;
|
||||
};
|
||||
|
||||
} // namespace NB
|
||||
#endif // _NB_VAO_MANAGER
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#ifndef _NB_WINDOW
|
||||
#define _NB_WINDOW
|
||||
|
||||
#include "GLLoad.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace NB {
|
||||
|
||||
class GLError : public std::runtime_error {
|
||||
public:
|
||||
GLError(const std::string&);
|
||||
};
|
||||
|
||||
class WindowError : public std::runtime_error {
|
||||
public:
|
||||
WindowError(const std::string&);
|
||||
};
|
||||
|
||||
class Window {
|
||||
public:
|
||||
static bool StrictInitialization;
|
||||
|
||||
static int getGLFWHint(int);
|
||||
static int setGLFWHint(int, int);
|
||||
static Window* getCurrent();
|
||||
|
||||
Window(const std::array<uint16_t, 2>, const char*, GLFWmonitor* initMonitor=NULL, GLFWwindow* initWindow=NULL);
|
||||
Window(const uint16_t, const uint16_t, const char*, GLFWmonitor* initMonitor=NULL, GLFWwindow* initWindow=NULL);
|
||||
~Window();
|
||||
|
||||
int getWindowHint(int) const;
|
||||
GLFWwindow* getWindow() const;
|
||||
std::array<uint16_t, 2> getSize() const;
|
||||
float getAspectRatio() const;
|
||||
std::string getName() const;
|
||||
|
||||
int init();
|
||||
int setWindowHint(int, int);
|
||||
void setCurrent();
|
||||
void resize(const std::array<uint16_t, 2>);
|
||||
void resize(const uint16_t x, const uint16_t y);
|
||||
|
||||
protected:
|
||||
static std::map<GLFWwindow*, Window*> WindowContexts;
|
||||
static std::map<int, int> GLFWHints;
|
||||
static Window* _current;
|
||||
static bool _glfw_init;
|
||||
static bool checkKillGLFW();
|
||||
|
||||
std::map<int, int> windowHints;
|
||||
std::array<uint16_t, 2> windowSize;
|
||||
float _aspect_ratio;
|
||||
std::string windowName;
|
||||
GLFWwindow* window;
|
||||
GLFWmonitor* monitor;
|
||||
GLFWwindow* shareWindow;
|
||||
bool _init = false;
|
||||
int gladResponse = -1;
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
#pragma once
|
||||
#ifndef _NB_SHADER
|
||||
#define _NB_SHADER
|
||||
|
||||
#include <GLLoad.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
// #define _PREPROC_FUNC_PARAMS_ (const ShaderPreprocessor&, ShaderUnit&, unsigned int, const std::string&, std::vector<uint8_t>&)
|
||||
|
||||
namespace NB {
|
||||
|
||||
class ShaderPreprocessorError : public std::runtime_error {
|
||||
public:
|
||||
enum Codes : unsigned char {
|
||||
NONE,
|
||||
FILE_NOT_FOUND,
|
||||
BUILTIN_NOT_FOUND,
|
||||
CUSTOM,
|
||||
UNDEFINED
|
||||
};
|
||||
|
||||
const Codes code;
|
||||
|
||||
ShaderPreprocessorError(const std::string&, const std::string& file="", int line=-1);
|
||||
ShaderPreprocessorError(Codes, const std::string& arg="", const std::string& file="", int line=-1);
|
||||
|
||||
protected:
|
||||
static std::string errorCodeParser(Codes, const std::string& arg="");
|
||||
};
|
||||
|
||||
class ShaderError : public std::runtime_error {
|
||||
public:
|
||||
ShaderError(const std::string&, const char* shad=nullptr, const std::string& file="", int line=-1);
|
||||
|
||||
protected:
|
||||
std::string formatString(const std::string&, const char* shad=nullptr, const std::string& file="", int line=-1);
|
||||
};
|
||||
|
||||
struct File {
|
||||
// typedef std::tuple<std::string, std::string, std::string> FilePath;
|
||||
struct FilePath {
|
||||
std::string dir;
|
||||
std::string basename;
|
||||
std::string ext;
|
||||
};
|
||||
FilePath path;
|
||||
std::stringstream src;
|
||||
std::map<unsigned int, std::shared_ptr<File>> include_map;
|
||||
|
||||
File() {}
|
||||
File(const File& rhs) { *this = rhs; }
|
||||
|
||||
File& operator=(const File& rhs) {
|
||||
path = rhs.path;
|
||||
src.str("");
|
||||
src << rhs.src.rdbuf();
|
||||
include_map = rhs.include_map;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// File::FilePath get_file_path(std::string);
|
||||
|
||||
class ShaderPreprocessor;
|
||||
|
||||
enum OpenGLProfiles {
|
||||
Core,
|
||||
Compatibility,
|
||||
ES
|
||||
};
|
||||
|
||||
struct ShaderUnit {
|
||||
GLenum type = 0x0;
|
||||
File file;
|
||||
std::string preprocSource;
|
||||
std::map<std::string, std::string> defines;
|
||||
short vMajor=0, vMinor=0;
|
||||
OpenGLProfiles profile = Core;
|
||||
};
|
||||
|
||||
class ShaderPreprocessor;
|
||||
|
||||
class ShaderProgram {
|
||||
friend ShaderPreprocessor;
|
||||
public:
|
||||
ShaderProgram() {}
|
||||
ShaderProgram(const ShaderProgram& rhs) = delete;
|
||||
ShaderProgram(ShaderProgram&& rhs);
|
||||
|
||||
~ShaderProgram();
|
||||
|
||||
ShaderProgram& operator=(const ShaderProgram& rhs) = delete;
|
||||
ShaderProgram& operator=(ShaderProgram&& rhs);
|
||||
|
||||
std::vector<ShaderUnit> getShaders() const;
|
||||
ShaderUnit getShaders(unsigned int) const;
|
||||
void use() const;
|
||||
unsigned int id() const;
|
||||
|
||||
void setBool(const std::string& name, bool value) const;
|
||||
void setInt(const std::string& name, int value) const;
|
||||
void setUnsigned(const std::string& name, int value) const;
|
||||
void setFloat(const std::string& name, float value) const;
|
||||
void setMat4(const std::string& name, glm::mat4& value) const;
|
||||
|
||||
static ShaderProgram CreateShaderProgram(std::vector<ShaderUnit>&);
|
||||
|
||||
private:
|
||||
ShaderProgram(std::vector<ShaderUnit>& shaders) : _shader_units(shaders){}
|
||||
|
||||
std::vector<ShaderUnit> _shader_units;
|
||||
unsigned int _id;
|
||||
};
|
||||
|
||||
class ShaderPreprocessor {
|
||||
public:
|
||||
typedef ShaderPreprocessorError::Codes Codes;
|
||||
|
||||
enum TokenType {
|
||||
TK,
|
||||
DR,
|
||||
WS,
|
||||
NL,
|
||||
LC,
|
||||
BC
|
||||
};
|
||||
static std::string TokenName(const TokenType&);
|
||||
|
||||
std::map<std::string, GLenum> AcceptedExtensions = {
|
||||
{".frag", GL_FRAGMENT_SHADER},
|
||||
{".fs", GL_FRAGMENT_SHADER},
|
||||
{".vert", GL_VERTEX_SHADER},
|
||||
{".vs", GL_VERTEX_SHADER},
|
||||
{".tess", 0x0},
|
||||
{".geom", GL_GEOMETRY_SHADER},
|
||||
{".comp", 0x0},
|
||||
{".shad", 0x0},
|
||||
{".glsl", 0x0}
|
||||
};
|
||||
std::map<std::string, OpenGLProfiles> AcceptedProfiles {
|
||||
{"core", Core},
|
||||
{"compatibility", Compatibility},
|
||||
{"es", ES}
|
||||
};
|
||||
std::vector<std::string> Directories;
|
||||
std::map<std::string, std::string> BuiltIns;
|
||||
|
||||
ShaderPreprocessor();
|
||||
|
||||
|
||||
File load(const std::string, bool builtin_first=false) const;
|
||||
ShaderUnit& preprocess(const std::string&, ShaderUnit&) const;
|
||||
ShaderUnit preprocess(File, GLenum shader_type=0x0) const;
|
||||
ShaderUnit preprocess(const std::string&, GLenum shader_type=0x0) const;
|
||||
ShaderProgram ReloadFromFile(const ShaderProgram& rhs) const;
|
||||
ShaderProgram CreateShaderProgram(std::vector<std::string>) const;
|
||||
|
||||
private:
|
||||
typedef std::pair<TokenType, std::string> Token;
|
||||
typedef std::vector<std::string> StringVec;
|
||||
|
||||
inline bool directive_dispatch(ShaderUnit&, const std::string&) const;
|
||||
inline std::vector<Token> tokenize(const std::string&) const;
|
||||
|
||||
inline bool preprocessor_include(ShaderUnit&, const StringVec&, const std::string&) const;
|
||||
inline bool preprocessor_version(ShaderUnit&, const StringVec&, const std::string&) const;
|
||||
inline bool preprocessor_define(ShaderUnit&, const StringVec&, const std::string&) const;
|
||||
// inline bool preprocessor_uniform(ShaderUnit&, const std::string&, const std::string&) const;
|
||||
|
||||
File loadFromBase(const std::string, const std::string base="") const;
|
||||
File loadFromDirectories(const std::string) const;
|
||||
File loadFromBuiltIn(const std::string) const;
|
||||
File load_BuiltInFirst(const std::string) const;
|
||||
File load_FilesFirst(const std::string) const;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user