nuclear@13: #ifndef SHADER_H_ nuclear@13: #define SHADER_H_ nuclear@13: nuclear@13: #include nuclear@13: #include nuclear@13: #include "vmath/vmath.h" nuclear@13: #include "opengl.h" nuclear@13: #include "dataset.h" nuclear@13: nuclear@13: class ShaderProg; nuclear@13: nuclear@13: nuclear@13: void bind_shader(const ShaderProg *sdr); nuclear@13: const ShaderProg *get_current_shader(); nuclear@13: nuclear@13: nuclear@13: class Shader { nuclear@13: private: nuclear@13: unsigned int sdr; nuclear@13: unsigned int type; nuclear@13: std::string name, src; nuclear@13: nuclear@13: public: nuclear@13: Shader(); nuclear@13: ~Shader(); nuclear@13: nuclear@13: unsigned int get_id() const; nuclear@13: nuclear@13: void set_name(const char *name); nuclear@13: const char *get_name() const; nuclear@13: nuclear@13: bool create(const char *src, unsigned int type); nuclear@13: void destroy(); nuclear@13: nuclear@13: bool load(const char *fname, unsigned int type); nuclear@13: nuclear@13: nuclear@13: // these functions are only meant to be used by the ShaderSet nuclear@13: static Shader *create_shader(); nuclear@13: static bool load_shader(Shader *sdr, const char *fname); nuclear@13: static bool done_shader(Shader *sdr, unsigned int type); nuclear@13: static void destroy_shader(Shader *sdr); nuclear@13: }; nuclear@13: nuclear@13: #define VSDR(s) s, GL_VERTEX_SHADER nuclear@13: #define FSDR(s) s, GL_FRAGMENT_SHADER nuclear@13: #define PSDR(s) FSDR(s) nuclear@13: #define GSDR(s) s, GL_GEOMETRY_SHADER nuclear@13: #define TCSDR(s) s, GL_TESS_CONTROL_SHADER nuclear@13: #define TESDR(s) s, GL_TESS_EVALUATION_SHADER nuclear@13: nuclear@13: class ShaderProg { nuclear@13: private: nuclear@13: unsigned int prog; nuclear@13: mutable bool must_link; nuclear@13: std::vector shaders; nuclear@13: nuclear@13: struct StateLocCache { int sidx, loc; }; nuclear@13: /** a cache of all st_ prefixed uniform locations and their corresponding nuclear@13: * index in the global uniform state vector (see unistate.h) nuclear@13: */ nuclear@13: mutable std::vector stloc_cache; nuclear@13: nuclear@13: void cache_state_uniforms() const; nuclear@13: void setup_state_uniforms() const; nuclear@13: nuclear@13: public: nuclear@13: static ShaderProg *current; nuclear@13: nuclear@13: ShaderProg(); nuclear@13: ~ShaderProg(); nuclear@13: nuclear@13: /// returns the OpenGL object id for this shader program nuclear@13: unsigned int get_id() const; nuclear@13: nuclear@13: /** takes a series of shaders, and constructs a program object by linking nuclear@13: * them together. Terminate with a null pointer (don't use 0!) */ nuclear@13: bool create(Shader *sdr, ...); nuclear@13: /// same as above, but with a va_list instead of variable arguments. nuclear@13: bool create(Shader *sdr, va_list ap); nuclear@13: /** takes two shaders (vertex and pixel) and constructs a program object by nuclear@13: * linking them together. Either one can be null. */ nuclear@13: bool create(Shader *vsdr, Shader *psdr); nuclear@13: nuclear@13: /** takes a series of shader source/shader type pairs and constructs a program nuclear@13: * object by linking them together. Terminate with a null pointer (don't use 0!) nuclear@13: * You can use the VSDR, PSDR, GSDR, TCSDR, TESDR convenience macros for passing nuclear@13: * the pairs. nuclear@13: * Example: create(VSDR(vsrc0), VSDR(vsrc1), PSDR(psrc), NULL); nuclear@13: */ nuclear@13: bool create(const char *src, unsigned int type, ...); nuclear@13: /// same as above, but with a va_list instead of variable arguments. nuclear@13: bool create(const char *src, unsigned int type, va_list ap); nuclear@13: /** takes two shaders source strings (vertex and pixel) and constructs nuclear@13: * a program object by linking them together. Either one can be null. */ nuclear@13: bool create(const char *vsrc, const char *psrc); nuclear@13: nuclear@13: void destroy(); nuclear@13: nuclear@13: /** takes a series of shader filename/shader type pairs, loads the shaders and nuclear@13: * constructs a program object by linking them together. Terminate with a null nuclear@13: * pointer (don't use 0!). You can use the VSDR, PSDR, GSDR, TCSDR, TESDR convenience nuclear@13: * macros for passing the pairs. nuclear@13: * Example: load(VSDR("vsdr1.glsl"), VSDR("vsdr2.glsl"), PSDR("pixel.glsl"), NULL); nuclear@13: */ nuclear@13: bool load(const char *fname, unsigned int type, ...); nuclear@13: /// same as above, but with a va_list instead of variable arguments. nuclear@13: bool load(const char *fname, unsigned int type, va_list ap); nuclear@13: /** takes the filenames of two shader files (vertex and pixel), loads them and nuclear@13: * constructs a program object by linking them together. Either one can be null */ nuclear@13: bool load(const char *vsrc, const char *psrc); nuclear@13: nuclear@13: void add_shader(Shader *sdr); nuclear@13: bool link() const; nuclear@13: nuclear@13: void bind() const; nuclear@13: nuclear@13: int get_attrib_location(const char *name) const; nuclear@13: void set_attrib_location(const char *name, int loc) const; nuclear@13: nuclear@13: int get_uniform_location(const char *name) const; nuclear@13: nuclear@13: bool set_uniform(int loc, int val) const; nuclear@13: bool set_uniform(int loc, float val) const; nuclear@13: bool set_uniform(int loc, const Vector2 &v) const; nuclear@13: bool set_uniform(int loc, const Vector3 &v) const; nuclear@13: bool set_uniform(int loc, const Vector4 &v) const; nuclear@13: bool set_uniform(int loc, const Matrix3x3 &m) const; nuclear@13: bool set_uniform(int loc, const Matrix4x4 &m) const; nuclear@13: nuclear@13: bool set_uniform(const char *name, int val) const; nuclear@13: bool set_uniform(const char *name, float val) const; nuclear@13: bool set_uniform(const char *name, const Vector2 &v) const; nuclear@13: bool set_uniform(const char *name, const Vector3 &v) const; nuclear@13: bool set_uniform(const char *name, const Vector4 &v) const; nuclear@13: bool set_uniform(const char *name, const Matrix3x3 &m) const; nuclear@13: bool set_uniform(const char *name, const Matrix4x4 &m) const; nuclear@13: nuclear@13: friend void setup_unistate(const ShaderProg*); nuclear@13: }; nuclear@13: nuclear@13: class ShaderSet : public DataSet { nuclear@13: private: nuclear@13: unsigned int type; nuclear@13: nuclear@13: public: nuclear@13: ShaderSet(unsigned int type); nuclear@13: }; nuclear@13: nuclear@13: #endif // SHADER_H_