#pragma once #ifndef _NB_SHADER #define _NB_SHADER #include #include #include #include #include #include #include #include #include #include #include #include #include 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 ShaderUnit { friend ShaderPreprocessor; typedef std::pair File; std::stringstream rawSource; std::stringstream preprocSource; std::map defines; std::map includes; uint8_t vMajor=0, vMinor=0; }; class ShaderPreprocessor { public: typedef ShaderPreprocessorError::Codes Codes; typedef void (*PreprocFunc)(const ShaderPreprocessor&, ShaderUnit&, std::stringstream&, unsigned int, const std::string&); std::vector AcceptedExtensions = {"frag", "vert", "tess", "geom", "comp", "shad", "glsl"}; std::vector Directories; std::map BuiltIns; std::map Keywords = { {"#include", preprocessor_include}, {"#define", nullptr}, {"#ifdef", nullptr}, {"#ifndef", nullptr}, {"#endif", nullptr} }; ShaderPreprocessor(); std::stringstream load(const std::string&) const; std::stringstream include(const std::string&, const std::string& base="", bool relativeFirst=false) const; std::stringstream loadFromRelative(const std::string&, const std::string& base="") const; std::stringstream loadFromDirectory(const std::string&) const; std::stringstream loadFromBuiltIn(const std::string&) const; virtual std::stringstream process(std::stringstream&, ShaderUnit&) const; virtual std::stringstream process(std::string) const; }; class Shader { public: Shader(const std::stringstream&, const std::stringstream&); Shader(); Shader(const Shader&); Shader& operator=(const Shader&); void use() const; void setBool(const std::string& name, bool value) const; void setInt(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; unsigned int id; private: }; } #endif