/*! * @file shader.h * @brief Definition of the Shader rendering class */ #ifndef _SHADER_H #define _SHADER_H #include "base_object.h" #include "glincl.h" #include // FORWARD DECLARATION //! A class for ... class Shader : public BaseObject { public: class Uniform { public: Uniform(const Shader* shader, const std::string& location) { glGetUniformLocationARB(shader->getProgram(), location.c_str()) ; } Uniform(const Shader& shader, const std::string& location) { glGetUniformLocation(shader.getProgram(), location.c_str()) ; }; Uniform(GLhandleARB shaderProgram, const std::string& location) { glGetUniformLocation(shaderProgram, location.c_str()) ; }; void set(float v0) const { glUniform1f(this->uniform, v0); } void set(float v0, float v1) const { glUniform2f(this->uniform, v0, v1); } void set(float v0, float v1, float v2) const { glUniform3f(this->uniform, v0, v1, v2); } void set(float v0, float v1, float v2, float v3) const { glUniform4f(this->uniform, v0, v1, v2, v3); } void set(int v0) const { glUniform1i(this->uniform, v0); } void set(int v0, int v1) const { glUniform2i(this->uniform, v0, v1); } void set(int v0, int v1, int v2) const { glUniform3i(this->uniform, v0, v1, v2); } void set(int v0, int v1, int v2, int v3) const { glUniform4i(this->uniform, v0, v1, v2, v3); } void setV(unsigned int count, float* vv) const { switch (count) { case 1: glUniform1fv(this->uniform, 1, vv); break; case 2: glUniform2fv(this->uniform, 2, vv); break; case 3: glUniform3fv(this->uniform, 3, vv); break; case 4: glUniform4fv(this->uniform, 4, vv); break; } } void setV(unsigned int count, int* vv) const { switch (count) { case 1: glUniform1iv(this->uniform, 1, vv); break; case 2: glUniform2iv(this->uniform, 2, vv); break; case 3: glUniform3iv(this->uniform, 3, vv); break; case 4: glUniform4iv(this->uniform, 4, vv); break; } } private: GLint uniform; }; typedef enum { None = 0, Fragment = 1, Vertex = 2, Program = 4, } Type; public: Shader(const std::string& vertexShaderFile = "", const std::string& fragmentShaderFile = ""); virtual ~Shader(); static Shader* getShader(const std::string& vertexShaderFile, const std::string& fragmentShaderFile); static bool unload(Shader* shader); static bool checkShaderAbility(); void activateShader(); static void deactivateShader(); Shader::Uniform getUniform(const std::string& location) { return Shader::Uniform(this, location); } bool loadShaderProgramm(Shader::Type type, const std::string& fileName); void deleteProgram(Shader::Type type); void linkShaderProgram(); bool readShader(const std::string& fileName, std::string& output); inline static bool shaderActive() { return (Shader::storedShader != NULL)? true : false; }; inline static Shader* getActiveShader() { return Shader::storedShader; }; inline static void suspendShader() { Shader* currShader = storedShader; if (storedShader!= NULL) { Shader::deactivateShader(); Shader::storedShader = currShader;} }; inline static void restoreShader() { if (storedShader != NULL) storedShader->activateShader(); storedShader = NULL; }; GLhandleARB getProgram() const { return this->shaderProgram; } GLhandleARB getVertexS() const { return this->vertexShader; } GLhandleARB getFragmentS() const { return this->fragmentShader; } void debug() const; static void printError(GLhandleARB program); private: std::string fragmentShaderFile; std::string vertexShaderFile; GLhandleARB shaderProgram; GLhandleARB vertexShader; GLhandleARB fragmentShader; static Shader* storedShader; }; #endif /* _SHADER_H */