#ifndef _SHADERPROGRAM_H__ #define _SHADERPROGRAM_H__ #include "common.h" #include "glInterface.h" #include "Matrix4x4.h" #include #include #include #include namespace CHCDemoEngine { class FrameBufferObject; class Vector3; class Camera; class ShadowMap; class DirectionalLight; class ShaderProgram; typedef std::map CGParameterMap; typedef std::vector CGParameterArray; /** This class represents the parameter values for a given GPU program. */ class GPUProgramParameters { public: /** Default construction. */ GPUProgramParameters(); /** Constructor which initializes this parameter set for a given program. */ GPUProgramParameters(ShaderProgram *p); /** Sets the program associated with these parameters (a 1:n relationship) */ void SetProgram(ShaderProgram *p) { mProgram = p; } /** Resets this parameter set. */ void Reset(); /////////// //-- functions for setting parameters by index void SetValue1f(int idx, float value); void SetValue2f(int idx, float val1, float val2); void SetValue3f(int idx, float val1, float val, float val3); void SetArray1f(int idx, float *vals, int numElements); void SetArray2f(int idx, float *vals, int numElements); void SetArray3f(int idx, float *vals, int numElements); /** Sets a texture parameter. */ void SetTexture(int idx, unsigned int tex); /** Sets a matrix parameter. */ void SetMatrix(int idx, const Matrix4x4 &mat); /** Sets an array of matrices */ void SetMatrixArray(int idx, float *vals, int numElements); //////////// //-- The following parameters are updated and set automatically once per frame. /** This parameter is connected to a timer that is updated once per frame. */ void SetTimerParam(int idx); void SetOldTimerParam(int idx); /** This parameter is connected to the current view matrix that is updated once per frame. */ void SetViewMatrixParam(int idx); /** This parameter is connected to the current view direction that is updated once per frame. */ void SetViewDirParam(int idx); /** This parameter is connected to the current light direction that is updated once per frame. */ void SetLightDirParam(int idx); /** This parameter is connected to the current light direction that is updated once per frame. */ void SetModelMatrixParam(int idx); /** This parameter is connected to the current light direction that is updated once per frame. */ void SetOldModelMatrixParam(int idx); /////////// //-- set parameters by name (slower!) void SetValue1f(const std::string &name, float value); void SetValue2f(const std::string &name, float val1, float val2); void SetValue3f(const std::string &name, float val1, float val, float val3); void SetArray1f(const std::string &name, float *vals, int numElements); void SetArray2f(const std::string &name, float *vals, int numElements); void SetArray3f(const std::string &name, float *vals, int numElements); /** Sets the texture parameter. */ void SetTexture(const std::string &name, unsigned int tex); /** Sets the matrix parameter. */ void SetMatrix(const std::string &name, const Matrix4x4 &mat); /** Sets an array of matrices */ void SetMatrixArray(const std::string &name, float *vals, int numElements); /** Feeds the shader program with the parameter values. */ void UpdateParameters(SceneEntity *ent = NULL); /** Function should be called once per frame to update frame related parameters. */ static void InitFrame(Camera *cam, DirectionalLight *light); protected: struct FloatParam { FloatParam(): mValid(false), mNumComponents(0) {} FloatParam(float *val, int comp): mNumComponents(comp), mValid(true) { for (int i = 0; i < mNumComponents; ++ i) mValues[i] = val[i]; } bool mValid; float mValues[4]; int mNumComponents; }; struct IntParam { IntParam(): mValid(false) {} IntParam(float val): mValue(val), mValid(true) {} bool mValid; float mValue; }; struct MatrixParam { MatrixParam(): mValue(IdentityMatrix()), mValid(false) {} MatrixParam(const Matrix4x4 &mat): mValue(mat), mValid(true) {} bool mValid; Matrix4x4 mValue; }; struct ArrayParam { ArrayParam(): mValues(NULL), mNumEntries(0), mNumComponents(0), mValid(false) {} ArrayParam(float *val, int comp, int numEntries): mValues(val), mNumComponents(comp), mNumEntries(numEntries), mValid(true) {} bool mValid; float *mValues; int mNumEntries; int mNumComponents; }; struct MatrixArrayParam { MatrixArrayParam(): mValues(NULL), mNumEntries(0), mValid(false) {} MatrixArrayParam(float *mats, int numEntries): mValues(mats), mNumEntries(numEntries), mValid(true) {} bool mValid; float *mValues; int mNumEntries; }; /// the program this parameter set is connected to ShaderProgram *mProgram; int mTimerParam; int mOldTimerParam; int mViewDirParam; int mLightDirParam; int mViewMatrixParam; int mModelMatrixParam; int mOldModelMatrixParam; std::vector mFloats; std::vector mTextures; std::vector mMatrices; std::vector mArrays; std::vector mMatrixArrays; }; /** This class represents a wrapper for a GPU shader program (vertex or fragment). */ class ShaderProgram { friend class GPUProgramParameters; public: enum PROGRAM_TYPE {FRAGMENT_PROGRAM, VERTEX_PROGRAM}; ShaderProgram(CGprogram program): mProgram(program) {} ShaderProgram(CGcontext context, const std::string &filename, CGprofile profile, const std::string &functionName, PROGRAM_TYPE type); ~ShaderProgram() { if (mProgram != NULL) cgDestroyProgram(mProgram); } /** Assigns a parameter to the specified index. */ CGparameter AddParameter(const std::string &name, int idx); /** Comvenience method that adds an array of parameters beginning with index i of size numElements */ void AddParameters(std::string params[], int startIdx, int numElements); ////////////// //-- set shader parameters per index void SetValue1f(int idx, float value); void SetValue2f(int idx, float val1, float val2); void SetValue3f(int idx, float val1, float val, float val3); void SetArray1f(int idx, float *vals, int numElements); void SetArray2f(int idx, float *vals, int numElements); void SetArray3f(int idx, float *vals, int numElements); void SetMatrix(int idx, const Matrix4x4 &mat); void SetMatrixArray(int idx, float *mats, int numElements); void SetTexture(int idx, unsigned int tex); //////////// //-- set shader parameters per parameter name (slow!) /// Float parameters void SetValue1f(const std::string &name, float value); void SetValue2f(const std::string &name, float val1, float val2); void SetValue3f(const std::string &name, float val1, float val, float val3); /// Array parameters void SetArray1f(const std::string &name, float *vals, int numElements); void SetArray2f(const std::string &name, float *vals, int numElements); void SetArray3f(const std::string &name, float *vals, int numElements); /** Sets a matrix parameter */ void SetMatrix(const std::string &name, const Matrix4x4 &mat); /** Sets array of matrices */ void SetMatrixArray(const std::string &name, float *mats, int numElements); /** Sets the texture parameter. */ void SetTexture(const std::string &name, unsigned int tex); /** Binds the program. */ void Bind(); /** Releases all texture resources. */ void Release(); /** Returns true if this program is valid. */ inline bool IsValid() const {return mProgram != NULL;} /** Returns type of program (fragment program or vertex program} */ inline PROGRAM_TYPE GetProgramType() const {return mProgramType;} /** See get */ inline void SetProgramType(PROGRAM_TYPE type) {mProgramType = type;} protected: inline int GetParamIdxByName(const std::string &name) const; inline CGparameter GetParameter(int idx) const; CGparameter GetOrCreateParameter(const std::string &name); /////////////// CGParameterMap mParamHash; CGprogram mProgram; CGParameterArray mTextureParams; CGParameterArray mParameters; PROGRAM_TYPE mProgramType; }; } // namespace #endif // _ShaderProgram_H__