Project restructure

This commit is contained in:
NaifBanana
2026-04-04 14:39:17 -05:00
parent 0ac355a4a0
commit 7d44f8dfff
22 changed files with 19 additions and 19 deletions
+367
View File
@@ -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
+151
View File
@@ -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
+84
View File
@@ -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
+35
View File
@@ -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
+75
View File
@@ -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
+69
View File
@@ -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
+193
View File
@@ -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