#ifndef CGFXSHADER_VERSION
#define CGFXSHADER_VERSION  "4.5"
#endif
#include "cgfxShaderNode.h"
#include "cgfxProfile.h"
#include "cgfxFindImage.h"
#include "cgfxPassStateSetter.h"
#include "cgfxTextureCache.h"
#include <maya/MDagPath.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MEventMessage.h>
#include <maya/MFloatVector.h>
#include <maya/MFnMesh.h>
#include <maya/MFnStringArrayData.h>
#include <maya/MFnStringData.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MGlobal.h>
#include <maya/MHwTextureManager.h>
#include <maya/MPlug.h>
#include <maya/MPoint.h>
#include <maya/MPointArray.h>
#include <maya/MVector.h>
#include <maya/MDGModifier.h>
#include <maya/MFileIO.h>
#include <maya/MNodeMessage.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MTextureManager.h>
#include <maya/MUIDrawManager.h>
#include <maya/MGLFunctionTable.h>
#include <maya/MDrawContext.h>
#include <maya/MMatrix.h>
#include <maya/MHWGeometry.h>
#undef ENABLE_TRACE_API_CALLS
#ifdef ENABLE_TRACE_API_CALLS
#define TRACE_API_CALLS(x) cerr << "cgfxShader: "<<(x)<<"\n"
#else
#define TRACE_API_CALLS(x)
#endif
#if defined(_SWATCH_RENDERING_SUPPORTED_)
    
    #include <maya/MHardwareRenderer.h>
    #include <maya/MGeometryData.h>
    #include <maya/MHWShaderSwatchGenerator.h>
#endif
#include <maya/MImage.h>
#include "nv_dds.h"
#ifdef _WIN32
    #include <Mmsystem.h>   
#else
    #include <sys/timeb.h>
    #include <string.h>
    #include <limits.h>     
    #define stricmp strcasecmp
    #define strnicmp strncasecmp
#endif
#define GLOBJECT_BUFFER_OFFSET(i) ((char *)NULL + (i)) // For GLObject offsets
PFNGLCLIENTACTIVETEXTUREARBPROC glStateCache::glClientActiveTexture = 0;
PFNGLVERTEXATTRIBPOINTERARBPROC glStateCache::glVertexAttribPointer = 0;
PFNGLENABLEVERTEXATTRIBARRAYARBPROC glStateCache::glEnableVertexAttribArray = 0;
PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glStateCache::glDisableVertexAttribArray = 0;
PFNGLVERTEXATTRIB4FARBPROC glStateCache::glVertexAttrib4f = 0;
PFNGLSECONDARYCOLORPOINTEREXTPROC glStateCache::glSecondaryColorPointer = 0;
PFNGLSECONDARYCOLOR3FEXTPROC glStateCache::glSecondaryColor3f = 0;
PFNGLMULTITEXCOORD4FARBPROC glStateCache::glMultiTexCoord4fARB = 0;
int glStateCache::sMaxTextureUnits = 0;
glStateCache::glStateCache()
{
    reset();
}
glStateCache glStateCache::gInstance;
void glStateCache::activeTexture( int i)
{
    if( i != fActiveTextureUnit)
    {
        fActiveTextureUnit = i;
        if( glStateCache::glClientActiveTexture)
            glStateCache::glClientActiveTexture( GL_TEXTURE0_ARB + i );
    }
}
void glStateCache::enableVertexAttrib( int i)
{
    if( !(fEnabledRegisters & (1 << (glRegister::kVertexAttrib + i))))
    {
        if( glStateCache::glEnableVertexAttribArray)
            glStateCache::glEnableVertexAttribArray( i);
        fEnabledRegisters |= (1 << (glRegister::kVertexAttrib + i));
    }
    fRequiredRegisters |= (1 << (glRegister::kVertexAttrib + i));
}
void glStateCache::flushState()
{
    
    long redundantRegisters = fEnabledRegisters & ~fRequiredRegisters;
    
    
    if( redundantRegisters & (1 << glRegister::kPosition))
        glDisableClientState(GL_VERTEX_ARRAY);
    if( redundantRegisters & (1 << glRegister::kNormal))
        glDisableClientState(GL_NORMAL_ARRAY);
    if( redundantRegisters & (1 << glRegister::kColor))
        glDisableClientState(GL_COLOR_ARRAY);
    if( redundantRegisters & (1 << glRegister::kSecondaryColor))
        glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
    for( int i = glRegister::kTexCoord; i <= glRegister::kLastTexCoord; i++)
    {
        if( redundantRegisters & (1 << i))
        {
            activeTexture( i - glRegister::kTexCoord);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        }
    }
    for( int i = glRegister::kVertexAttrib; i <= glRegister::kLastVertexAttrib; i++)
    {
        if( redundantRegisters & (1 << i))
        {
            if( glStateCache::glDisableVertexAttribArray)
                glStateCache::glDisableVertexAttribArray( i - glRegister::kVertexAttrib);
        }
    }
    fEnabledRegisters = fRequiredRegisters;
    fRequiredRegisters = 0;
}
#ifdef _WIN32
MTypeId     cgfxShaderNode::sId( 4084862000 );
 
#else
MTypeId     cgfxShaderNode::sId( 0xF37A0C30 );
 
#endif
CGcontext       cgfxShaderNode::sCgContext;
cgfxShaderNode::Effect2NodesMap cgfxShaderNode::sEffect2NodesMap;
MObject     cgfxShaderNode::sTechnique;
 
MObject     cgfxShaderNode::sAttributeList;
 
MObject     cgfxShaderNode::sVertexAttributeList;
 
MObject     cgfxShaderNode::sVertexAttributeSource;
 
MObject     cgfxShaderNode::sTexCoordSource;
 
MObject     cgfxShaderNode::sColorSource;
 
MObject     cgfxShaderNode::sTexturesByName;
 
enum ETexCoord
{
    etcNull      = -1,
    etcConstant  = -2,
    etcNormal    = -3,
    etcTangent   = -4,
    etcBinormal  = -5,
    etcDataSet   = -6,
};
cgfxShaderNode::cgfxShaderNode()
:   fCurrentTechnique( NULL)
,   fVertexAttributes( NULL)
#ifdef TEXTURES_BY_NAME
,   fTexturesByName( true )
#else
,   fTexturesByName( false )
#endif
,   fNormalsPerVertex( 3 )
,   fPassStateSetters( NULL )
,   fConstructed(false)
,   fErrorCount( 0 )
,   fErrorLimit( 8 )
,   fProfileName( "" )
,   fLastShaderFxFileAtVASSet( "" )
,   fShaderFxFile()
,   fShaderFxFileChanged( false )
,   fGeomReqDataVersionId( 0 )
,   fUVEditorTexture( NULL )
{
    
    setDataSources( &sa, &sa2 );
}
void
cgfxShaderNode::postConstructor()
{
    fConstructed = true;
    
    fCallbackIds.append(
            thisObj,
            attributeAddedOrRemovedCB,
}
cgfxShaderNode::~cgfxShaderNode()
{
    
    cgfxShaderNode::removeAssociation(this, fEffect);
#ifdef KH_DEBUG
    if ( fConstructed )
    {
        ss += fnNode.name();
    }
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    
    
    
    if (!fAttrDefList.isNull()) {
        fAttrDefList->releaseTextures();
    }
    
    fCallbackIds.clear();
    if (fUVEditorTexture) {
        if (theRenderer) {
            if (txtManager) {
            }
        }
    }
    delete [] fPassStateSetters;
}
{
    
    if ((plug == outColor) || (plug.
parent() == outColor))
 
    {
    }
}
void* cgfxShaderNode::creator()
{
    return new cgfxShaderNode();
}
cgfxShaderNode::initialize()
{
    try
    {
        initializeNodeAttrs();
    }
    catch ( cgfxShaderCommon::InternalError* e )   
    {
        size_t ee = (size_t)e;
        MString es = 
"cgfxShaderNode internal error ";
 
        es += (int)ee;
    }
    catch ( ... )
    {
        MString es = 
"cgfxShaderNode internal error: Unhandled exception in initialize";
 
    }
    return ms;
}
void
cgfxShaderNode::initializeNodeAttrs()
{
    
    
    
    M_CHECK( stat2 );
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    stat = addAttribute(sShader);
    M_CHECK( stat );
    
    
    
        stringData.
create(&stat2), &stat);
    M_CHECK( stat2 );
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    stat = addAttribute(sTechnique);
    M_CHECK( stat );
    
    
    
                                stringData.
create(&stat2), &stat);
    M_CHECK( stat2 );
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    stat = addAttribute(sProfile);
    M_CHECK( stat );
    
    
    
        stringArrayData.
create(&stat2), &stat);
    M_CHECK( stat2 );
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    stat = addAttribute(sAttributeList);
    M_CHECK( stat );
    
    
    
        stringArrayData.
create(&stat2), &stat);
    M_CHECK( stat2 );
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    M_CHECK( stat );
    
    
    stat = addAttribute(sVertexAttributeList);
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    M_CHECK( stat );
    M_CHECK( stat );
    stat = addAttribute( sVertexAttributeSource );
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    M_CHECK( stat );
    M_CHECK( stat );
    stat = addAttribute( sTexCoordSource );
    M_CHECK( stat );
    
    
    
    M_CHECK( stat );
    M_CHECK( stat );
    M_CHECK( stat );
    stat = addAttribute( sColorSource );
    M_CHECK( stat );
    
    
    
        0, &stat );
    M_CHECK( stat );
    M_CHECK( stat );
    M_CHECK( stat );
    
    
    
    
    
    
    
    M_CHECK( stat );
    stat = addAttribute( sTexturesByName );
    M_CHECK( stat );
}                                      
void
cgfxShaderNode::copyInternalData( 
MPxNode* pSrc )
{
    const cgfxShaderNode& src = *(cgfxShaderNode*)pSrc;
    setTexturesByName( src.getTexturesByName() );
    setShaderFxFile( src.shaderFxFile() );
    setShaderFxFileChanged( true );
    setDataSources( &src.getTexCoordSource(), &src.getColorSource() );
    
    
    fEffect = cgfxRCPtr<const cgfxEffect>();
    fCurrentTechnique = NULL;
    
    
    MString fileName = cgfxFindFile(shaderFxFile());
 
    bool hasFile = (fileName.
asChar() != NULL) && strcmp(fileName.
asChar(), 
"");
 
    if ( hasFile )
    {
        
        
        const cgfxRCPtr<const cgfxEffect> effect = cgfxEffect::loadEffect(fileName, cgfxProfile::getProfile(src.getProfile()));
        if (effect->isValid())
        {
            cgfxRCPtr<cgfxAttrDefList> effectList;
            
            
            cgfxAttrDef::updateNode(effect, this, &dagMod, effectList, attributeList);
#ifndef NDEBUG
#endif
            setAttrDefList(effectList);
            setAttributeList(attributeList);
            setEffect(effect);
        }
    }
    setTechnique( src.getTechnique() );
    setProfile( src.getProfile() );
}
bool cgfxShaderNode::setInternalValueInContext( 
const MPlug& plug,
 
{
    bool retVal = true;
    try
    {
#ifdef KH_DEBUG
        ss += plug.
partialName( 
true, 
true, 
true, 
false, 
false, 
true );
        if (plug == sShader ||
            plug == sTechnique)
        {
            ss += " \"";
            ss += "\"";
        }
        ss += "\n";
        ::OutputDebugString( ss.
asChar() );
#endif
        if (plug == sShader)
        {
        }
        else if (plug == sTechnique)
        {
        }
        else if (plug == sProfile)
        {
        }
        else if (plug == sAttributeList)
        {
            MObject saData = nonConstHandle.data();
 
            setAttributeList(fnSaData.array());
        }
        else if (plug == sVertexAttributeList)
        {
            MObject saData = nonConstHandle.data();
 
            cgfxRCPtr<cgfxVertexAttribute> attributes;
            cgfxRCPtr<cgfxVertexAttribute>* nextAttribute = &attributes;
            int numAttributes = attributeList.
length() / 4;
 
            for( int i = 0; i < numAttributes; i++)
            {
                cgfxRCPtr<cgfxVertexAttribute> attribute = cgfxRCPtr<cgfxVertexAttribute>(new cgfxVertexAttribute());
                attribute->fName = attributeList[ i * 4 + 0];
                attribute->fType = attributeList[ i * 4 + 1];
                attribute->fUIName = attributeList[ i * 4 + 2];
                attribute->fSemantic = attributeList[ i * 4 + 3];
                *nextAttribute = attribute;
                nextAttribute = &attribute->fNext;
            }
            setVertexAttributes( attributes );
        }
        else if ( plug == sVertexAttributeSource )
        {
            MObject     saData = nonConstHandle.data();
 
            setVertexAttributeSource( values);
        }
        else if ( plug == sTexCoordSource )
        {
            MObject     saData = nonConstHandle.data();
 
            setDataSources( &values, NULL );
        }
        else if ( plug == sColorSource )
        {
            MObject     saData = nonConstHandle.data();
 
            setDataSources( NULL, &values );
        }
        else if ( plug == sTexturesByName )
        {
        }
        else
        {
        }
    }
    catch ( cgfxShaderCommon::InternalError* e )
    {
        reportInternalError( __FILE__, (size_t)e );
        retVal = false;
    }
    catch ( ... )
    {
        reportInternalError( __FILE__, __LINE__ );
        retVal = false;
    }
    return retVal;
}
bool cgfxShaderNode::getInternalValueInContext( 
const MPlug& plug,
 
{
    bool retVal = true;
    try
    {
#ifdef KH_DEBUG
        ss += plug.
partialName( 
true, 
true, 
true, 
false, 
false, 
true );
        if ( plug == sShader )
            ss += " \"" + fShaderFxFile + "\"";
        else if (plug == sTechnique)
            ss += " \"" + fTechnique + "\"";
        ss += "\n";
        ::OutputDebugString( ss.
asChar() );
#endif
        if (plug == sShader)
        {
            handle.
set(fShaderFxFile);
        }
        else if (plug == sTechnique)
        {
        }
        else if (plug == sProfile)
        {
            handle.
set(fProfileName);
        }
        else if (plug == sAttributeList)
        {
            handle.
set(saData.
create(fAttributeListArray));
        }
        else if (plug == sVertexAttributeList)
        {
            cgfxRCPtr<cgfxVertexAttribute> attribute = fVertexAttributes;
            while( attribute.isNull() == false)
            {
                attributeList.
append( attribute->fName);
                attributeList.
append( attribute->fType);
                attributeList.
append( attribute->fUIName);
                attributeList.
append( attribute->fSemantic);
                attribute = attribute->fNext;
            }
        }
        else if ( plug == sVertexAttributeSource )
        {
            cgfxRCPtr<cgfxVertexAttribute> attribute = fVertexAttributes;
            while( attribute.isNull() == false)
            {
                attributeSources.
append( attribute->fSourceName);
                attribute = attribute->fNext;
            }
            handle.
set( saData.
create( attributeSources ) );
        }
        else if ( plug == sTexCoordSource )
        {
            handle.
set( saData.
create( fTexCoordSource ) );
        }
        else if ( plug == sColorSource )
        {
        }
        else if (plug == sTexturesByName)
        {
            handle.
set(fTexturesByName);
        }
        else
        {
        }
    }
    catch ( cgfxShaderCommon::InternalError* e )
    {
        reportInternalError( __FILE__, (size_t)e );
        retVal = false;
    }
    catch ( ... )
    {
        reportInternalError( __FILE__, __LINE__ );
        retVal = false;
    }
    return retVal;
}
static void checkGlErrors(const char* msg)
{
#if defined(CGFX_DEBUG)
#define MYERR(n)    case n: OutputDebugStrings("    ", #n); break
    GLenum err;
    bool errors = false;
    while ((err = glGetError()) != GL_NO_ERROR)
    {
        if (!errors)
        {
            
            
            OutputDebugStrings("OpenGl errors: ", msg);
        }
        errors = true;
        switch (err)
        {
            MYERR(GL_INVALID_ENUM);
            MYERR(GL_INVALID_VALUE);
            MYERR(GL_INVALID_OPERATION);
            MYERR(GL_STACK_OVERFLOW);
            MYERR(GL_STACK_UNDERFLOW);
            MYERR(GL_OUT_OF_MEMORY);
        default:
            {
                char tmp[32];
                sprintf(tmp, "%d", err);
                OutputDebugStrings("    GL Error #", tmp);
            }
        }
    }
#undef MYERR
#endif 
}
{
    cgfxAttrDef* aDef = (cgfxAttrDef*)aDefVoid;
    if (!status) {
        return;
    }
    if (plugAttr.name() == "fileTextureName") {
        MPlug outPlug(textureNode.findPlug(
"outColor", 
true));
 
            MPlug oplug(iter.thisPlug());
 
            if (oplug.attribute() == aDef->fAttr) {
                
                
                
                
                
                
                
                
                aDef->releaseCallback();
                
                
                aDef->fTexture->markAsStaled();
            }
        }
    }
}
#if defined(_SWATCH_RENDERING_SUPPORTED_)
{
    if( sCgContext == 0 )   return status;
    
    if (pRenderer)
    {
        
        
        unsigned int* pIndexing = 0;
        unsigned int  numberOfData = 0;
        unsigned int  indexCount = 0;
        if( !pGeomData )
        {
        }
        
        
        
        unsigned int width, height;
        unsigned int origWidth = width;
        unsigned int origHeight = height;
        {
            return status2;
        }
        glPushAttrib ( GL_ALL_ATTRIB_BITS );
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        
        
        {
            float light_pos[4];
        }
        
        
        {
            
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            double l, r, b, t, n, f;
            glFrustum( l, r, b, t, n, f );
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            float x, y, z, w;
            glTranslatef( x, y, z );
        }
        
        
        float r, g, b, a;
        glClearColor( r, g, b, a );
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glShadeModel(GL_SMOOTH);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        
        
        
        glBind( dummyPath );
        float *vertexData = (float *)( pGeomData[0].data() );
        float *normalData = (float *)( pGeomData[1].data() );
        float *uvData = (float *)( pGeomData[2].data() );
        float *tangentData = (float *)( pGeomData[3].data() );
        float *binormalData = (float *)( pGeomData[4].data() );
        
        int uvCount = fUVSets.length();
        float ** texCoordArrays = uvCount ? new float * [ uvCount] : NULL;
        for( int uv = 0; uv < uvCount; uv++)
        {
            texCoordArrays[ uv] = uvData;
        }
        
        int normalCount = uvCount > 0 ? uvCount : 1;
        float ** normalArrays = new float * [ fNormalsPerVertex * normalCount];
        for( int n = 0; n < normalCount; n++)
        {
            if( fNormalsPerVertex > 0)
            {
                normalArrays[ n * fNormalsPerVertex + 0] = normalData;
                if( fNormalsPerVertex > 1)
                {
                    normalArrays[ n * fNormalsPerVertex + 1] = tangentData;
                    if( fNormalsPerVertex > 2)
                    {
                        normalArrays[ n * fNormalsPerVertex + 2] = binormalData;
                    }
                }
            }
        }
        glGeometry( dummyPath,
                    GL_TRIANGLES,
                    false,
                    indexCount,
                    pIndexing,
                    pGeomData[0].elementCount(),
                    NULL, 
                    vertexData,
                    fNormalsPerVertex,
                    (const float **) normalArrays,
                    0,
                    NULL, 
                    uvCount,
                    (const float **) texCoordArrays);
        glUnbind( dummyPath );
        if( normalArrays) delete[] normalArrays;
        if( texCoordArrays) delete[] texCoordArrays;
        
        
        
        
        if (width != origWidth || height != origHeight)
        {
        }
        else
        {
        }
        
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
        glPopAttrib();
        
    }
    return status;
}
#endif
bool cgfxShaderNode::supportsBatching() const
{
    return true;
}
bool cgfxShaderNode::invertTexCoords() const
{
    if (cgfxProfile::getTexCoordOrientation() == cgfxProfile::TEXCOORD_OPENGL)
        return false;
    else
        return true;
}
bool cgfxShaderNode::createEffect()
{
    
    
    
    
    
    
    bool rc = false;
    if (shaderFxFileChanged())
    {
        MString fileName = cgfxFindFile(shaderFxFile());
 
        if(fileName.
asChar() != NULL && strcmp(fileName.
asChar(), 
""))
 
        {
            
            const cgfxRCPtr<const cgfxEffect> effect = cgfxEffect::loadEffect(fileName, cgfxProfile::getProfile(fProfileName));
            if (effect->isValid())
            {
                cgfxRCPtr<cgfxAttrDefList> effectList;
                
                
                
                
                
                
                
                cgfxAttrDef::updateNode(effect, this, &dagMod, effectList, attributeList);
#ifndef NDEBUG
#endif
                
                setAttrDefList(effectList);
                setAttributeList(attributeList);
                setEffect(effect);
                setTechnique(fTechnique);
                rc = true;
            }
        }
        setShaderFxFileChanged( false );
    }
    return rc;
}
{
    
    
    
    
    glStateCache::instance().reset();
    
    
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
    
    
    
    
    
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += " ";
    ss += request.multiPath().fullPathName();
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    try
    {
        
        if ( glStateCache::sMaxTextureUnits <= 0 )
        {
            
            
            
#ifdef _WIN32
#define RESOLVE_GL_EXTENSION( fn, ext) wglGetProcAddress( #fn #ext)
#elif defined LINUX
#define RESOLVE_GL_EXTENSION( fn, ext) &fn ## ext
#else
#define RESOLVE_GL_EXTENSION( fn, ext) &fn
#endif
            glStateCache::glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREARBPROC) RESOLVE_GL_EXTENSION( glClientActiveTexture, ARB);
            glStateCache::glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERARBPROC) RESOLVE_GL_EXTENSION( glVertexAttribPointer, ARB);
            glStateCache::glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) RESOLVE_GL_EXTENSION( glEnableVertexAttribArray, ARB);
            glStateCache::glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) RESOLVE_GL_EXTENSION( glDisableVertexAttribArray, ARB);
            glStateCache::glVertexAttrib4f = (PFNGLVERTEXATTRIB4FARBPROC) RESOLVE_GL_EXTENSION( glVertexAttrib4f, ARB);
            glStateCache::glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTEREXTPROC) RESOLVE_GL_EXTENSION( glSecondaryColorPointer, EXT);
            glStateCache::glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FEXTPROC) RESOLVE_GL_EXTENSION( glSecondaryColor3f, EXT);
            glStateCache::glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) RESOLVE_GL_EXTENSION( glMultiTexCoord4f, ARB);
            
            
            
            
            
            
            
            
            GLint tval;
            glGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &tval );
            GLint mic = 0;
            glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &mic );
            if (mic < tval)
                tval = mic;
            
            
            glStateCache::sMaxTextureUnits = tval;
            if (!glStateCache::glClientActiveTexture || glStateCache::sMaxTextureUnits < 1)
                glStateCache::sMaxTextureUnits = 1;
            else if (glStateCache::sMaxTextureUnits > CGFXSHADERNODE_GL_TEXTURE_MAX)
                glStateCache::sMaxTextureUnits = CGFXSHADERNODE_GL_TEXTURE_MAX;
        }
        
        if(fCurrentTechnique && fCurrentTechnique->isValid())
        {
            
            bindAttrValues();
            
            if (fCurrentTechnique->hasBlending())
                glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
            glGetBooleanv( GL_DEPTH_TEST, &fDepthEnableState);
            glGetIntegerv( GL_DEPTH_FUNC, &fDepthFunc);
            glGetIntegerv( GL_BLEND_SRC, &fBlendSourceFactor);
            glGetIntegerv( GL_BLEND_DST, &fBlendDestFactor);
            glDepthFunc(GL_LEQUAL);
        }
        else
        {
            
            
            
            
            
            glPushAttrib( GL_LIGHTING);
            static float diffuse_color[4]  = {1.0, 0.5, 0.5, 1.0};
            static float specular_color[4] = {1.0, 1.0, 1.0, 1.0};
            glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
            glEnable(GL_COLOR_MATERIAL);
            glColor4fv(diffuse_color);
            
            
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_color);
            
            
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0);
        }
        checkGlErrors("cgfxShaderNode::glBind");
    }
    catch ( cgfxShaderCommon::InternalError* e )
    {
        reportInternalError( __FILE__, (size_t)e );
    }
    catch ( ... )
    {
        reportInternalError( __FILE__, __LINE__ );
    }
    return stat;
}                                      
void cgfxShaderNode::bindAttrValues()
{
    if (fEffect.isNull() || !fEffect->isValid() || !fTechnique.length())
        return;
    
    
    
    
    for ( cgfxAttrDefList::iterator it( fAttrDefList ); it; ++it )
    {                                  
        cgfxAttrDef* aDef = *it;
        try
        {
            switch (aDef->fType)
            {
            case cgfxAttrDef::kAttrTypeBool:
                {
                    bool tmp;
                    aDef->getValue(oNode, tmp);
                    cgSetParameter1i(aDef->fParameterHandle, tmp);
                    break;
                }
            case cgfxAttrDef::kAttrTypeInt:
                {
                    int tmp;
                    aDef->getValue(oNode, tmp);
                    cgSetParameter1i(aDef->fParameterHandle, tmp);
                    break;
                }
            case cgfxAttrDef::kAttrTypeFloat:
                {
                    float tmp;
                    aDef->getValue(oNode, tmp);
                    cgSetParameter1f(aDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeString:
                {
                    aDef->getValue(oNode, tmp);
                    cgSetStringParameterValue(aDef->fParameterHandle, tmp.
asChar());
                    break;
                }
            case cgfxAttrDef::kAttrTypeVector2:
                {
                    float tmp[2];
                    aDef->getValue(oNode, tmp[0], tmp[1]);
                    cgSetParameter2fv(aDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeVector3:
            case cgfxAttrDef::kAttrTypeColor3:
                {
                    float tmp[3];
                    aDef->getValue(oNode, tmp[0], tmp[1], tmp[2]);
                    cgSetParameter3fv(aDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeVector4:
            case cgfxAttrDef::kAttrTypeColor4:
                {
                    float tmp[4];
                    aDef->getValue(oNode, tmp[0], tmp[1], tmp[2], tmp[3]);
                    cgSetParameter4fv(aDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeWorldDir:
            case cgfxAttrDef::kAttrTypeWorldPos:
                {
                    
                    
                    float tmp[4];
                    if (aDef->fSize == 3)
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2]);
                        tmp[3] = 1.0;
                    }
                    else
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2], tmp[3]);
                    }
                    cgSetParameterValuefr(aDef->fParameterHandle, aDef->fSize, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeMatrix:
                {
                    float tmp2[4][4];
                    aDef->getValue(oNode, tmp);
                    if (aDef->fInvertMatrix)
                    {
                    }
                    if (!aDef->fTransposeMatrix)
                    {
                    }
                    cgSetMatrixParameterfr(aDef->fParameterHandle, &tmp2[0][0]);
                    break;
                }
            case cgfxAttrDef::kAttrTypeColor1DTexture:
            case cgfxAttrDef::kAttrTypeColor2DTexture:
            case cgfxAttrDef::kAttrTypeColor3DTexture:
            case cgfxAttrDef::kAttrTypeColor2DRectTexture:
            case cgfxAttrDef::kAttrTypeNormalTexture:
            case cgfxAttrDef::kAttrTypeBumpTexture:
            case cgfxAttrDef::kAttrTypeCubeTexture:
            case cgfxAttrDef::kAttrTypeEnvTexture:
            case cgfxAttrDef::kAttrTypeNormalizationTexture:
                {
                    if( fTexturesByName)
                    {
                        aDef->getValue(oNode, texFileName);
                    }
                    else
                    {
                        
                        
                        aDef->getSource(oNode, srcPlug);
                        {
                            MPlug filenamePlug = dgFn.findPlug( 
"fileTextureName", &rc);
 
                            {
                                textureNode = filenamePlug.
node(&rc);
                            }
                            
                            
                            
                            
                            
                            {
                                
                                
                                
                                
                                aDef->releaseTexture();
                                aDef->fTextureMonitor =
                            }
                        }
                    }
                    if (aDef->fTexture.isNull() || texFileName != aDef->fStringDef)
                    {
                        aDef->fStringDef = texFileName;
                        aDef->fTexture = cgfxTextureCache::instance().getTexture(
                            texFileName, textureNode, fShaderFxFile,
                            aDef->fName, aDef->fType);
                        if (!aDef->fTexture->isValid() && texFileName.
length() > 0) {
 
                            sMsg += fnNode.name();
                            sMsg += " : failed to load texture \"";
                            sMsg += texFileName;
                            sMsg += "\".";
                        }
                    }
                    checkGlErrors("After loading texture");
                    cgGLSetupSampler(aDef->fParameterHandle, aDef->fTexture->getTextureId());
                    break;
                }
#ifdef _WIN32
            case cgfxAttrDef::kAttrTypeTime:
                {
                    int ival = timeGetTime() & 0xffffff;
                    float val = (float)ival * 0.001f;
                    cgSetParameter1f(aDef->fParameterHandle, val);
                    break;
                }
#endif
            case cgfxAttrDef::kAttrTypeOther:
            case cgfxAttrDef::kAttrTypeUnknown:
                break;
            case cgfxAttrDef::kAttrTypeObjectDir:
            case cgfxAttrDef::kAttrTypeViewDir:
            case cgfxAttrDef::kAttrTypeProjectionDir:
            case cgfxAttrDef::kAttrTypeScreenDir:
            case cgfxAttrDef::kAttrTypeObjectPos:
            case cgfxAttrDef::kAttrTypeViewPos:
            case cgfxAttrDef::kAttrTypeProjectionPos:
            case cgfxAttrDef::kAttrTypeScreenPos:
            case cgfxAttrDef::kAttrTypeWorldMatrix:
            case cgfxAttrDef::kAttrTypeViewMatrix:
            case cgfxAttrDef::kAttrTypeProjectionMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                
                break;
            default:
                M_CHECK( false );
            }                          
        }
        catch ( cgfxShaderCommon::InternalError* e )
        {
            if ( ++fErrorCount <= fErrorLimit )
            {
                size_t ee = (size_t)e;
                MString sMsg = 
"cgfxShader warning ";
 
                sMsg += (int)ee;
                sMsg += ": ";
                sMsg += fnNode.name();
                sMsg += " internal error while setting parameter \"";
                sMsg += aDef->fName;
                sMsg += "\" of effect \"";
                sMsg += fShaderFxFile;
                sMsg += "\" for shape ";
                sMsg += currentPath().partialPathName();
            }
        }
    }                                  
}                                      
void
cgfxShaderNode::bindViewAttrValues(
const MDagPath& shapePath)
{
    if (fEffect.isNull() || !fEffect->isValid() || !fTechnique.length())
        return;
    MMatrix wMatrix, vMatrix, pMatrix, sMatrix;
 
    MMatrix wvMatrix, wvpMatrix, wvpsMatrix;
 
    {
        float tmp[4][4];
        else
        glGetFloatv(GL_MODELVIEW_MATRIX, &tmp[0][0]);
        vMatrix = wMatrix.
inverse() * wvMatrix;
        glGetFloatv(GL_PROJECTION_MATRIX, &tmp[0][0]);
        wvpMatrix = wvMatrix * pMatrix;
        float vpt[4];
        float depth[2];
        glGetFloatv(GL_VIEWPORT, vpt);
        glGetFloatv(GL_DEPTH_RANGE, depth);
        
        
        float x0, y0, z0, w, h, d;
        x0 = vpt[0];
        y0 = vpt[1];
        z0 = depth[0];
        w  = vpt[2];
        h  = vpt[3];
        d  = depth[1] - z0;
        
        
        double* s = &sMatrix.
matrix[0][0];
 
        s[ 0] = w/2;    s[ 1] = 0.0;    s[ 2] = 0.0;    s[ 3] = 0.0;
        s[ 4] = 0.0;    s[ 5] = h/2;    s[ 6] = 0.0;    s[ 7] = 0.0;
        s[ 8] = 0.0;    s[ 9] = 0.0;    s[10] = d/2;    s[11] = 0.0;
        s[12] = x0+w/2; s[13] = y0+h/2; s[14] = z0+d/2; s[15] = 1.0;
        wvpsMatrix = wvpMatrix * sMatrix;
    }
    for ( cgfxAttrDefList::iterator it( fAttrDefList ); it; ++it )
    {                                  
        cgfxAttrDef* aDef = *it;
        try
        {
            switch (aDef->fType)
            {
            case cgfxAttrDef::kAttrTypeObjectDir:
            case cgfxAttrDef::kAttrTypeViewDir:
            case cgfxAttrDef::kAttrTypeProjectionDir:
            case cgfxAttrDef::kAttrTypeScreenDir:
            case cgfxAttrDef::kAttrTypeObjectPos:
            case cgfxAttrDef::kAttrTypeViewPos:
            case cgfxAttrDef::kAttrTypeProjectionPos:
            case cgfxAttrDef::kAttrTypeScreenPos:
                {
                    float tmp[4];
                    if (aDef->fSize == 3)
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2]);
                        tmp[3] = 1.0;
                    }
                    else
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2], tmp[3]);
                    }
                    
                    
                    
                    
                    MVector vec(tmp[0], tmp[1], tmp[2]);
 
                    int space = aDef->fType - cgfxAttrDef::kAttrTypeFirstPos;
                    if (space < 0)
                    {
                        space = aDef->fType - cgfxAttrDef::kAttrTypeFirstDir;
                    }
                    switch (space)
                    {
                    case 0:     break;
                    case 1: mat = wMatrix;          break;
                    case 2: mat = wvMatrix;         break;
                    case 3: mat = wvpMatrix;        break;
                    case 4: mat = wvpsMatrix;       break;
                    }
                    
                    
                    
                    
                    int base = cgfxAttrDef::kAttrTypeFirstPos;
                    if (aDef->fType <= cgfxAttrDef::kAttrTypeLastDir)
                        base = cgfxAttrDef::kAttrTypeFirstDir;
                    if (base == cgfxAttrDef::kAttrTypeFirstPos)
                    {
                        MPoint point(tmp[0], tmp[1], tmp[2], tmp[3]);
 
                        tmp[0] = (float)point.x;
                        tmp[1] = (float)point.y;
                        tmp[2] = (float)point.z;
                        tmp[3] = (float)point.w;
                    }
                    else
                    {
                        MVector vec(tmp[0], tmp[1], tmp[2]);
 
                        tmp[0] = (float)vec.x;
                        tmp[1] = (float)vec.y;
                        tmp[2] = (float)vec.z;
                        tmp[3] = 1.F;
                    }
                    cgSetParameterValuefc(aDef->fParameterHandle, aDef->fSize, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeWorldMatrix:
            case cgfxAttrDef::kAttrTypeViewMatrix:
            case cgfxAttrDef::kAttrTypeProjectionMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                {
                    switch (aDef->fType)
                    {
                    case cgfxAttrDef::kAttrTypeWorldMatrix:
                        mat = wMatrix; break;
                    case cgfxAttrDef::kAttrTypeViewMatrix:
                        mat = vMatrix; break;
                    case cgfxAttrDef::kAttrTypeProjectionMatrix:
                        mat = pMatrix; break;
                    case cgfxAttrDef::kAttrTypeWorldViewMatrix:
                        mat = wvMatrix; break;
                    case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                        mat = wvpMatrix; break;
                    default:
                        break;
                    }
                    if (aDef->fInvertMatrix)
                    {
                    }
                    if (!aDef->fTransposeMatrix)
                    {
                    }
                    float tmp[4][4];
                    cgSetMatrixParameterfr(aDef->fParameterHandle, &tmp[0][0]);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogEnabled:
            case cgfxAttrDef::kAttrTypeHardwareFogMode:
            case cgfxAttrDef::kAttrTypeHardwareFogStart:
            case cgfxAttrDef::kAttrTypeHardwareFogEnd:
            case cgfxAttrDef::kAttrTypeHardwareFogDensity:
            case cgfxAttrDef::kAttrTypeHardwareFogColor:
                    break;
                default:
                    break;
            }                          
        }
        catch ( cgfxShaderCommon::InternalError* e )
        {
            if ( ++fErrorCount <= fErrorLimit )
            {
                size_t ee = (size_t)e;
                MString sMsg = 
"cgfxShader warning ";
 
                sMsg += (int)ee;
                sMsg += ": ";
                sMsg += fnNode.name();
                sMsg += " internal error while setting parameter \"";
                sMsg += aDef->fName;
                sMsg += "\" of effect \"";
                sMsg += fShaderFxFile;
                sMsg += "\" for shape ";
                else
                    sMsg += "SWATCH GEOMETRY";
            }
        }
    }                                  
}
{
    if (fCurrentTechnique && fCurrentTechnique->isValid())
    {
        
        if( fDepthEnableState)
            glEnable( GL_DEPTH_TEST);
        else
            glDisable( GL_DEPTH_TEST);
        glDepthFunc( fDepthFunc);
        glBlendFunc( fBlendSourceFactor, fBlendDestFactor);
        if (fCurrentTechnique->hasBlending())
            glPopAttrib();
    }
    else
    {
        
        glPopAttrib();
    }
    glPopClientAttrib();
    glPopAttrib();
    glStateCache::instance().disableAll();
    glStateCache::instance().activeTexture( 0);
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
}
                                    int prim,
                                    unsigned int writable,
                                    int indexCount,
                                    const unsigned int * indexArray,
                                    int vertexCount,
                                    const int * vertexIDs,
                                    const float * vertexArray,
                                    int normalCount,
                                    const float ** normalArrays,
                                    int colorCount,
                                    const float ** colorArrays,
                                    int texCoordCount,
                                    const float ** texCoordArrays)
{
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += " ";
    ss += indexCount;
    ss += "i ";
    ss += vertexCount;
    ss += "v ";
    ss += normalCount;
    ss += "n ";
    ss += colorCount;
    ss += "c ";
    ss += texCoordCount;
    ss += "t ";
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    try
    {
        if (fCurrentTechnique && fCurrentTechnique->isValid())
        {
            
            cgfxPassStateSetter::registerCgStateCallBacks(
                cgfxPassStateSetter::kDefaultViewport);
            
            bindViewAttrValues(shapePath);
            
            if( dirtyMask() != kDirtyNone)
                fBoundDataCache.flush(shapePath);
            
            const cgfxPass* pass = fCurrentTechnique->getFirstPass();
            while( pass)
            {
                pass->bind(shapePath, &fBoundDataCache,
                           vertexCount, vertexArray,
                           fNormalsPerVertex, normalCount, normalArrays,
                           colorCount, colorArrays,
                           texCoordCount, texCoordArrays);
                glStateCache::instance().flushState();
                pass->setCgState();
                glDrawElements(prim, indexCount, GL_UNSIGNED_INT, indexArray);
                pass->resetCgState();
                pass = pass->getNext();
            }
        }
        else 
        {
            
            
            
            glStateCache::instance().enablePosition();
            glVertexPointer(3, GL_FLOAT, 0, vertexArray);
            if ( normalCount > 0 && normalArrays[ 0 ] )
            {
                glStateCache::instance().enableNormal();
                glNormalPointer(GL_FLOAT, 0, normalArrays[0]);
            }
            else
            {
                glStateCache::instance().disableNormal();
                glNormal3f(0.0, 0.0, 1.0);
            }
            glStateCache::instance().flushState();
            glDrawElements(prim, indexCount, GL_UNSIGNED_INT, indexArray);
        }
        checkGlErrors("After effects End");
    }
    catch ( cgfxShaderCommon::InternalError* e )
    {
        reportInternalError( __FILE__, (size_t)e );
    }
    catch ( ... )
    {
        reportInternalError( __FILE__, __LINE__ );
    }
    return stat;
}                                      
int
{
    names = fUVSets;
}                                      
#if MAYA_API_VERSION >= 700
int
{
    names = fColorSets;
}
#else
int cgfxShaderNode::colorsPerVertex()
{
    fColorType.setLength(1);
    fColorIndex.setLength(1);
    fColorType[0] = 0;
    fColorIndex[0] = 0;
    return 1;
} 
#endif
int cgfxShaderNode::normalsPerVertex()
{
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += " ";
    ss += fNormalsPerVertex;
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    
    
    
    if (fEffect.isNull() || !fEffect->isValid()) {
#ifdef _WIN32
        ::OutputDebugString( "CGFX: fEffect was NULL\n");
#endif
        
        
        
        
        
        
        createEffect();
    }
    return fNormalsPerVertex;
    
    
    
    
}                                      
cgfxShaderNode::getAvailableImages( 
const MString& uvSetName,
{
    
    
    
    cgfxRCPtr<cgfxVertexAttribute> attr = fVertexAttributes;
    while( attr.isNull() == false )
    {
        MString source = attr->fSourceName;
 
        source.
split( 
':', sourceArray );
        if( sourceArray.
length() == 2               &&
 
            sourceArray[0].toLowerCase() == "uv"    &&
            sourceArray[1] == uvSetName             )
        {
            varNames.
append( attr->fName );
        }
        attr = attr->fNext;
    }
    
    
    
    const cgfxRCPtr<cgfxAttrDefList>& nodeList = attrDefList();
    if( nodeList.isNull() )
    {
        
        
        
    }
    unsigned int nVars = varNames.
length();
 
    for( unsigned int i = 0; i < nVars; i++ )
    {
        cgfxAttrDefList::iterator nmIt;
        for (nmIt = nodeList->begin(); nmIt; ++nmIt)
        {
            cgfxAttrDef* adef = (*nmIt);
            if( adef->fType == cgfxAttrDef::kAttrTypeColor2DTexture &&
                adef->fTextureUVLink == varNames[i] )
            {
                imageNames.
append( adef->fName );
            }
        }
    }
    
    
    if( imageNames.
length() == 0 )
 
    {
        cgfxAttrDefList::iterator nmIt;
        for (nmIt = nodeList->begin(); nmIt; ++nmIt)
        {
            cgfxAttrDef* adef = (*nmIt);
            if( adef->fType == cgfxAttrDef::kAttrTypeColor2DTexture )
            {
                imageNames.
append( adef->fName );
            }
        }
    }
}
cgfxShaderNode::renderImage( 
const MString& imageName,
                            floatRegion region,
                            int& imageWidth,
                            int& imageHeight)
{
    
    const cgfxRCPtr<cgfxAttrDefList>& nodeList = attrDefList();
    cgfxAttrDef* texDef = NULL;
    cgfxAttrDefList::iterator nmIt;
    for (nmIt = nodeList->begin(); nmIt; ++nmIt)
    {
        cgfxAttrDef* adef = (*nmIt);
        if( adef->fType >= cgfxAttrDef::kAttrTypeFirstTexture   &&
            adef->fType <= cgfxAttrDef::kAttrTypeLastTexture    &&
            adef->fName == imageName )
        {
            texDef = adef;
            break;
        }
    }
    if( !texDef )
    {
    }
    
    
    if( texDef->fType != cgfxAttrDef::kAttrTypeColor2DTexture )
    {
    }
    
    
    glPushAttrib( GL_ALL_ATTRIB_BITS );
    glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT);
    
    
    
    texDef->getSource( thisNode, texPlug );
    {
        glPopAttrib();
        glPopClientAttrib();
        sMsg += fnNode.name();
        sMsg += " : failed to load texture \"";
        sMsg += imageName;
        sMsg += "\".";
    }
    GLint width = 0;
    GLint height = 0;
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glBegin( GL_QUADS );
    glTexCoord2f(region[0][0], region[0][1]);
    glVertex2f(region[0][0], region[0][1]);
    glTexCoord2f(region[0][0], region[1][1]);
    glVertex2f(region[0][0], region[1][1]);
    glTexCoord2f(region[1][0], region[1][1]);
    glVertex2f(region[1][0], region[1][1]);
    glTexCoord2f(region[1][0], region[0][1]);
    glVertex2f(region[1][0], region[0][1]);
    glEnd();
    glPopAttrib();
    glPopClientAttrib();
    imageWidth = (int) width;
    imageHeight = (int) height;
}
                            floatRegion region,
                            int& imageWidth,
                            int& imageHeight)
{
    
    const cgfxRCPtr<cgfxAttrDefList>& nodeList = attrDefList();
    cgfxAttrDef* texDef = NULL;
    cgfxAttrDefList::iterator nmIt;
    for (nmIt = nodeList->begin(); nmIt; ++nmIt)
    {
        cgfxAttrDef* adef = (*nmIt);
        if( adef->fType >= cgfxAttrDef::kAttrTypeFirstTexture   &&
            adef->fType <= cgfxAttrDef::kAttrTypeLastTexture    &&
            adef->fName == imageName )
        {
            texDef = adef;
            break;
        }
    }
    if( !texDef )
    {
    }
    
    
    if( texDef->fType != cgfxAttrDef::kAttrTypeColor2DTexture )
    {
    }
    
    
    
    
    {
        texDef->getSource( thisNode, texPlug );
        MPlug filenamePlug = dgFn.findPlug( 
"fileTextureName", &rc);
 
        }
    }
    if(textureFileName.
length() == 0)
 
    if(theRenderer == NULL)
    if(txtManager == NULL)
    int mipmapLevels = 1;
    if(texture == NULL)
    
    
    
    if(fUVEditorTexture) {
    }
    fUVEditorTexture = texture;
    
    if(region[0][0] == 0 && region[0][1] == 0 && region[1][0] == 0 && region[1][1] == 0)
    
    
    positions.
append(region[0][0], region[0][1]);
    positions.
append(region[1][0], region[0][1]);
    positions.
append(region[1][0], region[1][1]);
    
    positions.
append(region[0][0], region[0][1]);
    positions.
append(region[1][0], region[1][1]);
    positions.
append(region[0][0], region[1][1]);
    uiDrawManager.
setColor( parameters.
baseColor );
}
void
cgfxShaderNode::setAttrDefList( const cgfxRCPtr<cgfxAttrDefList>& list )
{
    if (!fAttrDefList.isNull()) {
        cgfxAttrDef::purgeMObjectCache( fAttrDefList );
    }
    if (!list.isNull()) {
        cgfxAttrDef::validateMObjectCache( thisMObject(), list );
    }
    fAttrDefList = list;
}                                      
void cgfxShaderNode::getAttributeList(
MStringArray& attrList)
 const 
{
    int len = fAttributeListArray.
length();
 
    for (int i = 0; i < len; ++i)
    {
        tmp = fAttributeListArray[i];
    }
}
void cgfxShaderNode::setAttributeList(
const MStringArray& attrList)
 
{
    fAttributeListArray.clear();
    for (int i = 0; i < len; ++i)
    {
        tmp = attrList[i];
        fAttributeListArray.
append(tmp);
    }
}
void
cgfxShaderNode::setVertexAttributes( cgfxRCPtr<cgfxVertexAttribute> attributeList)
{
    
    
    
    if( fTexCoordSource.length())
    {
        int length = fTexCoordSource.length();
        for( int i = 0; i < length; i++)
        {
            if( i)
                semantic += i;
            else
                semantic += "0";
            MString source( fTexCoordSource[ i]);
 
            if( source.
index( 
':') < 0)
 
                source = "uv:" + source;
            cgfxRCPtr<cgfxVertexAttribute> newAttribute = attributeList;
            while( newAttribute.isNull() == false)
            {
                if( newAttribute->fSemantic == semantic ||
                    (i == 6 && (newAttribute->fSemantic == "TANGENT" || newAttribute->fSemantic == "TANGENT0")) ||
                    (i == 7 && (newAttribute->fSemantic == "BINORMAL" || newAttribute->fSemantic == "BINORMAL0")))
                    newAttribute->fSourceName = source;
                newAttribute = newAttribute->fNext;
            }
        }
    }
    if( fColorSource.length())
    {
        int length = fColorSource.length();
        for( int i = 0; i < length; i++)
        {
            if( i)
                semantic += i;
            else
                semantic += "0";
            if( source.
index( 
':') < 0)
 
                source = "color:" + source;
            cgfxRCPtr<cgfxVertexAttribute> newAttribute = attributeList;
            while( newAttribute.isNull() == false)
            {
                if( newAttribute->fSemantic == semantic)
                    newAttribute->fSourceName = source;
                newAttribute = newAttribute->fNext;
            }
        }
    }
    
    
    
    if (fLastShaderFxFileAtVASSet == fShaderFxFile)
    {
        cgfxRCPtr<cgfxVertexAttribute> oldAttribute = fVertexAttributes;
        while (oldAttribute.isNull() == false)
        {
            cgfxRCPtr<cgfxVertexAttribute> newAttribute = attributeList;
            while (newAttribute.isNull() == false)
            {
                if (newAttribute->fSourceName.length() == 0 &&
                    newAttribute->fName == oldAttribute->fName &&
                    newAttribute->fSemantic == oldAttribute->fSemantic &&
                    newAttribute->fType == oldAttribute->fType)
                {
                    newAttribute->fSourceName = oldAttribute->fSourceName;
                    break;
                }
                newAttribute = newAttribute->fNext;
            }
            oldAttribute = oldAttribute->fNext;
        }
    }
    
    fVertexAttributes = attributeList;
    
    
    analyseVertexAttributes();
}
void
cgfxShaderNode::setVertexAttributeSource( 
const MStringArray& sources)
{
    
    fBoundDataCache.flush();
    
    int i = 0;
    int numSources = sources.
length();
 
    cgfxRCPtr<cgfxVertexAttribute> attribute = fVertexAttributes;
    while( attribute.isNull() == false)
    {
        attribute->fSourceName = ( i <  numSources) ? sources[ i++] : "";
        attribute = attribute->fNext;
    }
    
    fLastShaderFxFileAtVASSet = fShaderFxFile;
    
    
    analyseVertexAttributes();
}
{
    for( int i = 0; i < length; i++)
        if( list[ i] == value)
            return i;
    return length;
}
void
cgfxShaderNode::analyseVertexAttributes()
{
    ++fGeomReqDataVersionId;
    fColorSets.clear();
    fNormalsPerVertex = 0;
    cgfxRCPtr<cgfxVertexAttribute> attribute = fVertexAttributes;
    while( attribute.isNull() == false)
    {
        
        MString source( attribute->fSourceName);
 
        if( attribute->fSourceName.length() == 0)
        {
            attribute->fSourceType = cgfxVertexAttribute::kNone;
            
            if(attribute->fSemantic == "POSITION")
            {
                const MString warnMsg = 
"position can't be empty! Will use default position data!";
 
                attribute->fSourceName = "position";
                attribute->fSourceType = cgfxVertexAttribute::kPosition;
            }
        }
        else if( source == "position")
        {
            attribute->fSourceType = cgfxVertexAttribute::kPosition;
        }
        else if( source == "normal")
        {
            attribute->fSourceType = cgfxVertexAttribute::kNormal;
            if( fNormalsPerVertex < 1)
                fNormalsPerVertex = 1;
        }
        else
        {
            
            MString set = attribute->fSourceName;
 
            int colon = set.
index( 
':');
 
            if( colon >= 0)
            {
                if( colon > 0) type = source.
substring( 0, colon - 1);
 
            }
            
            if( type == "uv")
            {
                attribute->fSourceType = cgfxVertexAttribute::kUV;
                attribute->fSourceIndex = findOrInsert( set, fUVSets);
            }
            else if( type == "tangent")
            {
                attribute->fSourceType = cgfxVertexAttribute::kTangent;
                if( fNormalsPerVertex < 2)
                    fNormalsPerVertex = 2;
                attribute->fSourceIndex = findOrInsert( set, fUVSets);
            }
            else if( type == "binormal")
            {
                attribute->fSourceType = cgfxVertexAttribute::kBinormal;
                if( fNormalsPerVertex < 3)
                    fNormalsPerVertex = 3;
                attribute->fSourceIndex = findOrInsert( set, fUVSets);
            }
            else if( type == "color")
            {
                attribute->fSourceType = cgfxVertexAttribute::kColor;
                attribute->fSourceIndex = findOrInsert( set, fColorSets);
            }
            else
            {
                attribute->fSourceType = cgfxVertexAttribute::kBlindData;
            }
        }
        attribute = attribute->fNext;
    }
    
}
cgfxShaderNode::getTexCoordSource() const
{
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += " ";
    for ( int ii = 0; ii < fTexCoordSource.length(); ++ii )
    {
        ss += "\"";
        ss += fTexCoordSource[ii];
        ss += "\" ";
    }
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    return fTexCoordSource;
}                                      
cgfxShaderNode::getColorSource() const
{
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += " ";
    for ( int ii = 0; ii < fColorSource.length(); ++ii )
    {
        ss += "\"";
        ss += fColorSource[ii];
        ss += "\" ";
    }
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    return fColorSource;
}                                      
void
cgfxShaderNode::setDataSources( 
const MStringArray* texCoordSources,
{
    if( texCoordSources )
    {
        int length_TC = texCoordSources->
length();
 
        if ( length_TC > CGFXSHADERNODE_GL_TEXTURE_MAX )
            length_TC = CGFXSHADERNODE_GL_TEXTURE_MAX;
        fTexCoordSource.clear();
        for ( int i = 0; i < length_TC; ++i )
        {
            fTexCoordSource.append( (*texCoordSources)[ i ] );
        }
        
        
        
        
        
    }
    if( colorSources )
    {
        int length_CS = colorSources->
length();
 
        if ( length_CS > CGFXSHADERNODE_GL_COLOR_MAX )
            length_CS = CGFXSHADERNODE_GL_COLOR_MAX;
        fColorSource.setLength( length_CS );
        for ( int i = 0; i < length_CS; ++i )
            fColorSource[ i ] = (*colorSources)[ i ];
    }
    fDataSetNames.clear();
    fNormalsPerVertex = 1;
    updateDataSource( fTexCoordSource, fTexCoordType, fTexCoordIndex);
    updateDataSource( fColorSource, fColorType, fColorIndex);
}
void
{
#ifdef KH_DEBUG
    if ( this && fConstructed )
        ss += name();
    ss += " ";
    for ( 
int ii = 0; ii < v.
length(); ++ii )
 
    {
        ss += "\"";
        ss += v[ii];
        ss += "\" ";
    }
    ss += "\n";
    ::OutputDebugString( ss.
asChar() );
#endif
    for ( int iDataSet = 0; iDataSet < nDataSets; ++iDataSet )
    {                                  
        int iType = etcNull;
        int iBuf = 0;
        
        const char* bp = v[ iDataSet ].asChar();
        const char* ep = v[ iDataSet ].
length() + bp;
 
#ifdef _WIN32
        while ( bp < ep && *bp <= ' ' && *bp >= '\0') ++bp;
#else
        while ( bp < ep && *bp <= ' ') ++bp;
#endif
#ifdef _WIN32
        while ( bp < ep && ep[-1] <= ' ' && ep[-1] >= '\0' ) --ep;
#else
        while ( bp < ep && ep[-1] <= ' ' ) --ep;
#endif
        
        if ( bp == ep )
            iType = etcNull;
        
        else if ( (*bp >= '0' && *bp <= '9') ||
            *bp == '-' ||
            *bp == '+' ||
            *bp == '.' )
        {
            const char* cp = bp;
            int nValues = 0;
            while ( cp < ep &&
                nValues < 4 )
            {
                float x;
                int   nc = 0;
                int   nv = sscanf( cp, " %f%n", &x, &nc );
                if ( nv != 1 )
                    break;
                ++nValues;
                cp += nc;
            }
            if ( nValues > 0 )
            {
                s.
set( bp, (
int)(cp - bp) );      
                for ( ; nValues < 4; ++nValues )
                    s += " 0";
                iType = etcConstant;
            }
        }
        
        else
        {
            s.
set( bp, (
int)(ep - bp) );
            
            
            
            #define kDefaultUVSet "map1"
            {
                s = splitStrings[0];
                iBuf = findOrAppend( fDataSetNames, splitStrings[1]);
            }
            
            if ( 0 == stricmp( "normal", bp ) )
            {
                s = "normal";
                iType = etcNormal;
            }
            else if ( 0 == stricmp( "tangent", bp ) )
            {
                s = "tangent";
                if( splitStrings.
length() < 2)
 
                {
                    splitStrings[ 1] = kDefaultUVSet;
                    iBuf = findOrAppend( fDataSetNames, kDefaultUVSet);
                }
                s += ":" + splitStrings[1];
                iType = etcTangent;
                if( fNormalsPerVertex < 2)
                    fNormalsPerVertex = 2;
            }
            else if ( 0 == stricmp( "binormal", bp ) )
            {
                s = "binormal";
                if( splitStrings.
length() < 2)
 
                {
                    splitStrings[ 1] = kDefaultUVSet;
                    iBuf = findOrAppend( fDataSetNames, kDefaultUVSet);
                }
                s += ":" + splitStrings[1];
                iType = etcBinormal;
                fNormalsPerVertex = 3;
            }
            
            else
            {
                iType = etcDataSet;
                iBuf = findOrAppend( fDataSetNames, s );
            }
        }
        
        typeList[ iDataSet ] = iType;
        indexList[ iDataSet ] = iBuf;
        
        v[ iDataSet ] = s;
    }                                  
}                                      
cgfxShaderNode::getEmptyUVSets() const
{
    return saNull;
}                                      
cgfxShaderNode::getEmptyUVSetShapes() const
{
    return oaNull;
}                                      
void
cgfxShaderNode::setEffect(const cgfxRCPtr<cgfxEffect const>& pNewEffect)
{
    
    cgfxShaderNode::removeAssociation(this, fEffect);
    fEffect = pNewEffect;
    
    cgfxShaderNode::addAssociation(this, fEffect);
    updateTechniqueList();
    setTechnique( getTechnique() );
}
void
cgfxShaderNode::updateTechniqueList()
{
    
    
    
    
    
    
    
    
    fTechniqueList.clear();
    if (!fEffect.isNull() && fEffect->isValid())
    {
        const cgfxTechnique* technique = fEffect->getFirstTechnique();
        while (technique)
        {
            s += technique->getName();
            if (technique->isValid())
            {
                s += "\t";
                s += technique->getNumPasses();
            }
            else
            {
                s += "\t0";
            }
            fTechniqueList.append(s);
            technique = technique->getNext();
        }
    }
}                                      
 bool cgfxShaderNode::hasTransparency()
{
    
    
    return false;
}
unsigned int cgfxShaderNode::transparencyOptions()
{
    if (fCurrentTechnique && fCurrentTechnique->isValid() && fCurrentTechnique->hasBlending())
    {
        
        
        return ( kIsTransparent | kNoTransparencyFrontBackCull | kNoTransparencyPolygonSort );
    }
    return 0;
}
void
cgfxShaderNode::setTechnique( 
const MString& techn )
{
    
    if (fEffect.isNull() || !fEffect->isValid())
    {
        fTechnique = techn;
        return;
    }
    
        const cgfxTechnique* technique = fEffect->getTechnique(techn);
        if (technique) {
            if (technique->isValid())
            {
                fTechnique = techn;
                fCurrentTechnique = technique;
                
                setVertexAttributes(fCurrentTechnique->getVertexAttributes());
                
                
                fBoundDataCache.flush();
                ++fGeomReqDataVersionId;
                return;
            }
            else {
                s += typeName();
                s += " \"";
                s += name();
                s += "\" : unable to validate technique \"";
                s += "\"";
            }
        }
        else if (!shaderFxFileChanged()) {
            s += typeName();
            s += " \"";
            s += name();
            s += "\" : unable to find technique \"";
            s += "\"";
        }
    }
    
    if (fTechnique.length() != 0 && fTechnique != techn) {
        const cgfxTechnique* technique = fEffect->getTechnique(techn);
        if (technique) {
            if (technique->isValid())
            {
                fCurrentTechnique = technique;
                
                setVertexAttributes(fCurrentTechnique->getVertexAttributes());
                
                
                fBoundDataCache.flush();
                return;
            }
            else {
                s += typeName();
                s += " \"";
                s += name();
                s += "\" : unable to validate technique \"";
                s += "\"";
            }
        }
        else if (!shaderFxFileChanged()) {
            s += typeName();
            s += " \"";
            s += name();
            s += "\" : unable to find technique \"";
            s += "\"";
        }
    }
    
    const cgfxTechnique* technique = fEffect->getFirstTechnique();
    while (technique)
    {
        if (technique->isValid())
        {
            fTechnique = technique->getName();
            fCurrentTechnique = technique;
            
            setVertexAttributes(fCurrentTechnique->getVertexAttributes());
            
            
            fBoundDataCache.flush();
            
            ++fGeomReqDataVersionId;
            return;
        }
        technique = technique->getNext();
    }
    
    
    
    fTechnique = techn;
    s += typeName();
    s += " \"";
    s += name();
    s += "\" : unable to find a valid technique.";
}                                      
void
cgfxShaderNode::setProfile( 
const MString& profileName )
{
    const cgfxProfile* profile = cgfxProfile::getProfile(profileName);
    if (profile) {
        fProfileName = profileName;
        setProfile(profile);
    }
    else {
        fProfileName = "";
        setProfile(NULL);
        if (profileName.
length() > 0) {
 
            sMsg += "The profile \"";
            sMsg += profileName;
            sMsg += "\" is not a supported profile on your platform. Reverting to use the default profile.";
        }
    }
}
void
cgfxShaderNode::setProfile( const cgfxProfile* profile )
{
    if (fEffect.isNull() || !fEffect->isValid())
        return;
    
    fEffect->setProfile(profile);
    
    updateTechniqueList();
    
    
    setTechnique(fTechnique);
}
MStatus cgfxShaderNode::shouldSave ( 
const MPlug & plug, 
bool & ret )
 
{
    if (plug == sAttributeList)
    {
        ret = true;
    }
    else if (plug == sVertexAttributeList)
    {
        ret = true;
    }
}
void cgfxShaderNode::setTexturesByName(bool texturesByName, bool updateAttributes)
{
    if( updateAttributes && fTexturesByName != texturesByName)
    {
        
        
        
        
        const cgfxRCPtr<cgfxAttrDefList>& nodeList = attrDefList();
        cgfxAttrDefList::iterator nmIt;
        bool foundTextures = false;
        for (nmIt = nodeList->begin(); nmIt; ++nmIt)
        {
            cgfxAttrDef* adef = (*nmIt);
            if(adef->fType >= cgfxAttrDef::kAttrTypeFirstTexture && adef->fType <= cgfxAttrDef::kAttrTypeLastTexture)
            {
                MObject theMObject = thisMObject();
 
                adef->destroyAttribute( theMObject, &dgMod);
                foundTextures = true;
            }
        }
        
        
        
        fTexturesByName = texturesByName;
        
        
        if( foundTextures)
        {
            for (nmIt = nodeList->begin(); nmIt; ++nmIt)
            {
                cgfxAttrDef* adef = (*nmIt);
                if( adef->fType >= cgfxAttrDef::kAttrTypeFirstTexture && adef->fType <= cgfxAttrDef::kAttrTypeLastTexture)
                {
                    adef->createAttribute(thisMObject(), &dgMod, this);
                }
            }
            
            
            
            if( fTexturesByName)
            {
                for (nmIt = nodeList->begin(); nmIt; ++nmIt)
                {
                    cgfxAttrDef* adef = (*nmIt);
                    if( adef->fType >= cgfxAttrDef::kAttrTypeFirstTexture &&
                        adef->fType <= cgfxAttrDef::kAttrTypeLastTexture)
                    {
                        MObject theMObject = thisMObject();
 
                        adef->setTexture( theMObject, adef->fStringDef, &dgMod);
                    }
                }
            }
        }
    }
    else
    {
        fTexturesByName = texturesByName;
    }
}
cgfxShaderNode::getPluginVersion()
{
    sVer += CGFXSHADER_VERSION;
    sVer += " for Maya ";
    sVer += (int)(MAYA_API_VERSION / 100);
    sVer += ".";
    sVer += (int)(MAYA_API_VERSION % 100 / 10);
    sVer += " (";
    sVer += __DATE__;
    sVer += ")";
    return sVer;
}                                      
void
cgfxShaderNode::reportInternalError( const char* function, size_t errcode )
{
    try
    {
        if ( this &&
            fConstructed )
        {
            if ( ++fErrorCount > fErrorLimit )
                return;
            s += "\"";
            s += name();
            s += "\": ";
            s += typeName();
            es = s;
        }
    }
    catch ( ... )
    {}
    es += " internal error ";
    es += (int)errcode;
    es += " in ";
    es += function;
#ifdef KH_DEBUG
    ::OutputDebugString( es.
asChar() );
    ::OutputDebugString( "\n" );
#endif
}                                      
void
cgfxShaderNode::cgErrorCallBack()
{
    CGerror cgLastError = cgGetError();
    if(cgLastError)
    {
    }
}                                                                            
void
cgfxShaderNode::cgErrorHandler(CGcontext cgContext, CGerror cgError, void* userData)
{
}
void cgfxShaderNode::getNodesUsingEffect(const cgfxRCPtr<const cgfxEffect>& effect, NodeList &nodes)
{
    Effect2NodesMap::const_iterator it = sEffect2NodesMap.find( effect.operator->() );
    if(it != sEffect2NodesMap.end())
    {
        const NodeList &nodeList = it->second;
        nodes.insert(nodeList.begin(), nodeList.end());
    }
}
void cgfxShaderNode::addAssociation(cgfxShaderNode* node, const cgfxRCPtr<const cgfxEffect>& effect)
{
    if(effect.isNull() == false)
    {
        NodeList &nodes = sEffect2NodesMap[ effect.operator->() ];
        nodes.insert(node);
    }
}
void cgfxShaderNode::removeAssociation(cgfxShaderNode* node, const cgfxRCPtr<const cgfxEffect>& effect)
{
    if(effect.isNull() == false)
    {
        Effect2NodesMap::iterator it = sEffect2NodesMap.find( effect.operator->() );
        if(it != sEffect2NodesMap.end())
        {
            NodeList &nodes = it->second;
            nodes.erase(node);
            if(nodes.empty())
                sEffect2NodesMap.erase(it);
        }
    }
}
void cgfxShaderNode::attributeAddedOrRemovedCB(
    void* clientData)
{
    
    
    
    
    
    
    
    
    
    
    
    
        clientData &&
    {
        cgfxShaderNode* shaderNode = (cgfxShaderNode*)clientData;
        if (!shaderNode->effect().isNull())
        {
            
            shaderNode->setShaderFxFileChanged(true);
            shaderNode->setEffect(cgfxRCPtr<const cgfxEffect>());
        }
    }
}
const MString cgfxShaderOverride::drawDbClassification(
"drawdb/shader/surface/cgfxShader");
 
const MString cgfxShaderOverride::drawRegistrantId(
"cgfxShaderRegistrantId");
 
cgfxShaderNode* cgfxShaderOverride::sActiveShaderNode = NULL;
cgfxShaderNode* cgfxShaderOverride::sLastDrawShaderNode = NULL;
{
    return new cgfxShaderOverride(obj);
}
cgfxShaderOverride::cgfxShaderOverride(
const MObject& obj)
    : MPxShaderOverride(obj)
    , fShaderNode(NULL)
    , fGeomReqDataVersionId(0)
    , fNeedPassSetterInit(false)
    , fOldBlendState(NULL)
    , fOldDepthStencilState(NULL)
    , fOldRasterizerState(NULL)
{
}
cgfxShaderOverride::~cgfxShaderOverride()
{
    fShaderNode = NULL;
}
{
    TRACE_API_CALLS("cgfxShaderOverride::initialize");
    
    
    
    
    glStateCache::instance().reset();
    
    if ( glStateCache::sMaxTextureUnits <= 0 )
    {
        
        
        
#ifdef _WIN32
#define RESOLVE_GL_EXTENSION( fn, ext) wglGetProcAddress( #fn #ext)
#elif defined LINUX
#define RESOLVE_GL_EXTENSION( fn, ext) &fn ## ext
#else
#define RESOLVE_GL_EXTENSION( fn, ext) &fn
#endif
        glStateCache::glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREARBPROC) RESOLVE_GL_EXTENSION( glClientActiveTexture, ARB);
        glStateCache::glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERARBPROC) RESOLVE_GL_EXTENSION( glVertexAttribPointer, ARB);
        glStateCache::glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) RESOLVE_GL_EXTENSION( glEnableVertexAttribArray, ARB);
        glStateCache::glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) RESOLVE_GL_EXTENSION( glDisableVertexAttribArray, ARB);
        glStateCache::glVertexAttrib4f = (PFNGLVERTEXATTRIB4FARBPROC) RESOLVE_GL_EXTENSION( glVertexAttrib4f, ARB);
        glStateCache::glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTEREXTPROC) RESOLVE_GL_EXTENSION( glSecondaryColorPointer, EXT);
        glStateCache::glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FEXTPROC) RESOLVE_GL_EXTENSION( glSecondaryColor3f, EXT);
        glStateCache::glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) RESOLVE_GL_EXTENSION( glMultiTexCoord4f, ARB);
        
        
        
        
        
        
        
        
        GLint tval;
        glGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &tval );
        GLint mic = 0;
        glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &mic );
        if (mic < tval)
            tval = mic;
        
        
        glStateCache::sMaxTextureUnits = tval;
        if (!glStateCache::glClientActiveTexture || glStateCache::sMaxTextureUnits < 1)
            glStateCache::sMaxTextureUnits = 1;
        else if (glStateCache::sMaxTextureUnits > CGFXSHADERNODE_GL_TEXTURE_MAX)
            glStateCache::sMaxTextureUnits = CGFXSHADERNODE_GL_TEXTURE_MAX;
    }
    
    
    {
        
    }
    else
        fShaderNode = NULL;
    bool useCustomPrimitiveGenerator = false;
    if (fShaderNode)
    {
        static bool enableCustomPrimitiveGenerator = (getenv("MAYA_USE_CUSTOMPRIMITIVEGENERATOR") != NULL);
        fShaderNode->createEffect();
        const cgfxTechnique* technique = fShaderNode->fCurrentTechnique;
        if (technique && technique->isValid())
        {
            
            
            
            
            
            
            
            cgfxRCPtr<cgfxVertexAttribute> pVertexAttribute = fShaderNode->fVertexAttributes;
            while(pVertexAttribute.isNull() == false)
            {
                
                
                sourceName = pVertexAttribute->fSourceName;
                if ( sourceName  == "position")
                {
                    
                    sourceName = "";
                }
                else if( sourceName  == "normal")
                {
                    
                    sourceName = "";
                }
                else
                {
                    
                    MString set = pVertexAttribute->fSourceName;
 
                    int colon = set.
index( 
':');
 
                    if( colon >= 0)
                    {
                        
                    }
                }
                int dimension = 1;
                unsigned int dimensionIndex = UINT_MAX;
                if(pVertexAttribute->fType.indexW( 
MString(
"float") ) == 0)
 
                {
                    dimensionIndex = 5;
                }
                else if(pVertexAttribute->fType.indexW( 
MString(
"half") ) == 0)
 
                {
                    dimensionIndex = 4;
                }
                else if(pVertexAttribute->fType.indexW( 
MString(
"int") ) == 0)
 
                {
                    dimensionIndex = 3;
                }
                if(dimensionIndex < pVertexAttribute->fType.length())
                {
                    char dim = pVertexAttribute->fType.asChar()[dimensionIndex];
                    dimension = dim - '0';
                }
                cgfxVertexAttribute::SourceType sourceType = pVertexAttribute->fSourceType;
                if(enableCustomPrimitiveGenerator &&
                    (pVertexAttribute->fSourceType == cgfxVertexAttribute::kBlindData || pVertexAttribute->fSourceType == cgfxVertexAttribute::kPosition) &&
                    pVertexAttribute->fSemantic == "ATTR7") {
                    useCustomPrimitiveGenerator = true;
                    sourceType = cgfxVertexAttribute::kPosition;
                    pVertexAttribute->fSourceName = "position";
                    semanticName = "customPositionStream";
                }
                else if(enableCustomPrimitiveGenerator &&
                    (pVertexAttribute->fSourceType == cgfxVertexAttribute::kBlindData || pVertexAttribute->fSourceType == cgfxVertexAttribute::kNormal) &&
                    pVertexAttribute->fSemantic == "ATTR8") {
                    useCustomPrimitiveGenerator = true;
                    sourceType = cgfxVertexAttribute::kNormal;
                    pVertexAttribute->fSourceName = "normal";
                    semanticName = "customNormalStream";
                }
                else if(pVertexAttribute->fSourceType == cgfxVertexAttribute::kBlindData) {
                    
                    
                    sourceType = cgfxVertexAttribute::kUV;
                    semanticName = pVertexAttribute->fSourceName;
                }
                switch(sourceType)
                {
                    case cgfxVertexAttribute::kPosition:
                        {
                            
                                sourceName,
                                dataType,
                                dimension);
                            desc.setSemanticName(semanticName);
                            geomReqStatus = addGeometryRequirement(desc);
                        }
                        break;
                    case cgfxVertexAttribute::kNormal:
                        {
                            
                                sourceName,
                                dataType,
                                dimension);
                            desc.setSemanticName(semanticName);
                            geomReqStatus = addGeometryRequirement(desc);
                        }
                        break;
                    case cgfxVertexAttribute::kUV:
                        {
                            
                            if (semanticName.
length() == 0)
 
                            {
                                
                                
                                dimension = 2;
                            }
                                sourceName,
                                dataType,
                                dimension);
                            desc.setSemanticName(semanticName);
                            geomReqStatus = addGeometryRequirement(desc);
                        }
                        break;
                    case cgfxVertexAttribute::kTangent:
                        {
                            
                                sourceName,
                                dataType,
                                dimension);
                            desc.setSemanticName(semanticName);
                            geomReqStatus = addGeometryRequirement(desc);
                        }
                        break;
                    case cgfxVertexAttribute::kBinormal:
                        {
                            
                                sourceName,
                                dataType,
                                dimension);
                            desc.setSemanticName(semanticName);
                            geomReqStatus = addGeometryRequirement(desc);
                        }
                        break;
                    case cgfxVertexAttribute::kColor:
                        {
                            
                                sourceName,
                                dataType,
                                dimension);
                            desc.setSemanticName(semanticName);
                            geomReqStatus = addGeometryRequirement(desc);
                        }
                        break;
                    default:;
                }
                    MString s = 
"cgfxShader : Can't find the source named \"";
 
                    s += pVertexAttribute->fSourceName;;
                    s += "\" for vertex attribute \"";
                    s += pVertexAttribute->fName;;
                    s +="\".";
                }
                pVertexAttribute = pVertexAttribute->fNext;
            }
        }
    }
    fGeomReqDataVersionId = fShaderNode->fGeomReqDataVersionId;
    fNeedPassSetterInit = true;
    
    
    
    
    
    
    if (useCustomPrimitiveGenerator)
    {
        MString customPrimitiveName(
"customPrimitiveTest");
 
        addIndexingRequirement(indexingRequirement);
    }
    
    
    
    
    
        (
MString(
"Autodesk Maya cgfxShaderOverride, shader file = ") +
         fShaderNode->shaderFxFile() +
         fShaderNode->getTechnique() +
         fShaderNode->getProfile());
    return result;
}
void cgfxShaderOverride::updateDG(
MObject object)
 
{
    TRACE_API_CALLS("cgfxShaderOverride::updateDG");
    {
        
    }
    else
        fShaderNode = NULL;
}
void cgfxShaderOverride::updateDevice()
{
}
void cgfxShaderOverride::endUpdate()
{
}
{
    TRACE_API_CALLS("cgfxShaderOverride::activateKey");
    if (!fShaderNode)
    {
        
        return;
    }
    
    
    
    
    sActiveShaderNode = fShaderNode;
    sLastDrawShaderNode = NULL;
    const cgfxTechnique* technique = sActiveShaderNode->fCurrentTechnique;
    if(technique && technique->isValid())
    {
        
        cgfxPassStateSetter::registerCgStateCallBacks(
            cgfxPassStateSetter::kVP20Viewport);
        
        {
            if (fNeedPassSetterInit) {
                delete [] sActiveShaderNode->fPassStateSetters;
                sActiveShaderNode->fPassStateSetters =
                    new cgfxPassStateSetter[technique->getNumPasses()];
                const cgfxPass* pass = technique->getFirstPass();
                for (int i=0; pass; ++i, pass = pass->getNext()) {
                    sActiveShaderNode->fPassStateSetters[i].init(
                        stateMgr, pass->getCgPass());
                }
                fNeedPassSetterInit = false;
            }
        }
        
        glPushClientAttrib ( GL_CLIENT_ALL_ATTRIB_BITS );
        glStateCache::instance().reset();   
        if (technique->getNumPasses() == 1) {
            
            
            sActiveShaderNode->fPassStateSetters[0].setPassState(stateMgr);
        }
    }
}
bool cgfxShaderOverride::draw(
{
    TRACE_API_CALLS("cgfxShaderOverride::draw");
    if (!fShaderNode || !sActiveShaderNode)
    {
        
        return false;
    }
    
    static const bool debugPassInformation = false;
    if (debugPassInformation)
    {
        printf(
"CgFx shader drawing in pass[%s], semantic[", passId.
asChar());
        for (
unsigned int i=0; i<passSem.
length(); i++)
 
            printf(" %s", passSem[i].asChar());
        printf( "]\n");
    }
    if ( 0 == gGLFT )
    bool result = true;
    const cgfxTechnique* technique = sActiveShaderNode->fCurrentTechnique;
    if (technique && technique->isValid())
    {
        bool needFullCgSetPassState = false;
        
        if (sLastDrawShaderNode != fShaderNode) {
            try
            {
                needFullCgSetPassState = bindAttrValues();
                checkGlErrors("cgfxShaderOverride::bindAttrValues");
            }
            catch ( cgfxShaderCommon::InternalError* e )
            {
                if (fShaderNode)
                    fShaderNode->reportInternalError( __FILE__, (size_t)e );
            }
            catch ( ... )
            {
                if (fShaderNode)
                    fShaderNode->reportInternalError( __FILE__, __LINE__ );
            }
        }
        
        bindViewAttrValues(context);
        const int numRenderItems = renderItemList.
length();
 
        for (int renderItemIdx=0; renderItemIdx<numRenderItems; renderItemIdx++)
        {
            if (!renderItem) continue;
            if (!geometry) continue;
            bool boundData = true;
            sourceStreamInfo *pBindSource = new sourceStreamInfo[bufferCount];
            for (int i=0; i<bufferCount && boundData; i++)
            {
                if (!buffer)
                {
                    boundData = false;
                    continue;
                }
                GLuint * dataBufferId = NULL;
                if (!dataHandle)
                {
                    boundData = false;
                    continue;
                }
                dataBufferId = (GLuint *)(dataHandle);
                {
                        {
                            pBindSource[i].fSourceType = cgfxVertexAttribute::kPosition;
                            pBindSource[i].fSourceName = "position";
                        }
                        break;
                        {
                            pBindSource[i].fSourceType = cgfxVertexAttribute::kNormal;
                            pBindSource[i].fSourceName = "normal";
                        }
                        break;
                        {
                            {
                                pBindSource[i].fSourceName = 
"uv:" + desc.
name();
                                pBindSource[i].fSourceType = cgfxVertexAttribute::kUV;
                            }
                            else
                            {
                                
                                pBindSource[i].fSourceType = cgfxVertexAttribute::kBlindData;
                            }
                            
                            
                        }
                        break;
                        {
                            pBindSource[i].fSourceType =  cgfxVertexAttribute::kColor;
                            pBindSource[i].fSourceName = 
"color:" + desc.
name();
                        }
                        break;
                        {
                            pBindSource[i].fSourceType = cgfxVertexAttribute::kTangent;
                            pBindSource[i].fSourceName = 
"tangent:" + desc.
name();
                        }
                        break;
                        {
                            pBindSource[i].fSourceType = cgfxVertexAttribute::kBinormal;
                            pBindSource[i].fSourceName = 
"binormal:" + desc.
name();
                        }
                        break;
                    default:
                        {
                            pBindSource[i].fSourceType = cgfxVertexAttribute::kBlindData;
                        }
                        break;
                }
                pBindSource[i].fDimension = desc.
dimension();
                pBindSource[i].fOffset = desc.
offset();
                pBindSource[i].fStride = desc.
stride();
                pBindSource[i].fDataBufferId = *dataBufferId;
            }
            
            
            {
                
                
                unsigned int indexBufferCount = 0;
                GLuint *indexBufferId = NULL;
                if (indexHandle)
                {
                    indexBufferId = (GLuint *)(indexHandle);
                    indexBufferCount = buffer->
size();
                    
                }
                GLenum indexPrimTypeGL = GL_TRIANGLES;
                switch (indexPrimType) {
                        indexPrimTypeGL = GL_POINTS; break;
                        indexPrimTypeGL = GL_LINES; break;
                        indexPrimTypeGL = GL_LINE_STRIP; break;
                        indexPrimTypeGL = GL_TRIANGLES; break;
                        indexPrimTypeGL = GL_TRIANGLE_STRIP; break;
                    default:
                        result = false;
                        break;
                };
                GLenum indexType =
                if(!result)
                    break;
                if (indexBufferId  && (*indexBufferId > 0))
                {
                    
                    const cgfxPass* pass = technique->getFirstPass();
                    if (technique->getNumPasses() == 1) {
                        
                        
                        if (sLastDrawShaderNode == NULL) {
                            if (sActiveShaderNode->fPassStateSetters[0].isPushPopAttribsRequired()) {
                                gGLFT->
glPushAttrib(GL_ALL_ATTRIB_BITS);
                            }
                            pass->setCgState();
                        }
                        else {
                            if (needFullCgSetPassState) {
                                pass->setCgState();
                            }
                            else {
                                pass->updateCgParameters();
                            }
                        }
                        pass->bind(pBindSource, bufferCount);
                        gGLFT->
glBindBufferARB(MGL_ELEMENT_ARRAY_BUFFER_ARB, *indexBufferId);
                        
                        gGLFT->
glDrawElements(indexPrimTypeGL, indexBufferCount, indexType, GLOBJECT_BUFFER_OFFSET(0));
                    }
                    else {
                        for (int i=0; pass; ++i, pass = pass->getNext()) {
                            sActiveShaderNode->fPassStateSetters[i].setPassState(stateMgr);
                            
                            if (sActiveShaderNode->fPassStateSetters[i].isPushPopAttribsRequired()) {
                                gGLFT->glPushAttrib(GL_ALL_ATTRIB_BITS);
                            }
                            pass->setCgState();
                            pass->bind(pBindSource, bufferCount);
                            gGLFT->glBindBufferARB(MGL_ELEMENT_ARRAY_BUFFER_ARB, *indexBufferId);
                            
                            gGLFT->glDrawElements(indexPrimTypeGL, indexBufferCount, indexType, GLOBJECT_BUFFER_OFFSET(0));
                            glStateCache::instance().flushState();
                            pass->resetCgState();
                            if (sActiveShaderNode->fPassStateSetters[i].isPushPopAttribsRequired()) {
                            }
                        }
                    }
                }
            }
            delete[] pBindSource;
        }
        checkGlErrors("cgfxShaderOverride::draw");
        sLastDrawShaderNode = fShaderNode;
    }
    else 
    {
        
        
        result = false;
    }
    return result;
}
{
    TRACE_API_CALLS("cgfxShaderOverride::terminateKey");
    if (!fShaderNode || !sActiveShaderNode)
    {
        
        return;
    }
    const cgfxTechnique* technique = sActiveShaderNode->fCurrentTechnique;
    if (technique && technique->isValid())
    {
        const cgfxPass* pass = technique->getFirstPass();
        if (technique->getNumPasses() == 1) {
            
            
            glStateCache::instance().flushState();
            pass->resetCgState();
            if (sActiveShaderNode->fPassStateSetters[0].isPushPopAttribsRequired()) {
                gGLFT->glPopAttrib();
            }
            
        }
        glPopClientAttrib();
        fOldBlendState = 0;
        fOldDepthStencilState = 0;
        fOldRasterizerState = 0;
    }
    sActiveShaderNode = NULL;
    sLastDrawShaderNode = NULL;
}
{
}
bool cgfxShaderOverride::isTransparent()
{
    if(fShaderNode && fShaderNode->fCurrentTechnique)
        return fShaderNode->fCurrentTechnique->hasBlending();
    return false;
}
bool cgfxShaderOverride::overridesDrawState()
{
    return true;
}
bool cgfxShaderOverride::bindAttrValues() const
{
    if (!fShaderNode || !sActiveShaderNode ||
        sActiveShaderNode->fEffect.isNull() ||
        !sActiveShaderNode->fEffect->isValid() ||
        !sActiveShaderNode->fTechnique.length())
        return false;
    MObject  oNode = fShaderNode->thisMObject();
 
    bool needFullCgSetPassState = false;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    for (cgfxAttrDefList::iterator it(fShaderNode->fAttrDefList),
             activeIt(sActiveShaderNode->fAttrDefList);
         it; ++it, ++activeIt )
    {                                  
        cgfxAttrDef* aDef = *it;
        cgfxAttrDef* activeDef = *activeIt;
        if (aDef->fName != activeDef->fName) {
          fShaderNode->reportInternalError( __FILE__, __LINE__ );
        }
        try
        {
            switch (aDef->fType)
            {
            case cgfxAttrDef::kAttrTypeBool:
                {
                    bool tmp;
                    aDef->getValue(oNode, tmp);
                    cgSetParameter1i(activeDef->fParameterHandle, tmp);
                    break;
                }
            case cgfxAttrDef::kAttrTypeInt:
                {
                    int tmp;
                    aDef->getValue(oNode, tmp);
                    cgSetParameter1i(activeDef->fParameterHandle, tmp);
                    break;
                }
            case cgfxAttrDef::kAttrTypeFloat:
                {
                    float tmp;
                    aDef->getValue(oNode, tmp);
                    cgSetParameter1f(activeDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeString:
                {
                    aDef->getValue(oNode, tmp);
                    cgSetStringParameterValue(activeDef->fParameterHandle, tmp.
asChar());
                    break;
                }
            case cgfxAttrDef::kAttrTypeVector2:
                {
                    float tmp[2];
                    aDef->getValue(oNode, tmp[0], tmp[1]);
                    cgSetParameter2fv(activeDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeVector3:
            case cgfxAttrDef::kAttrTypeColor3:
                {
                    float tmp[3];
                    aDef->getValue(oNode, tmp[0], tmp[1], tmp[2]);
                    cgSetParameter3fv(activeDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeVector4:
            case cgfxAttrDef::kAttrTypeColor4:
                {
                    float tmp[4];
                    aDef->getValue(oNode, tmp[0], tmp[1], tmp[2], tmp[3]);
                    cgSetParameter4fv(activeDef->fParameterHandle, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeWorldDir:
            case cgfxAttrDef::kAttrTypeWorldPos:
                {
                    
                    
                    float tmp[4];
                    if (aDef->fSize == 3)
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2]);
                        tmp[3] = 1.0;
                    }
                    else
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2], tmp[3]);
                    }
                    cgSetParameterValuefr(activeDef->fParameterHandle, aDef->fSize, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeMatrix:
                {
                    float tmp2[4][4];
                    aDef->getValue(oNode, tmp);
                    if (aDef->fInvertMatrix)
                    {
                    }
                    if (!aDef->fTransposeMatrix)
                    {
                    }
                    cgSetMatrixParameterfr(activeDef->fParameterHandle, &tmp2[0][0]);
                    break;
                }
            case cgfxAttrDef::kAttrTypeColor1DTexture:
            case cgfxAttrDef::kAttrTypeColor2DTexture:
            case cgfxAttrDef::kAttrTypeColor3DTexture:
            case cgfxAttrDef::kAttrTypeColor2DRectTexture:
            case cgfxAttrDef::kAttrTypeNormalTexture:
            case cgfxAttrDef::kAttrTypeBumpTexture:
            case cgfxAttrDef::kAttrTypeCubeTexture:
            case cgfxAttrDef::kAttrTypeEnvTexture:
            case cgfxAttrDef::kAttrTypeNormalizationTexture:
                {
                    if( fShaderNode->fTexturesByName)
                    {
                        aDef->getValue(oNode, texFileName);
                    }
                    else
                    {
                        
                        
                        aDef->getSource(oNode, srcPlug);
                        {
                            MPlug filenamePlug = dgFn.findPlug( 
"fileTextureName", &rc);
 
                            {
                                textureNode = filenamePlug.
node(&rc);
                            }
                            
                            
                            
                            
                            
                            {
                                
                                
                                
                                
                                aDef->releaseTexture();
                                    textureNode, textureChangedCallback, aDef);
                            }
                        }
                    }
                    if (aDef->fTexture.isNull() || texFileName != aDef->fStringDef)
                    {
                        aDef->fStringDef = texFileName;
                        aDef->fTexture = cgfxTextureCache::instance().getTexture(
                            texFileName, textureNode, fShaderNode->fShaderFxFile,
                            aDef->fName, aDef->fType);
                        cgGLSetupSampler(activeDef->fParameterHandle, aDef->fTexture->getTextureId());
                        if (!aDef->fTexture->isValid() && texFileName.
length() > 0) {
 
                            sMsg += fnNode.name();
                            sMsg += " : failed to load texture \"";
                            sMsg += texFileName;
                            sMsg += "\".";
                        }
                        
                        
                        
                        
                        needFullCgSetPassState = true;
                    }
                    else if (sLastDrawShaderNode == NULL) {
                        
                        
                        
                        cgGLSetTextureParameter(activeDef->fParameterHandle, aDef->fTexture->getTextureId());
                    }
                    else {
                        GLuint textureId = aDef->fTexture->getTextureId();
                        
                        
                        
                        
                        
                        
                        cgGLSetTextureParameter(activeDef->fParameterHandle, textureId);
                        GLenum texEnum = cgGLGetTextureEnum(activeDef->fParameterHandle);
                        gGLFT->
glActiveTexture(texEnum);
                        switch (aDef->fType)
                        {
                        case cgfxAttrDef::kAttrTypeColor1DTexture:
                            gGLFT->
glBindTexture(GL_TEXTURE_1D, textureId);
                            break;
                        case cgfxAttrDef::kAttrTypeColor2DTexture:
                        case cgfxAttrDef::kAttrTypeNormalTexture:
                        case cgfxAttrDef::kAttrTypeBumpTexture:
#if !defined(WIN32) && !defined(LINUX)
                        case cgfxAttrDef::kAttrTypeColor2DRectTexture:
#endif
                            gGLFT->glBindTexture(GL_TEXTURE_2D, textureId);
                            break;
                        case cgfxAttrDef::kAttrTypeEnvTexture:
                        case cgfxAttrDef::kAttrTypeCubeTexture:
                        case cgfxAttrDef::kAttrTypeNormalizationTexture:
                            {
                                gGLFT->glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, textureId);
                                break;
                            }
                        case cgfxAttrDef::kAttrTypeColor3DTexture:
                            gGLFT->glBindTexture(GL_TEXTURE_3D, textureId);
#if defined(WIN32) || defined(LINUX)
                            
                            
                        case cgfxAttrDef::kAttrTypeColor2DRectTexture:
                            gGLFT->glBindTexture(GL_TEXTURE_RECTANGLE_NV, textureId);
                            break;
#endif
                        default:
                            assert(false);
                        }
                    }
                    checkGlErrors("After loading texture");
                    break;
                }
#ifdef _WIN32
            case cgfxAttrDef::kAttrTypeTime:
                {
                    int ival = timeGetTime() & 0xffffff;
                    float val = (float)ival * 0.001f;
                    cgSetParameter1f(activeDef->fParameterHandle, val);
                    break;
                }
#endif
            case cgfxAttrDef::kAttrTypeOther:
            case cgfxAttrDef::kAttrTypeUnknown:
                break;
            case cgfxAttrDef::kAttrTypeObjectDir:
            case cgfxAttrDef::kAttrTypeViewDir:
            case cgfxAttrDef::kAttrTypeProjectionDir:
            case cgfxAttrDef::kAttrTypeScreenDir:
            case cgfxAttrDef::kAttrTypeObjectPos:
            case cgfxAttrDef::kAttrTypeViewPos:
            case cgfxAttrDef::kAttrTypeProjectionPos:
            case cgfxAttrDef::kAttrTypeScreenPos:
            case cgfxAttrDef::kAttrTypeWorldMatrix:
            case cgfxAttrDef::kAttrTypeViewMatrix:
            case cgfxAttrDef::kAttrTypeProjectionMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                
                break;
            default:
                M_CHECK( false );
            }                          
        }
        catch ( cgfxShaderCommon::InternalError* e )
        {
            if ( ++fShaderNode->fErrorCount <= fShaderNode->fErrorLimit )
            {
                size_t ee = (size_t)e;
                MString sMsg = 
"cgfxShader warning ";
 
                sMsg += (int)ee;
                sMsg += ": ";
                sMsg += fnNode.name();
                sMsg += " internal error while setting parameter \"";
                sMsg += aDef->fName;
                sMsg += "\" of effect \"";
                sMsg += fShaderNode->fShaderFxFile;
                sMsg += "\" for shape ";
                sMsg += fShaderNode->currentPath().partialPathName();
            }
        }
    }                                  
    return needFullCgSetPassState;
}
{
    if (!fShaderNode || !sActiveShaderNode ||
        sActiveShaderNode->fEffect.isNull() ||
        !sActiveShaderNode->fEffect->isValid() ||
        !sActiveShaderNode->fTechnique.length())
        return;
    MObject  oNode = fShaderNode->thisMObject();
 
    MMatrix wMatrix, vMatrix, pMatrix, sMatrix;
 
    MMatrix wvMatrix, wvpMatrix, wvpsMatrix;
 
    {
        int vpt[4];
        float depth[2];
        
        
        double x0, y0, z0, w, h, d;
        x0 = (double)vpt[0];
        y0 = (double)vpt[1];
        z0 = depth[0];
        w  = (double)vpt[2];
        h  = (double)vpt[3];
        d  = depth[1] - z0;
        
        
        double* s = &sMatrix.
matrix[0][0];
 
        s[ 0] = w/2;    s[ 1] = 0.0;    s[ 2] = 0.0;    s[ 3] = 0.0;
        s[ 4] = 0.0;    s[ 5] = h/2;    s[ 6] = 0.0;    s[ 7] = 0.0;
        s[ 8] = 0.0;    s[ 9] = 0.0;    s[10] = d/2;    s[11] = 0.0;
        s[12] = x0+w/2; s[13] = y0+h/2; s[14] = z0+d/2; s[15] = 1.0;
        vpsMatrix = vpMatrix * sMatrix;
        wvpsMatrix = wvpMatrix * sMatrix;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    for (cgfxAttrDefList::iterator it(fShaderNode->fAttrDefList),
             activeIt(sActiveShaderNode->fAttrDefList);
         it; ++it, ++activeIt )
    {                                  
        cgfxAttrDef* aDef = *it;
        cgfxAttrDef* activeDef = *activeIt;
        if (aDef->fName != activeDef->fName) {
          fShaderNode->reportInternalError( __FILE__, __LINE__ );
        }
        try
        {
            switch (aDef->fType)
            {
            case cgfxAttrDef::kAttrTypeObjectDir:
            case cgfxAttrDef::kAttrTypeViewDir:
            case cgfxAttrDef::kAttrTypeProjectionDir:
            case cgfxAttrDef::kAttrTypeScreenDir:
            case cgfxAttrDef::kAttrTypeObjectPos:
            case cgfxAttrDef::kAttrTypeViewPos:
            case cgfxAttrDef::kAttrTypeProjectionPos:
            case cgfxAttrDef::kAttrTypeScreenPos:
                {
                    float tmp[4];
                    if (aDef->fSize == 3)
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2]);
                        tmp[3] = 1.0;
                    }
                    else
                    {
                        aDef->getValue(oNode, tmp[0], tmp[1], tmp[2], tmp[3]);
                    }
                    int space = aDef->fType - cgfxAttrDef::kAttrTypeFirstPos;
                    if (space < 0)
                    {
                        space = aDef->fType - cgfxAttrDef::kAttrTypeFirstDir;
                    }
                    switch (space)
                    {
                    case 0: mat = wMatrix.
inverse();    
break;
 
                    case 1:          break;
                    case 2: mat = vMatrix;          break;
                    case 3: mat = vpMatrix;     break;
                    case 4: mat = vpsMatrix;        break;
                    }
                    
                    
                    
                    
                    int base = cgfxAttrDef::kAttrTypeFirstPos;
                    if (aDef->fType <= cgfxAttrDef::kAttrTypeLastDir)
                        base = cgfxAttrDef::kAttrTypeFirstDir;
                    if (base == cgfxAttrDef::kAttrTypeFirstPos)
                    {
                        MPoint point(tmp[0], tmp[1], tmp[2], tmp[3]);
 
                        point *= mat;
                        tmp[0] = (float)point.x;
                        tmp[1] = (float)point.y;
                        tmp[2] = (float)point.z;
                        tmp[3] = (float)point.w;
                    }
                    else
                    {
                        MVector vec(tmp[0], tmp[1], tmp[2]);
 
                        vec *= mat;
                        tmp[0] = (float)vec.x;
                        tmp[1] = (float)vec.y;
                        tmp[2] = (float)vec.z;
                        tmp[3] = 1.F;
                    }
                    cgSetParameterValuefc(activeDef->fParameterHandle, aDef->fSize, tmp);
                    aDef->setUnitsToInternal(aDef->fParameterHandle);
                    break;
                }
            case cgfxAttrDef::kAttrTypeWorldMatrix:
            case cgfxAttrDef::kAttrTypeViewMatrix:
            case cgfxAttrDef::kAttrTypeProjectionMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewMatrix:
            case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                {
                    switch (aDef->fType)
                    {
                    case cgfxAttrDef::kAttrTypeWorldMatrix:
                        break;
                    case cgfxAttrDef::kAttrTypeViewMatrix:
                        break;
                    case cgfxAttrDef::kAttrTypeProjectionMatrix:
                        break;
                    case cgfxAttrDef::kAttrTypeWorldViewMatrix:
                        break;
                    case cgfxAttrDef::kAttrTypeWorldViewProjectionMatrix:
                        break;
                    default:
                        break;
                    }
                    double tmp[4][4];
                    cgSetMatrixParameterdr(activeDef->fParameterHandle, &tmp[0][0]);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogEnabled:
                {
                    cgSetParameter1i(activeDef->fParameterHandle, fogEnabled);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogMode:
                {
                    unsigned int fogMode = hwFogParams.
HwFogMode;
 
                    cgSetParameter1i(activeDef->fParameterHandle, fogMode);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogStart:
                {
                    cgSetParameter1f(activeDef->fParameterHandle, fogStart);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogEnd:
                {
                    cgSetParameter1f(activeDef->fParameterHandle, fogEnd);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogDensity:
                {
                    cgSetParameter1f(activeDef->fParameterHandle, fogDensity);
                    break;
                }
            case cgfxAttrDef::kAttrTypeHardwareFogColor:
                {
                    cgSetParameter4fv(activeDef->fParameterHandle, &hwFogParams.
HwFogColor[0]);
                    break;
                }
                default:
                    break;
            }                          
        }
        catch ( cgfxShaderCommon::InternalError* e )
        {
            if ( ++fShaderNode->fErrorCount <= fShaderNode->fErrorLimit )
            {
                size_t ee = (size_t)e;
                MString sMsg = 
"cgfxShader warning ";
 
                sMsg += (int)ee;
                sMsg += ": ";
                sMsg += fnNode.name();
                sMsg += " internal error while setting parameter \"";
                sMsg += aDef->fName;
                sMsg += "\" of effect \"";
                sMsg += fShaderNode->fShaderFxFile;
                sMsg += "\" for shape ";
                
            }
        }
    }                                  
}