#ifndef _cgfxEffectDef_h_
#define _cgfxEffectDef_h_
#include "cgfxShaderCommon.h"
#include "cgfxProfile.h"
#include "cgfxRCPtr.h"
class cgfxEffect;
class cgfxAttrDefList;
#include <maya/MDagPath.h>
#include <maya/MObjectHandle.h>
class cgfxVertexAttribute
{
public:
cgfxVertexAttribute();
void addRef() const { ++refcount; }
void release() const;
MString fName;
MString fSemantic;
MString fUIName;
MString fType;
MString fSourceName;
enum SourceType
{
kNone,
kPosition,
kNormal,
kUV,
kTangent,
kBinormal,
kColor,
kBlindData,
kUnknown
} fSourceType;
int fSourceIndex;
cgfxRCPtr<cgfxVertexAttribute> fNext;
private:
mutable int refcount;
};
struct sourceStreamInfo
{
cgfxVertexAttribute::SourceType fSourceType;
MString fSourceName;
unsigned int fOffset;
unsigned int fStride;
unsigned int fDimension;
unsigned int fElementSize;
GLuint fDataBufferId;
};
#define MAX_STRUCTURE_ELEMENTS 16
class cgfxVaryingParameterStructure
{
public:
int fLength;
int fSize;
struct cgfxVaryingParameterElement
{
cgfxRCPtr<cgfxVertexAttribute> fVertexAttribute;
int fSize;
};
cgfxVaryingParameterElement fElements[ MAX_STRUCTURE_ELEMENTS];
};
class cgfxStructureCache
{
public:
cgfxStructureCache();
~cgfxStructureCache();
char* findEntry(const MDagPath& shape, const MString& name);
char* addEntry(const MDagPath& shape, const MString& name, int stride, int count);
void flush();
void flush(const MDagPath& shape);
private:
cgfxStructureCache(const cgfxStructureCache&);
const cgfxStructureCache& operator=(const cgfxStructureCache&);
private:
struct Entry
{
Entry(const MDagPath& shape, const MString& name, int stride, int count);
~Entry();
MObjectHandle fShape;
MString fName;
char* fData;
Entry* fNext;
};
Entry* fEntries;
};
class cgfxVaryingParameter
{
private:
friend class cgfxPass;
static inline void addRecursive(
CGparameter parameter,
cgfxVaryingParameter**& nextParameter
);
cgfxVaryingParameter( CGparameter parameter);
~cgfxVaryingParameter();
cgfxVaryingParameter(const cgfxVaryingParameter&);
const cgfxVaryingParameter& operator=(const cgfxVaryingParameter&);
void setupAttributes(
cgfxRCPtr<cgfxVertexAttribute>& vertexAttributes,
CGprogram program
);
cgfxRCPtr<cgfxVertexAttribute> setupAttribute(
MString name,
const MString& semantic,
CGparameter parameter,
cgfxRCPtr<cgfxVertexAttribute>& vertexAttributes
);
void null() const;
public:
void bind( const MDagPath& shape, cgfxStructureCache* cache,
int vertexCount, const float * vertexArray,
int normalsPerVertex, int normalCount, const float ** normalArrays,
int colorCount, const float ** colorArrays,
int texCoordCount, const float ** texCoordArrays) const;
bool bind( const float* data, int stride) const;
bool bind(const sourceStreamInfo& source) const;
private:
CGparameter fParameter;
MString fName;
int fGLType;
int fGLIndex;
cgfxRCPtr<cgfxVertexAttribute> fVertexAttribute;
cgfxVaryingParameterStructure* fVertexStructure;
cgfxVaryingParameter* fNext;
};
class cgfxPass
{
private:
friend class cgfxTechnique;
cgfxPass(CGpass pass,
const cgfxProfile* profile);
~cgfxPass();
cgfxPass(const cgfxPass&);
const cgfxPass& operator=(const cgfxPass&);
void setupAttributes( cgfxRCPtr<cgfxVertexAttribute>& vertexAttributes) const;
void setProfile(const cgfxProfile* profile) const;
public:
void setCgState() const { cgSetPassState(fPass); }
void resetCgState() const { cgResetPassState(fPass); }
void updateCgParameters() const { cgUpdatePassParameters(fPass); }
CGpass getCgPass() const { return fPass; }
const cgfxPass* getNext() const { return fNext; }
void bind(
const MDagPath& shape, cgfxStructureCache* cache,
int vertexCount, const float * vertexArray,
int normalsPerVertex, int normalCount, const float ** normalArrays,
int colorCount, const float ** colorArrays,
int texCoordCount, const float ** texCoordArrays) const;
void bind(const sourceStreamInfo dataSources[], const int sourceCount) const;
private:
CGpass fPass;
CGprogram fProgram;
MString fName;
cgfxVaryingParameter* fParameters;
cgfxProfile fDefaultProfile;
cgfxPass* fNext;
};
class cgfxTechnique
{
private:
friend class cgfxEffect;
cgfxTechnique( CGtechnique technique, const cgfxProfile* profile);
~cgfxTechnique();
cgfxTechnique(const cgfxTechnique&);
const cgfxTechnique& operator=(const cgfxTechnique&);
void setProfile(const cgfxProfile* profile) const;
void validate() const;
const cgfxProfile* getSupportedProfile(const cgfxProfile* profile) const;
static bool hasBlending(CGtechnique technique);
public:
MString getName() const { return fName; }
bool isValid() const { return fValid; }
MString getCompilationErrors() const { return fErrorString; }
bool hasBlending() const { return fHasBlending; }
const cgfxPass* getFirstPass() const { return fPasses; }
const cgfxTechnique* getNext() const { return fNext; }
int getNumPasses() const { return fNumPasses; }
cgfxRCPtr<cgfxVertexAttribute> getVertexAttributes() const;
private:
MString fName;
CGtechnique fTechnique;
mutable bool fValid;
mutable MString fErrorString;
bool fHasBlending;
cgfxPass* fPasses;
int fNumPasses;
cgfxTechnique* fNext;
};
class cgfxEffect
{
public:
static cgfxRCPtr<const cgfxEffect> loadEffect(const MString& fileName, const cgfxProfile* profile);
bool isValid() const { return fEffect != NULL && fTechniques != 0; }
const cgfxTechnique* getFirstTechnique() const { return fTechniques; }
const cgfxTechnique* getTechnique(MString techniqueName) const;
cgfxRCPtr<cgfxAttrDefList> attrsFromEffect() const;
void setProfile(const cgfxProfile* profile) const;
private:
friend class cgfxRCPtr<const cgfxEffect>;
cgfxEffect(const MString& fileName, const cgfxProfile* profile);
~cgfxEffect();
void addRef() const { ++refcount; }
void release() const;
cgfxEffect(const cgfxEffect&);
const cgfxEffect& operator=(const cgfxEffect&);
mutable int refcount;
CGeffect fEffect;
const cgfxTechnique* fTechniques;
mutable const cgfxProfile* fProfile;
};
#undef VALID
#endif