#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;
}
return MS::kSuccess;
}
{
plugin.deregisterNode( hwUnlitShader::id );
if (!status) {
status.
perror(
"deregisterNode");
return status;
}
return MS::kSuccess;
}
MStatus hwUnlitShader::initialize()
{
color = nAttr.
create(
"color",
"c", colorR, colorG, colorB);
transparency = nAttr.
create(
"transparency",
"it", transparencyR, transparencyG, transparencyB);
addAttribute(color);
addAttribute(transparency);
return MS::kSuccess;
}
{
bool k = false;
k |= (plug==outColor);
k |= (plug==outColorR);
k |= (plug==outColorG);
k |= (plug==outColorB);
if( !k ) return MS::kUnknownParameter;
outColor = resultColor;
return MS::kSuccess;
}
{
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;
}
return MS::kSuccess;
}
{
MPlug plug(thisMObject(), attr);
return MS::kSuccess;
}
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);
return MS::kSuccess;
}
{
glPopClientAttrib();
glPopAttrib();
return MS::kSuccess;
}
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);
return MS::kSuccess;
}
int hwUnlitShader::normalsPerVertex()
{
return 1;
}
int hwUnlitShader::texCoordsPerVertex()
{
return 1;
}
bool hwUnlitShader::hasTransparency()
{
return true;
}