119 lines
3.4 KiB
C++

#pragma once
#ifndef _NB_SHADER
#define _NB_SHADER
#include <GLLoad.h>
#include <cctype>
#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>
namespace NB {
typedef std::pair<std::string, std::string> FileLocation;
FileLocation get_file_path(std::string);
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 {
FileLocation loc;
std::stringstream src;
std::map<unsigned int, std::shared_ptr<File>> include_map;
};
class ShaderPreprocessor;
struct ShaderUnit {
friend ShaderPreprocessor;
File file;
std::stringstream preprocSource;
std::map<std::string, std::string> defines;
uint8_t vMajor=0, vMinor=0;
};
void preprocessor_include(const ShaderPreprocessor&, ShaderUnit&, unsigned int, const std::string&);
void preprocessor_define(const ShaderPreprocessor&, ShaderUnit&, unsigned int, const std::string&);
void preprocessor_version(const ShaderPreprocessor&, ShaderUnit&, unsigned int, const std::string&);
class ShaderPreprocessor {
public:
typedef ShaderPreprocessorError::Codes Codes;
typedef void (*PreprocFunc)(const ShaderPreprocessor&, ShaderUnit&, unsigned int, const std::string&);
std::vector<std::string> AcceptedExtensions = {"frag", "vert", "tess", "geom", "comp", "shad", "glsl"};
std::vector<std::string> Directories;
std::map<std::string, std::string> BuiltIns;
std::map<std::string, PreprocFunc> Keywords = {
{"#include", preprocessor_include},
{"#define", preprocessor_define},
{"#version", preprocessor_version},
{"#ifdef", nullptr},
{"#ifndef", nullptr},
{"#endif", nullptr}
};
ShaderPreprocessor();
std::stringstream load(const std::string&) 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;
void process(std::stringstream&, ShaderUnit&) const;
ShaderUnit process(std::stringstream&) 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