#include "cgfxShaderCommon.h"
#include "cgfxShaderNode.h"
#include "cgfxShaderCmd.h"
#include "cgfxVector.h"
#include <maya/MFnPlugin.h>
#include <maya/MIOStream.h>
#include <maya/MSceneMessage.h>
#include <maya/MNodeMessage.h>
#include <maya/MGlobal.h>
#include <maya/MFileIO.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MDGMessage.h>
#if defined(_SWATCH_RENDERING_SUPPORTED_)
#include <maya/MHWShaderSwatchGenerator.h>
#include <maya/MHardwareRenderer.h>
#endif
static MIntArray callbackIds;
static void cgfxShaderFileSaveCB(void* clientData );
static void cgfxShaderFileReadCB(void* clientData );
MStatus initializePlugin( MObject obj )
{
MString sVer = cgfxShaderNode::getPluginVersion();
#if defined(_SWATCH_RENDERING_SUPPORTED_)
const char *cgfxEnvVar = getenv("CGFX_SWATCH_RENDERING");
MString UserClassify = MString( "shader/surface/utility" );
if (MGlobal::mayaState() != MGlobal::kBatch)
{
const MString& swatchName = MHWShaderSwatchGenerator::initialize();
#ifdef _WIN32
if (!cgfxEnvVar)
UserClassify = MString( "shader/surface/utility/:swatch/"+swatchName );
else
{
if ( 0 != strcmp(cgfxEnvVar,"0") )
UserClassify = MString( "shader/surface/utility/:swatch/"+swatchName );
}
#else
if ( cgfxEnvVar && ( 0 != strcmp(cgfxEnvVar,"0") ) )
{
UserClassify = MString( "shader/surface/utility/:swatch/"+swatchName );
}
#endif
}
#else
const MString UserClassify( "shader/surface/utility" );
#endif
MFnPlugin plugin( obj, "NVIDIA", sVer.asChar(), MApiVersion );
MGlobal::displayInfo( sVer );
CHECK_MSTATUS( plugin.registerUIStrings(NULL,
"cgfxShaderPluginInitStrings" ));
#if defined(_SWATCH_RENDERING_SUPPORTED_)
MStatus status = MStatus::kFailure;
#if !defined(LINUX)
if (MGlobal::mayaState() != MGlobal::kInteractive)
#endif
{
MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer();
if (pRenderer) {
const MString & backEndStr = pRenderer->backEndString();
unsigned int width = 64, height = 64;
status = pRenderer->makeSwatchContextCurrent( backEndStr,
width,
height );
}
if (status != MStatus::kSuccess) {
MGlobal::displayError(MString("Unqualified video card : Offscreen contexts not supported. CgFx plugin will not be loaded."));
return MStatus::kFailure;
}
}
#else
#error "CgFx requires the Maya version 7 or greater"
#endif
cgfxShaderNode::sCgContext = cgCreateContext();
cgSetErrorCallback(cgfxShaderNode::cgErrorCallBack);
cgSetErrorHandler(cgfxShaderNode::cgErrorHandler, 0);
cgGLRegisterStates(cgfxShaderNode::sCgContext);
cgGLSetManageTextureParameters(cgfxShaderNode::sCgContext, CG_TRUE);
CHECK_MSTATUS( plugin.registerNode("cgfxShader",
cgfxShaderNode::sId,
cgfxShaderNode::creator,
cgfxShaderNode::initialize,
MPxNode::kHwShaderNode,
&UserClassify));
CHECK_MSTATUS( plugin.registerNode("cgfxVector",
cgfxVector::sId,
cgfxVector::creator,
cgfxVector::initialize));
CHECK_MSTATUS( plugin.registerCommand("cgfxShader",
cgfxShaderCmd::creator,
cgfxShaderCmd::newSyntax));
cgfxShaderCmd::sPluginPath = plugin.loadPath();
if (MGlobal::mayaState() == MGlobal::kInteractive)
{
MString sCmd = "evalDeferred \"source \\\"cgfxShader_initUI.mel\\\"\"";
MGlobal::executeCommand( sCmd );
}
MCallbackId id;
id = MSceneMessage::addCallback(MSceneMessage::kAfterNew,
cgfxShaderFileReadCB, NULL, &status);
CHECK_MSTATUS(status);
callbackIds.append((int)id);
id = MSceneMessage::addCallback(MSceneMessage::kAfterImport,
cgfxShaderFileReadCB, NULL, &status);
CHECK_MSTATUS(status);
callbackIds.append((int)id);
id = MSceneMessage::addCallback(MSceneMessage::kAfterOpen,
cgfxShaderFileReadCB, NULL, &status);
CHECK_MSTATUS(status);
callbackIds.append((int)id);
id = MSceneMessage::addCallback(MSceneMessage::kAfterReference,
cgfxShaderFileReadCB, NULL, &status);
CHECK_MSTATUS(status);
callbackIds.append((int)id);
id = MSceneMessage::addCallback(MSceneMessage::kBeforeSave,
cgfxShaderFileSaveCB, NULL, &status);
CHECK_MSTATUS(status);
callbackIds.append((int)id);
id = MSceneMessage::addCallback(MSceneMessage::kBeforeExport,
cgfxShaderFileSaveCB, NULL, &status);
CHECK_MSTATUS(status);
callbackIds.append((int)id);
return MStatus::kSuccess;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
cgDestroyContext(cgfxShaderNode::sCgContext);
MMessage::removeCallbacks(callbackIds);
CHECK_MSTATUS(plugin.deregisterNode( cgfxShaderNode::sId ));
CHECK_MSTATUS(plugin.deregisterNode( cgfxVector::sId ));
CHECK_MSTATUS(plugin.deregisterCommand( "cgfxShader" ));
return MStatus::kSuccess;
}
static void cfxfFxFileChanged( MPlug& plug )
{
MString fxFile;
plug.getValue(fxFile);
MString nodeName = plug.name();
int index = nodeName.index('.');
if (index >= 0)
{
nodeName = nodeName.substring(0, index - 1);
MString cmd("cgfxShader -e -fx \"");
cmd += fxFile;
cmd += "\" ";
cmd += nodeName;
cmd += ";";
MGlobal::executeCommand(cmd);
}
}
static void cgfxShaderFileSaveCB(void* clientData )
{
MStatus status;
MString workspace;
status = MGlobal::executeCommand(MString("workspace -q -rd;"),
workspace);
if (!status)
{
workspace.clear();
}
MItDependencyNodes nodeIt;
for (nodeIt.reset(MFn::kPluginHwShaderNode);
!nodeIt.isDone();
nodeIt.next())
{
MObject oNode = nodeIt.item();
MFnDependencyNode fnNode(oNode);
if (fnNode.typeId() == cgfxShaderNode::sId)
{
cgfxShaderNode* pNode = (cgfxShaderNode*)fnNode.userNode();
MString ShaderFxFile = pNode->shaderFxFile();
if (strncmp(ShaderFxFile.asChar(),workspace.asChar(),workspace.length()) == 0)
{
ShaderFxFile = ShaderFxFile.substring(workspace.length(),ShaderFxFile.length() - 1);
MPlug plShader = fnNode.findPlug( pNode->sShader );
plShader.setValue( ShaderFxFile );
OutputDebugString("CGFX shader pathname saved as: ");
OutputDebugString(ShaderFxFile.asChar());
OutputDebugString("\n");
}
if( pNode->getTexturesByName())
{
cgfxAttrDefList::iterator it(pNode->attrDefList());
while (it)
{
cgfxAttrDef* aDef = (*it);
MObject oNode = pNode->thisMObject();
switch (aDef->fType)
{
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:
{
MString pathname;
aDef->getValue(oNode, pathname);
if (strncmp(pathname.asChar(),workspace.asChar(),workspace.length()) == 0)
{
pathname = pathname.substring(workspace.length(),pathname.length());
aDef->setValue(oNode, pathname);
OutputDebugString("CGFX texture pathname saved as: ");
OutputDebugString(pathname.asChar());
OutputDebugString("\n");
}
}
break;
default:
break;
}
++it;
}
}
}
}
}
static void cgfxShaderFileReadCB(void* clientData )
{
MStatus status;
MItDependencyNodes nodeIt;
for (nodeIt.reset(MFn::kPluginHwShaderNode);
!nodeIt.isDone();
nodeIt.next())
{
MObject oNode = nodeIt.item();
MFnDependencyNode fnNode(oNode);
if (fnNode.typeId() == cgfxShaderNode::sId)
{
MPlug plug(oNode, cgfxShaderNode::sShader);
cfxfFxFileChanged( plug );
}
}
}