#ifdef WIN32
#pragma warning( disable : 4786 )       // Disable stupid STL warnings.
#endif
#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MString.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnStringData.h>
#include <maya/MGlobal.h>
#include <maya/MPoint.h>
#include <maya/MMatrix.h>
#include <maya/MVector.h>
#include <maya/MEulerRotation.h>
#include <maya/MDagPath.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MSceneMessage.h>
#include <maya/MGL.h>
#include "hwUnlitShader.h"
#include "ShadingConnection.h"
MTypeId  hwUnlitShader::id( 0x00105440 );
 
MObject  hwUnlitShader::transparency;
 
MObject  hwUnlitShader::transparencyR;
 
MObject  hwUnlitShader::transparencyG;
 
MObject  hwUnlitShader::transparencyB;
 
void hwUnlitShader::postConstructor( )
{
    setMPSafe(false);
}
void hwUnlitShader::printGlError( const char *call )
{
    GLenum error;
    while( (error = glGetError()) != GL_NO_ERROR ) {
        assert(0);
        cerr << call << ":" << error << " is " << (const char *)gluErrorString( error ) << "\n";
    }
}
hwUnlitShader::hwUnlitShader()
{
    m_pTextureCache = MTextureCache::instance();
    attachSceneCallbacks();
}
hwUnlitShader::~hwUnlitShader()
{
    detachSceneCallbacks();
}
void hwUnlitShader::releaseEverything()
{
    
    m_pTextureCache->release();
    if(!MTextureCache::getReferenceCount())
    {
        m_pTextureCache = 0;
    }
}
void hwUnlitShader::attachSceneCallbacks()
{
                                                          releaseCallback, this);
}
void hwUnlitShader::releaseCallback(void* clientData)
{
    hwUnlitShader *pThis = (hwUnlitShader*) clientData;
    pThis->releaseEverything();
}
void hwUnlitShader::detachSceneCallbacks()
{
    if (fBeforeNewCB)
    if (fBeforeOpenCB)
    if (fBeforeRemoveReferenceCB)
    if (fMayaExitingCB)
    fBeforeNewCB = 0;
    fBeforeOpenCB = 0;
    fBeforeRemoveReferenceCB = 0;
    fMayaExitingCB = 0;
}
void * hwUnlitShader::creator()
{
    return new hwUnlitShader();
}
{ 
    
    const MString UserClassify( 
"shader/surface/utility" );
 
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"4.0.1", 
"Any");
 
    status = plugin.registerNode( "hwUnlitShader", hwUnlitShader::id, 
                                  hwUnlitShader::creator, hwUnlitShader::initialize,
    if (!status) {
        status.
perror(
"registerNode");
        return status;
    }
}
{
    
    plugin.deregisterNode( hwUnlitShader::id );
    if (!status) {
        status.
perror(
"deregisterNode");
        return status;
    }
}
MStatus hwUnlitShader::initialize()
 
{
    
    color = nAttr.
create( 
"color", 
"c", colorR, colorG, colorB);
    
    transparency = nAttr.
create( 
"transparency", 
"it", transparencyR, transparencyG, transparencyB);
    
    addAttribute(color);
    addAttribute(transparency);
 
    
    
    
}
{ 
    bool k = false;
    k |= (plug==outColor);
    k |= (plug==outColorR);
    k |= (plug==outColorG);
    k |= (plug==outColorB);
    
    
    outColor = resultColor;
}
{
    
    
    MPlug   plug(thisMObject(), attr);
 
    if (!status)
    {
        status.
perror(
"hwUnlitShader::bind plug.getValue.");
        return status;
    }
    if (!status)
    {
        status.
perror(
"hwUnlitShader::bind construct data.");
        return status;
    }
    status = data.getData(value[0], value[1], value[2]);
    if (!status)
    {
        status.
perror(
"hwUnlitShader::bind get values.");
        return status;
    }
}
{
    MPlug   plug(thisMObject(), attr);
 
}
void hwUnlitShader::updateTransparencyFlags(
MString objectPath)
 
{
    
    
    
    
    ShadingConnection transparencyConnection(thisMObject(), objectPath, "transparency");
    if (transparencyConnection.type() == ShadingConnection::CONSTANT_COLOR)
    {
        
        MColor tc = transparencyConnection.constantColor();
 
        fConstantTransparency = (tc.
r + tc.
g + tc.
b) / 3.0f;
    }
    else
        fConstantTransparency = 0.0f;   
}
{
    
    float bgColor[4] = {1,1,1,1};
    
    MString currentPathName( currentObjectPath.partialPathName() );
 
    updateTransparencyFlags(currentPathName);
    
    ShadingConnection colorConnection(thisMObject(), currentPathName, "color");
    
    
    if (colorConnection.type() == ShadingConnection::TEXTURE &&
    {
        
        MPlug filenamePlug( colorConnection.texture(), textureNode.attribute(
MString(
"fileTextureName")) );
 
        if (decalName == "")
            getFloat3(color, bgColor);
    }
    else
    {
        decalName = "";
        getFloat3(color, bgColor);
    }
    
    assert(glGetError() == GL_NO_ERROR);
    glPushAttrib( GL_ALL_ATTRIB_BITS );
    glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    
    float alpha = 1.0f - fConstantTransparency;
    
    
    
    glColor4f(bgColor[0], bgColor[1], bgColor[2], alpha);
    
    {
        
        glEnable(GL_TEXTURE_2D);
        assert(glGetError() == GL_NO_ERROR);
        
        
        
        
        
        if(m_pTextureCache)
            m_pTextureCache->bind(colorConnection.texture(), MTexture::RGBA, false);    
        
        
        
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    }
    
    glDisable(GL_LIGHTING);
}
{
    glPopClientAttrib();
    glPopAttrib();
}
                                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)
{
    glVertexPointer(3, GL_FLOAT, 0, vertexArray);
    glEnableClientState(GL_VERTEX_ARRAY);
    if (normalCount > 0)
    {
        
        
        
        glNormalPointer(GL_FLOAT, 0, normalArrays[0]);
        glEnableClientState(GL_NORMAL_ARRAY);
    }
    if (texCoordCount > 0)
    {
        glTexCoordPointer(2, GL_FLOAT, 0, texCoordArrays[0]);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    }
    glDrawElements(prim, indexCount, GL_UNSIGNED_INT, indexArray);
}
int     hwUnlitShader::normalsPerVertex()
{
    
    return 1;
}
int     hwUnlitShader::texCoordsPerVertex()
{
    return 1;
}
bool    hwUnlitShader::hasTransparency()
{
    
    
    
    
    return true;
}