#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;
enum SourceType
{
kPosition,
kNormal,
kUV,
kTangent,
kBinormal,
kColor,
kBlindData,
kUnknown
} fSourceType;
int fSourceIndex;
cgfxRCPtr<cgfxVertexAttribute> fNext;
private:
mutable int refcount;
};
struct sourceStreamInfo
{
cgfxVertexAttribute::SourceType fSourceType;
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* addEntry(
const MDagPath& shape,
const MString& name,
int stride,
int count);
void flush();
private:
cgfxStructureCache(const cgfxStructureCache&);
const cgfxStructureCache& operator=(const cgfxStructureCache&);
private:
struct Entry
{
~Entry();
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(
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;
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;
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:
CGtechnique fTechnique;
mutable bool fValid;
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