#ifndef GLSHADER_SHADER_HPP_ #define GLSHADER_SHADER_HPP_ #include <map> #include <set> #include <string> #include <GL/glew.h> class Shader { public: using Paths = std::set<std::string>; explicit Shader(Paths const & paths); virtual ~Shader(); Shader(Shader &&) noexcept; Shader(Shader const &) = delete; Shader & operator=(Shader &&) = delete; Shader & operator=(Shader const &) = delete; using Defines = std::map<std::string, std::string>; using Locations = std::map<std::string, GLuint>; static void root(std::string const & root); static void defines(Defines const & defines); static void verts(Locations const & verts); static void frags(Locations const & frags); GLuint program() const; Shader & validate(); Shader & use(); protected: void validate_() const; void current_( std::string const & error ) const; GLuint program_; std::string program_name_; std::string static root_; Defines static defines_; Locations static verts_; Locations static frags_; }; // Debug macros. #ifndef NDEBUG #define GLSHADER_DEBUG_(...) __VA_ARGS__ #else #define GLSHADER_DEBUG_(...) #endif // NDEBUG // Inline definitions. #define GLSHADER_SET_(TYPE, NAME) \ inline void Shader::NAME(TYPE const & NAME) \ { \ NAME##_ = NAME; \ } GLSHADER_SET_(std::string, root) GLSHADER_SET_(Defines, defines) GLSHADER_SET_(Locations, verts) GLSHADER_SET_(Locations, frags) inline GLuint Shader::program() const { return program_; } inline Shader & Shader::validate() { GLSHADER_DEBUG_(validate_();) return *this; } inline Shader & Shader::use() { glUseProgram(program_); return *this; } #endif // GLSHADER_SHADER_HPP_