193 lines
5.4 KiB
C++
193 lines
5.4 KiB
C++
#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 |