#include "GLSLShader.h"
#include "GLSLShaderSemantics.h"
#include "GLSLShaderStrings.h"
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnStringData.h>
#include <maya/MFnDependencyNode.h>
#include <maya/M3dView.h>
#include <maya/MGlobal.h>
#include <maya/MFileIO.h>
#include <maya/MString.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MFnAmbientLight.h>
#include <maya/MFnMessageAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnEnumAttribute.h>
#include <maya/MFnStringArrayData.h>
#include <maya/MDGModifier.h>
#include <maya/MEventMessage.h>
#include <maya/MSceneMessage.h>
#include <maya/MPlugArray.h>
#include <maya/MFileObject.h>
#include <maya/MModelMessage.h>
#include <maya/MAngle.h>
#include <maya/MImageFileInfo.h>
#include <maya/MRenderUtil.h>
#include <maya/MAnimControl.h>
#include <maya/MRenderProfile.h>
#include <maya/MPointArray.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MDrawContext.h>
#include <maya/MTextureManager.h>
#include <maya/MHWGeometryUtilities.h>
#include <maya/MRenderUtilities.h>
#include <maya/MRenderTargetManager.h>
#include <maya/MUIDrawManager.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <list>
#if defined(_WIN32)
#define STRICMP(X,Y) stricmp(X,Y)
#define MSTRICMP(X,Y) stricmp(X.asChar(),Y)
using namespace std;
#else
#include <strings.h>
#define STRICMP(X,Y) strcasecmp(X,Y)
#define MSTRICMP(X,Y) strcasecmp(X.asChar(),Y)
#endif
const MTypeId GLSLShaderNode::m_TypeId(0x00081101);
const MString GLSLShaderNode::m_TypeName(
"GLSLShader");
const MString GLSLShaderNode::m_RegistrantId(
"GLSLShaderRegistrantId");
const MString GLSLShaderNode::m_drawDbClassification(
"drawdb/shader/surface/GLSLShader");
static MObject sEffectUniformParameters;
#define M_CHECK(assertion) if (assertion) ; else throw ((GLSLShaderNamespace::InternalError*)__LINE__)
namespace GLSLShaderNamespace
{
struct InternalError
{
char* message;
};
const unsigned int sNbMacros = 1;
}
struct MStringSorter
{
{
}
};
class EffectCollection
{
public:
static EffectCollection& instance()
{
static EffectCollection s_instance;
return s_instance;
}
inline void registerNode(GLSLShaderNode* node,
const MString& effectName)
{
fEffectLookup[node] = effectName;
fNodesLookup[effectName].insert(node);
}
inline void deregisterNode(GLSLShaderNode* node)
{
const MString effectName = fEffectLookup[node];
fEffectLookup.erase(node);
fNodesLookup[effectName].erase(node);
if(fNodesLookup[effectName].size() == 0) {
fNodesLookup.erase(effectName);
unregisterBrokenEffect(node, effectName);
}
}
typedef std::set<GLSLShaderNode*> NodeSet_t;
inline void getNodesUsingEffect(
const MString& effectName, NodeSet_t &nodes)
const
{
Effect2NodesMap_t::const_iterator it = fNodesLookup.find(effectName);
if(it != fNodesLookup.end()) {
nodes = it->second;
}
}
bool isBrokenEffect(
const MString& effectName )
const
{
return fBrokenEffects.count(effectName) > 0;
}
void registerBrokenEffect(
const MString& effectName )
{
fBrokenEffects.insert(effectName);
}
void unregisterBrokenEffect( GLSLShaderNode* node,
const MString& effectName )
{
if (!renderer)
return;
if (!shaderMgr)
return;
if (techniqueNames.
length() == 0)
shaderMgr->
getEffectsTechniques(effectName, techniqueNames, GLSLShaderNamespace::sMacros, GLSLShaderNamespace::sNbMacros);
for (
int i = 0; i < (int) techniqueNames.
length(); ++i)
{
const MString& technique = techniqueNames[i];
shaderMgr->
removeEffectFromCache(effectName, technique, GLSLShaderNamespace::sMacros, GLSLShaderNamespace::sNbMacros);
}
fBrokenEffects.erase(effectName);
}
private:
EffectCollection() {}
private:
typedef std::map<GLSLShaderNode*, MString> Node2EffectMap_t;
typedef std::map<MString, NodeSet_t, MStringSorter> Effect2NodesMap_t;
typedef std::set<MString, MStringSorter> StringSet_t;
Node2EffectMap_t fEffectLookup;
Effect2NodesMap_t fNodesLookup;
StringSet_t fBrokenEffects;
};
{
GLSLShaderNode::ELightType type = GLSLShaderNode::eUndefinedLight;
switch (lightType.
asChar()[2])
{
case 'o':
if (STRICMP(lightType.
asChar(),
"spotLight") == 0)
type = GLSLShaderNode::eSpotLight;
break;
case 'r':
if (STRICMP(lightType.
asChar(),
"directionalLight") == 0)
{
type = GLSLShaderNode::eDirectionalLight;
else
type = GLSLShaderNode::eDefaultLight;
}
break;
case 'i':
if (STRICMP(lightType.
asChar(),
"pointLight") == 0)
type = GLSLShaderNode::ePointLight;
break;
case 'b':
if (STRICMP(lightType.
asChar(),
"ambientLight") == 0)
type = GLSLShaderNode::eAmbientLight;
break;
case 'l':
if (STRICMP(lightType.
asChar(),
"volumeLight") == 0)
type = GLSLShaderNode::eVolumeLight;
break;
case 'e':
if (STRICMP(lightType.
asChar(),
"areaLight") == 0)
type = GLSLShaderNode::eAreaLight;
break;
}
}
return type;
}
static int findSubstring(
const MString& haystack,
const MString& needle)
{
int at = haystack.
indexW(needle);
if(at < 0)
{
at = haystack.
indexW(needleLowerCase);
}
return at;
}
{
std::string retVal(dirtyName.
asChar());
for (size_t i=0; i<retVal.size(); ++i)
if (!isalnum(retVal[i]))
retVal.replace(i, 1, "_");
}
{
unsigned int index = 0;
for (; index < where.
length(); ++index)
{
if (where[index] == what || sanitizeName(where[index]) == what)
return (int)index;
}
if (appendIfNotFound)
{
return (int)index;
}
return -1;
}
static const wchar_t layerNameSeparator(L'\r');
{
return;
return;
alphaChannelIdx = -1;
const int idx = fileName.
indexW(layerNameSeparator);
if(idx >= 0)
{
fileName.
split(layerNameSeparator, splitData);
alphaChannelIdx = splitData[2].asInt();
layerName = splitData[1];
fileName = splitData[0];
}
else
{
}
plug = dependNode.
findPlug(
"alpha",
true);
if(alphaChannel.
length() > 0) {
if(alphaChannel == "Default") {
alphaChannelIdx = 1;
}
else {
plug = dependNode.
findPlug(
"alphaList",
true);
stringArrayData.copyTo(allAlphaChannels);
unsigned int count = allAlphaChannels.
length();
for(unsigned int idx = 0; idx < count; ++idx) {
const MString& channel = allAlphaChannels[idx];
if(channel == alphaChannel) {
alphaChannelIdx = idx + 2;
break;
}
}
}
}
}
}
}
}
}
static bool resetTechniqueEnumAttribute(const GLSLShaderNode& shader)
{
if (!stat) return false;
MObject attr = node.attribute(
"techniqueEnum", &stat);
{
MString addAttrCmd = enumAttr.getAddAttrCmd();
if (addAttrCmd.
indexW(
" -en ") >= 0)
{
MPlug techniquePlug = node.findPlug(attr,
false);
MString resetCmd =
"addAttr -e -en \"\" ";
}
}
return true;
}
static MObject buildTechniqueEnumAttribute(
const GLSLShaderNode& shader)
{
resetTechniqueEnumAttribute(shader);
MObject attr = node.attribute(
"techniqueEnum", &stat);
{
attr = enumAttr.
create(
"techniqueEnum",
"te", 0, &stat);
node.addAttribute(attr);
}
M_CHECK(techniques.
length() < (
unsigned int)std::numeric_limits<short>::max());
for (
unsigned int i = 0; i < techniques.
length(); ++i)
{
enumAttr.
addField(techniques[i], (
short)i);
}
return attr;
}
static bool isLightAcceptable(GLSLShaderNode::ELightType shaderLightType, GLSLShaderNode::ELightType sceneLightType)
{
if(sceneLightType == GLSLShaderNode::eSpotLight)
return true;
if(sceneLightType == GLSLShaderNode::eDirectionalLight || sceneLightType == GLSLShaderNode::eDefaultLight)
return (shaderLightType == GLSLShaderNode::eDirectionalLight || shaderLightType == GLSLShaderNode::eAmbientLight);
if(sceneLightType == GLSLShaderNode::ePointLight ||
sceneLightType == GLSLShaderNode::eAreaLight ||
sceneLightType == GLSLShaderNode::eVolumeLight)
return (shaderLightType == GLSLShaderNode::ePointLight || shaderLightType == GLSLShaderNode::eAmbientLight);
if(sceneLightType == GLSLShaderNode::eAmbientLight)
return (shaderLightType == GLSLShaderNode::eAmbientLight);
return false;
}
typedef std::vector<MStringArray> TNamesForSemantic;
typedef std::vector<TNamesForSemantic> TSemanticNamesForLight;
static TSemanticNamesForLight sSemanticNamesForLight(GLSLShaderNode::eLightCount);
{
TNamesForSemantic& namesForLight(sSemanticNamesForLight[lightType]);
namesForLight.resize(GLSLShaderNode::eLastParameterType);
for (
unsigned int p = 0; p < params.
length(); ++p)
{
switch (semantic)
{
namesForLight[GLSLShaderNode::eLightPosition].append(pname);
if (pname == "LP0")
namesForLight[GLSLShaderNode::eLightAreaPosition0].append(pname);
if (pname == "LP1")
namesForLight[GLSLShaderNode::eLightAreaPosition1].append(pname);
if (pname == "LP2")
namesForLight[GLSLShaderNode::eLightAreaPosition2].append(pname);
if (pname == "LP3")
namesForLight[GLSLShaderNode::eLightAreaPosition3].append(pname);
break;
namesForLight[GLSLShaderNode::eLightDirection].append(pname);
break;
namesForLight[GLSLShaderNode::eLightIntensity].append(pname);
break;
namesForLight[GLSLShaderNode::eLightColor].append(pname);
namesForLight[GLSLShaderNode::eLightAmbientColor].append(pname);
namesForLight[GLSLShaderNode::eLightSpecularColor].append(pname);
namesForLight[GLSLShaderNode::eLightDiffuseColor].append(pname);
break;
namesForLight[GLSLShaderNode::eLightShadowOn].append(pname);
break;
namesForLight[GLSLShaderNode::eLightShadowViewProj].append(pname);
break;
namesForLight[GLSLShaderNode::eLightShadowOn].append(pname);
namesForLight[GLSLShaderNode::eLightShadowMap].append(pname);
namesForLight[GLSLShaderNode::ePointLightShadowMap].append(pname);
break;
namesForLight[GLSLShaderNode::eLightShadowColor].append(pname);
break;
namesForLight[GLSLShaderNode::eLightShadowMapBias].append(pname);
break;
namesForLight[GLSLShaderNode::eLightHotspot].append(pname);
namesForLight[GLSLShaderNode::eLightFalloff].append(pname);
break;
namesForLight[GLSLShaderNode::eDecayRate].append(pname);
break;
default:
break;
}
}
}
{
if (sSemanticNamesForLight[lightType].size() == 0)
buildDrawContextParameterNames(lightType, lightParam);
return sSemanticNamesForLight[lightType][paramType];
}
{
switch (dataType)
{
default:
}
}
{
return paramSemantic;
}
class AfterOpenErrorCB
{
public:
static void addError(
const MString& errorMsg)
{
if(sInstance == NULL)
sInstance = new AfterOpenErrorCB;
sInstance->mErrorMsg += errorMsg;
}
private:
AfterOpenErrorCB()
{
}
~AfterOpenErrorCB()
{
}
static void afterOpen(void*)
{
if(sInstance)
{
delete sInstance;
sInstance = NULL;
}
}
private:
MCallbackId mSceneOpenedCallback;
static AfterOpenErrorCB *sInstance;
};
AfterOpenErrorCB *AfterOpenErrorCB::sInstance = NULL;
class IdleAttributeEditorImplicitRefresher
{
public:
static void activate()
{
if (sInstance == NULL)
sInstance = new IdleAttributeEditorImplicitRefresher();
};
private:
IdleAttributeEditorImplicitRefresher()
{
};
~IdleAttributeEditorImplicitRefresher()
{
}
static void refresh(void* data)
{
if (sInstance)
{
delete sInstance;
sInstance = NULL;
}
}
private:
MCallbackId mIdleCallback;
static IdleAttributeEditorImplicitRefresher *sInstance;
};
IdleAttributeEditorImplicitRefresher *IdleAttributeEditorImplicitRefresher::sInstance = NULL;
class PostSceneUpdateAttributeRefresher
{
public:
static void add(GLSLShaderNode* node)
{
if (sInstance == NULL)
sInstance = new PostSceneUpdateAttributeRefresher();
sInstance->mNodeSet.insert(node);
};
static void remove(GLSLShaderNode* node)
{
if (sInstance != NULL)
sInstance->mNodeSet.erase(node);
}
private:
PostSceneUpdateAttributeRefresher()
{
};
~PostSceneUpdateAttributeRefresher()
{
}
static void refresh(void* data)
{
if (sInstance)
{
for (TNodeSet::iterator itNode = sInstance->mNodeSet.begin();
itNode != sInstance->mNodeSet.end();
++itNode )
{
(*itNode)->refreshLightConnectionAttributes(true);
}
delete sInstance;
sInstance = NULL;
}
}
private:
typedef std::set<GLSLShaderNode*> TNodeSet;
TNodeSet mNodeSet;
MCallbackId mSceneUpdateCallback;
MCallbackId mAfterCreateReference;
MCallbackId mAfterImport;
MCallbackId mAfterLoadReference;
static PostSceneUpdateAttributeRefresher *sInstance;
};
PostSceneUpdateAttributeRefresher *PostSceneUpdateAttributeRefresher::sInstance = NULL;
GLSLShaderNode::GLSLShaderNode()
: fEffectLoaded(false)
, fGLSLShaderInstance(NULL)
, fTechniqueName("Main")
, fTechniqueIdx(-1)
, fTechniqueIsSelectable(false)
, fTechniqueIsTransparent(false)
, fTechniqueSupportsAdvancedTransparency(false)
, fTechniqueOverridesDrawState(false)
, fTechniqueTextureMipmapLevels(0)
, fTechniqueBBoxExtraScale(1.0)
, fTechniqueOverridesNonMaterialItems(false)
, fTechniqueHandlesConsolidatedGeometry(true)
, fTechniquePassCount(0)
, fTechniquePassSpecs()
, fLastFrameStamp((MUint64)-1)
{
static bool s_addResourcePath = true;
if (s_addResourcePath)
{
if (renderer)
{
if (textureMgr) {
}
if (shaderMgr) {
}
}
s_addResourcePath = false;
}
}
GLSLShaderNode::~GLSLShaderNode()
{
EffectCollection::instance().deregisterNode(this);
deleteUniformUserData();
PostSceneUpdateAttributeRefresher::remove(this);
if (fGLSLShaderInstance)
{
if (renderer)
{
if (shaderMgr)
{
fGLSLShaderInstance = NULL;
}
}
}
}
MStatus GLSLShaderNode::initialize()
{
try
{
initializeNodeAttrs();
}
catch ( ... )
{
ms = MS::kFailure;
}
return ms;
}
void* GLSLShaderNode::creator()
{
return new GLSLShaderNode();
}
void GLSLShaderNode::initializeNodeAttrs()
{
M_CHECK( stat );
stat = addAttribute(sShader);
M_CHECK( stat );
M_CHECK( stat );
stat = addAttribute(sEffectUniformParameters);
M_CHECK( stat );
M_CHECK( stat );
stat = addAttribute(sTechnique);
M_CHECK( stat );
M_CHECK( stat );
stat = addAttribute(sTechniques);
M_CHECK( stat );
M_CHECK( stat );
stat = addAttribute(sDescription);
M_CHECK( stat );
M_CHECK( stat );
stat = addAttribute(sDiagnostics);
M_CHECK( stat );
M_CHECK( stat );
stat = addAttribute(sLightInfo);
M_CHECK( stat );
attributeAffects( sShader, sTechniques);
attributeAffects( sShader, sTechnique);
}
{
bool retVal = true;
try
{
if (plug == sShader)
{
handle.
set( fEffectName );
}
else if (plug == sTechnique)
{
handle.
set( fTechniqueName );
}
else if (plug ==sTechniques)
{
if (tlist)
else
}
else if (plug == fTechniqueEnumAttr)
{
fTechniqueIdx = -1;
for (int i = 0; i < (int) fTechniqueNames.length(); ++i)
{
if (fTechniqueNames[i] == fTechniqueName)
{
fTechniqueIdx = i;
break;
}
}
if (fTechniqueIdx >=0)
{
handle.
set((
short)fTechniqueIdx);
}
}
else
{
}
}
catch ( ... )
{
retVal = false;
}
return retVal;
}
bool GLSLShaderNode::setInternalValue(
const MPlug& plug,
const MDataHandle& handle)
{
bool retVal = true;
try
{
if (plug == sShader)
{
}
else if (plug == sTechnique)
{
loadEffect (fEffectName);
}
else if (plug == fTechniqueEnumAttr)
{
M_CHECK(fTechniqueNames.length() < (unsigned int)std::numeric_limits<int>::max());
if (index >= 0 && index < (int)fTechniqueNames.length() && index != fTechniqueIdx)
{
fTechniqueName = fTechniqueNames[index];
}
}
else
{
}
}
catch( ... )
{
retVal = false;
}
return retVal;
}
MStatus GLSLShaderNode::dependsOn(
const MPlug& plug,
const MPlug& otherPlug,
bool& depends)
const
{
if( plug == outColor )
{
unsigned int paramCount = fUniformParameters.length();
for( unsigned int i = 0; i < paramCount; ++i )
{
{
return MS::kSuccess;
}
}
}
return MS::kUnknownParameter;
}
const MString& GLSLShaderNode::effectName()
const
{
return fEffectName;
}
bool GLSLShaderNode::loadEffect(
const MString& effectName)
{
if (!renderer)
return false;
if (renderer->
drawAPI() != MHWRender::kOpenGLCoreProfile) {
fEffectName = effectName;
return false;
}
if (!shaderMgr)
return false;
{
return false;
}
{
clearParameters();
fEffectName.clear();
fEffectLoaded = false;
if (fGLSLShaderInstance != NULL) {
fGLSLShaderInstance = NULL;
}
fTechniqueNames.clear();
return true;
}
if (fGLSLShaderInstance != NULL)
{
fEffectLoaded = false;
fGLSLShaderInstance = NULL;
}
EffectCollection::instance().registerNode(this, effectName);
if (EffectCollection::instance().isBrokenEffect(effectName))
{
fEffectName = effectName;
return false;
}
shaderMgr->
getEffectsTechniques(effectName, techniqueNames, GLSLShaderNamespace::sMacros, GLSLShaderNamespace::sNbMacros);
if (techniqueNames.
length() == 0)
{
errorArgs.
append( effectName );
const MString errorMsg = glslShaderStrings::getString( glslShaderStrings::kErrorLoadingEffect, errorArgs );
displayErrorAndWarnings(errorMsg);
fEffectName = effectName;
EffectCollection::instance().registerBrokenEffect(effectName);
return false;
}
int techniqueIdx = -1;
if (fTechniqueName.length() > 0)
{
for (
unsigned int i = 0; i < techniqueNames.
length(); ++i)
{
if (techniqueNames[i] == fTechniqueName)
{
techniqueName = fTechniqueName;
techniqueIdx = i;
break;
}
}
}
if (techniqueName.
length() == 0) {
techniqueName = techniqueNames[0];
techniqueIdx = 0;
}
if (newInstance)
{
if(context)
{
{
newInstance->
unbind(*context);
context = 0;
EffectCollection::instance().registerBrokenEffect(effectName);
}
}
}
else
{
EffectCollection::instance().registerBrokenEffect(effectName);
}
if (context)
{
clearLightConnectionData(false );
fLightParameters.clear();
fGLSLShaderInstance = newInstance;
fEffectName = effectName;
fTechniqueNames = techniqueNames;
fTechniqueName = techniqueName;
fTechniqueIdx = techniqueIdx;
MPlug descriptionPlug( thisMObject(), sDescription);
descriptionPlug.setValue( "" );
fTechniqueIsSelectable = false;
fTechniquePassCount = 0;
fTechniquePassSpecs.
clear();
for (unsigned int passIndex = 0; passIndex < fTechniquePassCount; ++passIndex)
{
fTechniqueIsSelectable = true;
const bool passIsForFatLine = (STRICMP(passPrimitiveFilter.
asChar(), glslShaderAnnotationValue::kFatLine) == 0);
const bool passIsForFatPoint = (STRICMP(passPrimitiveFilter.
asChar(), glslShaderAnnotationValue::kFatPoint) == 0);
PassSpec spec = { passDrawContext, passIsForFatLine, passIsForFatPoint };
fTechniquePassSpecs.insert( std::make_pair(passIndex, spec) );
}
newInstance->
unbind(*context);
context = NULL;
fTechniqueIsTransparent = false;
const MString transparency = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kTransparency, opStatus);
{
fTechniqueIsTransparent = (STRICMP(transparency.
asChar(), glslShaderAnnotationValue::kValueTransparent)==0);
}
fTechniqueSupportsAdvancedTransparency = false;
const MString advancedTransparency = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kSupportsAdvancedTransparency, opStatus);
{
fTechniqueSupportsAdvancedTransparency = (STRICMP(advancedTransparency.
asChar(), glslShaderAnnotationValue::kValueTrue)==0);
}
fTechniqueIndexBufferType =
MString();
const MString indexBufferType = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kIndexBufferType, opStatus);
{
fTechniqueIndexBufferType = indexBufferType;
if( fTechniqueIndexBufferType == "PNAEN18" )
fTechniqueIndexBufferType = "GLSL_PNAEN18";
else if( fTechniqueIndexBufferType == "PNAEN9" )
fTechniqueIndexBufferType = "GLSL_PNAEN9";
}
fTechniqueOverridesDrawState = false;
const MString overridesDrawState = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kOverridesDrawState, opStatus);
{
fTechniqueOverridesDrawState = (STRICMP(overridesDrawState.
asChar(), glslShaderAnnotationValue::kValueTrue)==0);
}
fTechniqueTextureMipmapLevels = 0;
const int textureMipMapLevels = fGLSLShaderInstance->techniqueAnnotationAsInt(glslShaderAnnotation::kTextureMipmaplevels, opStatus);
{
fTechniqueTextureMipmapLevels = textureMipMapLevels;
}
fTechniqueBBoxExtraScale = 1.0;
const double extraScale = (double) fGLSLShaderInstance->techniqueAnnotationAsFloat(glslShaderAnnotation::kExtraScale, opStatus);
{
fTechniqueBBoxExtraScale = extraScale;
}
fTechniqueOverridesNonMaterialItems = false;
MString overridesNonMaterialItems = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kOverridesNonMaterialItems, opStatus);
{
fTechniqueOverridesNonMaterialItems = (STRICMP(overridesNonMaterialItems.
asChar(), glslShaderAnnotationValue::kValueTrue)==0);
}
fTechniqueHandlesConsolidatedGeometry = true;
MString handlesConsolidatedGeometry = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kHandlesConsolidatedGeometry, opStatus);
{
fTechniqueHandlesConsolidatedGeometry = (STRICMP(handlesConsolidatedGeometry.
asChar(), glslShaderAnnotationValue::kValueTrue)==0);
}
configureUniforms();
configureGeometryRequirements();
fTechniqueEnumAttr = buildTechniqueEnumAttribute(*this);
fEffectLoaded = true;
IdleAttributeEditorImplicitRefresher::activate();
displayErrorAndWarnings(
MString());
return true;
}
fEffectName = effectName;
errorArgs.
append( effectName );
const MString errorMsg = glslShaderStrings::getString( glslShaderStrings::kErrorLoadingEffect, errorArgs );
displayErrorAndWarnings(errorMsg);
return false;
}
void GLSLShaderNode::displayErrorAndWarnings(
const MString& message)
const
{
MPlug diagnosticsPlug( thisMObject(), sDiagnostics);
diagnosticsPlug.setValue( message );
{
{
AfterOpenErrorCB::addError(message);
}
else
{
}
}
}
void GLSLShaderNode::clearParameters()
{
clearLightConnectionData();
fLightParameters.clear();
fUniformParameters.setLength(0);
setUniformParameters( fUniformParameters, false );
deleteUniformUserData();
fGeometryRequirements.clear();
fVaryingParameters.setLength(0);
setVaryingParameters( fVaryingParameters, false );
fVaryingParametersUpdateId = 0;
fTechniqueIndexBufferType.clear();
fTechniquePassSpecs.clear();
fTechniqueIdx = -1;
fUIGroupNames.setLength(0);
fUIGroupParameters.clear();
}
{
const MString uiWidget = fGLSLShaderInstance->uiWidget(parameterName, opStatus);
{
if (uiWidget == "None")
{
}
else
{
#define SET_VALUE_FROM_ANNOTATION(shaderAnnotation, parameterFunction) \
{ \
const float value = fGLSLShaderInstance->annotationAsFloat(parameterName, glslShaderAnnotation::shaderAnnotation, opStatus); \
if (opStatus == MStatus::kSuccess) \
{ \
uniformParam.parameterFunction((double)value); \
} \
}
SET_VALUE_FROM_ANNOTATION(kUIMin, setRangeMin);
SET_VALUE_FROM_ANNOTATION(kUIMax, setRangeMax);
SET_VALUE_FROM_ANNOTATION(kUISoftMin, setSoftRangeMin);
SET_VALUE_FROM_ANNOTATION(kUISoftMax, setSoftRangeMax);
#undef SET_VALUE_FROM_ANNOTATION
}
}
const MString uiName = fGLSLShaderInstance->uiName(parameterName, opStatus);
{
}
}
{
if (fGLSLShaderInstance == NULL)
{
return space;
}
MString ann = fGLSLShaderInstance->annotationAsString(parameterName, glslShaderAnnotation::kSpace, opStatus);
{
return space;
}
return space;
}
{
if (fGLSLShaderInstance == NULL)
{
return uniformSemantic;
}
MString sasSemantic = fGLSLShaderInstance->annotationAsString(parameterName, glslShaderAnnotation::kSasBindAddress, opStatus);
{
else if( sasSemantic.
rindexW( glslShaderAnnotationValue::k_Direction) >= 0 &&
}
{
const char* UIAnnotations[2] = { glslShaderAnnotation::kSasUiControl, glslShaderAnnotation::kUIWidget };
for (int i = 0; i < 2; ++i)
{
MString UiControl = fGLSLShaderInstance->annotationAsString(parameterName, UIAnnotations[i], opStatus);
if (opStatus ==
MStatus::kSuccess && UiControl.
length() && !MSTRICMP( UiControl, glslShaderAnnotationValue::kColorPicker))
{
break;
}
}
}
MString semantic = fGLSLShaderInstance->semantic(parameterName);
{
if ( parameterName.
rindexW( glslShaderAnnotationValue::kPosition) >= 0)
{
}
else if ( parameterName.
rindexW( glslShaderAnnotationValue::kDirection) >= 0 &&
parameterName.
rindexW( glslShaderAnnotationValue::kDirection) != parameterName.
rindexW( glslShaderAnnotationValue::kDirectional))
{
}
else if ( parameterName.
rindexW( glslShaderAnnotationValue::kColor) >= 0 ||
parameterName.
rindexW( glslShaderAnnotationValue::kColour) >= 0 ||
parameterName.
rindexW( glslShaderAnnotationValue::kDiffuse) >= 0 ||
parameterName.
rindexW( glslShaderAnnotationValue::kSpecular) >= 0 ||
parameterName.
rindexW( glslShaderAnnotationValue::kAmbient) >= 0)
{
}
}
return uniformSemantic;
}
void GLSLShaderNode::configureUniforms()
{
fUniformParameters.setLength(0);
deleteUniformUserData();
fUIGroupNames.setLength(0);
fUIGroupParameters.clear();
fGLSLShaderInstance->parameterList(unordedParams);
std::multimap<int, MString> orderedParams;
const unsigned int numParams = unordedParams.
length();
for (unsigned int i=0; i<numParams; ++i)
{
const MString& paramName = unordedParams[i];
int uiOrder = fGLSLShaderInstance->annotationAsInt(paramName, glslShaderAnnotation::kUIOrder, opStatus);
uiOrder = -1;
orderedParams.
insert( std::make_pair(uiOrder, paramName) );
}
bool useVariableNameAsAttributeName = true;
const MString useVariableNameAsAttributeNameValue = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kVariableNameAsAttributeName, opStatus);
useVariableNameAsAttributeName = ((STRICMP(useVariableNameAsAttributeNameValue.
asChar(), glslShaderAnnotationValue::kValueTrue)==0));
std::multimap<int, MString>::const_iterator it = orderedParams.begin();
std::multimap<int, MString>::const_iterator itEnd = orderedParams.end();
for(; it != itEnd; ++it)
{
const MString& paramName = it->second;
{
uniformSemantic = convertSpace(paramName, uniformSemantic);
}
{
uniformSemantic = guessUnknownSemantics(paramName);
}
const MString uiName = fGLSLShaderInstance->uiName(paramName, opStatus);
const MString uniformName = (useVariableNameAsAttributeName || uiName.
length() == 0 ? paramName : sanitizeName(uiName));
void* uniformUserData = NULL;
if( uniformName != paramName || !STRICMP( fGLSLShaderInstance->parameterSemantic(paramName, opStatus).asChar(), glslShaderSemantic::kShadowMap)
||!STRICMP( fGLSLShaderInstance->parameterSemantic(paramName, opStatus).asChar(), glslShaderSemantic::kPointLightShadowMap)) {
uniformUserData = createUniformUserData(paramName);
}
#ifdef _DEBUG_SHADER
printf(
"ParamName='%s', ParamType=", paramName.
asChar());
#endif
bool validParam = false;
bool isArray = fGLSLShaderInstance->isArrayParameter(paramName);
int arraySize = 1;
if (isArray)
{
arraySize = fGLSLShaderInstance->getArraySize(paramName);
}
switch (fGLSLShaderInstance->parameterType(paramName))
{
{
#ifdef _DEBUG_SHADER
printf("'Invalid'\n");
#endif
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Boolean'\n");
if (isArray)
{
printf("'Bool arrays are not supported properly'\n");
}
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 1, 1, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsBool(static_cast<bool*>(defaultValue)[0]);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Integer'\n");
if (isArray)
{
printf("'Integer arrays are not supported properly'\n");
}
#endif
const MString uiFieldNames = fGLSLShaderInstance->annotationAsString(paramName, glslShaderAnnotation::kUIFieldNames, opStatus);
{
}
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 1, 1, uniformUserData);
validParam = true;
{
uniParam.setEnumFieldNames(uiFieldNames);
}
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsInt(static_cast<int*>(defaultValue)[0]);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Float'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 1, arraySize, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsFloatArray(static_cast<float*>(defaultValue), arraySize);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Float2'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 2, arraySize, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsFloatArray(static_cast<float*>(defaultValue), arraySize * 2);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Float3'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 3, 1, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsFloatArray(static_cast<float*>(defaultValue),3);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Float4'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 4, 1, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsFloatArray(static_cast<float*>(defaultValue),4);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Float4x4Row'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 4, 4, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsFloatArray(static_cast<float*>(defaultValue),16);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Float4x4Col'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 4, 4, uniformUserData);
validParam = true;
void* defaultValue = fGLSLShaderInstance->parameterDefaultValue(paramName, opStatus);
if (defaultValue != NULL)
{
uniParam.setAsFloatArray(static_cast<float*>(defaultValue),16);
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Texture'\n");
#endif
uniParam =
MUniformParameter(uniformName, uniformDataType, uniformSemantic, 1, 1, uniformUserData);
validParam = true;
const MString resourceName = fGLSLShaderInstance->resourceName(paramName, opStatus);
{
{
uniParam.setAsString(resourceName);
}
{
uniParam.setAsString(fileObj.
rawPath() +
MString(
"/") + resourceName);
}
else
{
uniParam.setAsString(resourceName);
}
}
break;
}
{
#ifdef _DEBUG_SHADER
printf("'Sampler'\n");
#endif
validParam = true;
break;
}
default:
{
#ifdef _DEBUG_SHADER
printf("'Unknown'\n");
#endif
break;
}
}
if(validParam)
{
configureUniformUI(paramName, uniParam);
fUniformParameters.append(uniParam);
updateLightInfoFromSemantic(paramName, fUniformParameters.
length()-1);
}
}
setUniformParameters(fUniformParameters, true);
for(int i = 0; i < fUniformParameters.length(); ++i)
{
if (uniformPlug.isNull())
continue;
if (uniformAttribute.isHidden())
continue;
parameterName = getParameterName(uniformParam.
userData());
}
MString uiGroupName = fGLSLShaderInstance->annotationAsString(parameterName, glslShaderAnnotation::kUIGroup, opStatus);
uiGroupName = fGLSLShaderInstance->annotationAsString(parameterName, glslShaderAnnotation::kObject, opStatus);
}
{
int uiIndex = findInArray(fUIGroupNames, uiGroupName, true );
if( fUIGroupParameters.size() <= (unsigned int)uiIndex )
fUIGroupParameters.resize(uiIndex+1);
const MString uniformName = uniformAttribute.shortName();
findInArray(fUIGroupParameters[uiIndex], uniformName, true );
}
}
updateImplicitLightParameterCache();
}
void GLSLShaderNode::configureGeometryRequirements()
{
fVaryingParameters.setLength(0);
fVaryingParametersUpdateId = 0;
std::list<MVaryingParameter::MVaryingParameterSemantic> semanticUsage;
fGeometryRequirements.clear();
fGLSLShaderInstance->requiredVertexBuffers( fGeometryRequirements );
typedef std::map<MString, MString, MStringSorter> MapOfMString;
MapOfMString customSemantics;
{
MString customSemanticsAnno = fGLSLShaderInstance->techniqueAnnotationAsString(glslShaderAnnotation::kCustomSemantics, opStatus);
if( customSemanticsAnno.
length() > 0 )
{
customSemanticsAnno.
split(
':', allCustomSemantics);
for(
unsigned int i = 0; i < allCustomSemantics.
length(); ++i )
{
MString& oneCustomSemantic = allCustomSemantics[i];
oneCustomSemantic.
split(
'=', oneCustomSemanticValues);
if( oneCustomSemanticValues.
length() == 2 ) {
customSemantics[oneCustomSemanticValues[0]] = oneCustomSemanticValues[1];
}
}
}
}
const int nbReq = fGeometryRequirements.length();
for( int i = 0; i < nbReq; ++i )
{
fGeometryRequirements.getDescriptor(0, vbDesc);
bool useCustomSemantic = false;
MapOfMString::const_iterator it = customSemantics.find(semanticName);
if( it != customSemantics.end() ) {
semanticName = it->second;
useCustomSemantic = true;
}
{
break;
break;
break;
break;
break;
break;
break;
break;
default:
break;
}
{
uiName = glslShaderSemantic::kPosition;
break;
uiName = glslShaderSemantic::kNormal;
break;
if( dimension == 2 || useCustomSemantic )
{
uiName = glslShaderSemantic::kTexCoord;
}
else
{
uiName = glslShaderSemantic::kColor;
semanticName = "colorset";
}
break;
uiName = glslShaderSemantic::kColor;
break;
uiName = glslShaderSemantic::kTangent;
break;
uiName = glslShaderSemantic::kBinormal;
break;
default:
break;
}
const unsigned int usageCount = (unsigned int) std::count(semanticUsage.begin(), semanticUsage.end(), semantic);
uiName += usageCount;
sourceSet = "map";
sourceSet += (usageCount+1);
}
else {
sourceSet = "colorSet";
if( usageCount > 0 ) {
sourceSet += usageCount;
}
}
semanticUsage.push_back( semantic );
}
uiName,
dataType,
dimension,
dimension,
dimension,
semantic,
sourceSet,
false,
semanticName);
fVaryingParameters.append(varying);
fGeometryRequirements.removeAt(0);
fGeometryRequirements.append(vbDesc);
}
setVaryingParameters(fVaryingParameters, true);
}
bool GLSLShaderNode::hasUpdatedVaryingInput() const
{
unsigned int varyingUpdateId = 0;
for( int i = 0; i < fVaryingParameters.length(); ++i) {
}
return (fVaryingParametersUpdateId != varyingUpdateId);
}
void GLSLShaderNode::updateGeometryRequirements()
{
unsigned int varyingUpdateId = 0;
const int nbReq = fGeometryRequirements.length();
for( int i = 0; i < nbReq; ++i )
{
fGeometryRequirements.getDescriptor(0, vbDesc);
fGeometryRequirements.removeAt(0);
fGeometryRequirements.append(vbDesc);
}
fVaryingParametersUpdateId = varyingUpdateId;
}
{
return sProfile;
}
{
int alphaChannelIdx;
getTextureDesc(context, uniform, textureName, layerName, alphaChannelIdx);
parameterName = getParameterName(uniform.
userData());
}
int mipmaplevels = fTechniqueTextureMipmapLevels;
int readMipMapLevels = fGLSLShaderInstance->annotationAsInt(parameterName, glslShaderAnnotation::kMipmaplevels, opStatus);
{
mipmaplevels = readMipMapLevels;
}
return loadTexture(textureName, layerName, alphaChannelIdx, mipmaplevels);
}
{
return NULL;
if(theRenderer == NULL)
return NULL;
if(txtManager == NULL)
return NULL;
int idx = textureName.
rindexW(L
'.');
if(idx > 0)
{
}
bool isEXR = (extension == "exr");
#ifdef _DEBUG_SHADER
if(texture == NULL)
{
printf(
"-- Texture %s not found.\n", textureName.
asChar());
}
#endif
return texture;
}
{
if(!fGLSLShaderInstance)
return;
bool updateLightParameters = true;
if(renderType == RENDER_SCENE)
{
updateLightParameters = (currentFrameStamp != fLastFrameStamp);
if (updateLightParameters)
{
{
updateLightParameters = false;
}
else
{
fLastFrameStamp = currentFrameStamp;
}
}
}
else if(renderType == RENDER_SWATCH)
{
fLastFrameStamp = (MUint64)-1;
}
else
{
fLastFrameStamp = (MUint64)-1;
updateLightParameters = false;
}
bool updateTransparencyTextures = false;
if( renderType == RENDER_SCENE && techniqueIsTransparent() && techniqueSupportsAdvancedTransparency())
{
{
for (
unsigned int i = 0; i < passSemantics.
length() && !updateTransparencyTextures; ++i)
{
const MString& semantic = passSemantics[i];
{
updateTransparencyTextures = true;
}
}
}
}
std::set<int> lightParametersToUpdate;
if(updateLightParameters)
{
getLightParametersToUpdate(lightParametersToUpdate, renderType);
}
if(updateLightParameters)
{
updateExplicitLightConnections(context, renderType);
updateImplicitLightConnections(context, renderType);
}
for (int i = 0;i <fUniformParameters.length(); ++i)
{
if( currentUniform.
userData() != NULL ) {
parameterName = getParameterName(currentUniform.
userData());
}
if( currentUniform.
hasChanged(context) || lightParametersToUpdate.count(i) || (updateTransparencyTextures && currentUniform.
isATexture()) )
{
switch (currentUniform.
type())
{
{
int width, height;
const float data[] = { (float)width, (float)height };
fGLSLShaderInstance->setParameter(parameterName, data);
}
{
float data = status ? tuple[0] : 0.1f ;
fGLSLShaderInstance->setParameter(parameterName, data);
}
{
float data = status ? tuple[0] : 10000.0f ;
fGLSLShaderInstance->setParameter(parameterName, data);
}
else
{
bool isArray = fGLSLShaderInstance->isArrayParameter(parameterName);
if (isArray)
{
int arraySize = fGLSLShaderInstance->getArraySize(parameterName);
fGLSLShaderInstance->setArrayParameter(parameterName, data, arraySize);
}
else
{
fGLSLShaderInstance->setParameter(parameterName, data[0]);
else
fGLSLShaderInstance->setParameter(parameterName, data);
}
}
break;
fGLSLShaderInstance->setParameter(parameterName, currentUniform.
getAsInt(context));
break;
fGLSLShaderInstance->setParameter(parameterName, currentUniform.
getAsBool(context));
break;
break;
default:
{
if(updateTransparencyTextures) {
fGLSLShaderInstance->setParameter(parameterName, assignment);
}
}
if(updateTransparencyTextures) {
fGLSLShaderInstance->setParameter(parameterName, assignment);
}
bool releaseTexture = false;
if (currentUniform.
userData() != NULL) {
texture = getTexture(currentUniform.
userData());
}
if (!texture) {
texture = loadTexture(context, currentUniform);
releaseTexture = true;
}
assignment.texture = texture;
fGLSLShaderInstance->setParameter(parameterName, assignment);
if (releaseTexture && txtManager && texture) {
}
}
}
break;
}
}
}
}
{
if(!fGLSLShaderInstance)
return;
return;
renderItemDesc.isOverrideNonMaterialItem = true;
unsigned int size;
{
bool hasValidDefaultColor = false;
static const MString defaultColorParameter(
"defaultColor");
if(defaultColor && size == 4) {
static const MString solidColorUniform(
"gsSolidColor");
fGLSLShaderInstance->setParameter(solidColorUniform, defaultColor);
hasValidDefaultColor = true;
}
{
static const MString validSolidColorUniform(
"gsValidSolidColor");
fGLSLShaderInstance->setParameter(validSolidColorUniform, hasValidDefaultColor);
}
}
static const MString lineWidthParameter(
"lineWidth");
if(lineWidth && size == 2 && lineWidth[0] > 1.f && lineWidth[1] > 1.f) {
static const MString fatLineWidthUniform(
"gsFatLineWidth");
fGLSLShaderInstance->setParameter(fatLineWidthUniform, lineWidth);
renderItemDesc.isFatLine = true;
}
}
static const MString pointSizeParameter(
"pointSize");
if(pointSize && size == 2 && pointSize[0] > 1.f && pointSize[1] > 1.f) {
static const MString fatPointSizeUniform(
"gsFatPointSize");
fGLSLShaderInstance->setParameter(fatPointSizeUniform, pointSize);
renderItemDesc.isFatPoint = true;
}
}
fGLSLShaderInstance->updateParameters(context);
}
{
addExternalContentForFileAttr(table, sShader);
}
{
setExternalContentForFileAttr(sShader, table);
}
{
if (!fEffectLoaded)
{
}
}
{
MString uvLocalName = uvSetName==
"" ?
"map1" : uvSetName;
unsigned int nVarying = fVaryingParameters.
length();
for( unsigned int i = 0; i < nVarying; i++ ) {
}
}
attrName += "_DefaultTexture";
MPlug defaultTexPlug = depFn.findPlug( attrName ,
true);
if( !defaultTexPlug.
isNull() ) {
}
}
std::multimap<int, MString> sortedTextures;
std::vector<MString> unsortedTextures;
if( imageNames.
length() == 0 )
{
for( int i = 0; i < fUniformParameters.length(); i++ )
{
{
if (uniformPlug.isNull())
continue;
if (uniformAttribute.isHidden())
continue;
int uvEditorOrder = fGLSLShaderInstance->annotationAsInt(uniform.
name(),
MString(
"UVEditorOrder"), opStatus);
sortedTextures.insert(std::pair<int, MString>(uvEditorOrder, uniform.
name()));
}
else {
unsortedTextures.push_back(uniform.
name());
}
}
}
}
for (std::multimap<int, MString>::iterator itSorted = sortedTextures.begin();
itSorted != sortedTextures.end();
++itSorted)
{
MString &elemName(itSorted->second);
if( elemName == defaultTex ) {
imageNames.
insert( elemName, 0 );
} else {
imageNames.
append( elemName );
}
}
for (std::vector<MString>::iterator itOther = unsortedTextures.begin();
itOther != unsortedTextures.end();
++itOther)
{
if( elemName == defaultTex ) {
imageNames.
insert( elemName, 0 );
} else {
imageNames.
append( elemName );
}
}
}
{
if (!theRenderer)
for( int i = 0; i < fUniformParameters.length(); i++ ) {
imageParam = elem;
break;
}
}
if(texture == NULL)
{
}
{
imageWidth = (int)desc.
fWidth;
}
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 );
}
{
return m_TypeId;
}
bool GLSLShaderNode::reload()
{
EffectCollection::instance().unregisterBrokenEffect(this, fEffectName);
bool result = true;
EffectCollection::NodeSet_t allNodes;
EffectCollection::instance().getNodesUsingEffect(fEffectName, allNodes);
EffectCollection::NodeSet_t::iterator it = allNodes.begin();
EffectCollection::NodeSet_t::iterator itEnd = allNodes.end();
for(; it != itEnd; ++it)
{
GLSLShaderNode* node = *it;
result = node->loadEffect(fEffectName) && result;
}
refreshView();
return result;
}
void GLSLShaderNode::updateLightInfoFromSemantic(
const MString& parameterName,
int uniformParamIndex)
{
if (fGLSLShaderInstance == NULL)
{
return;
}
MString objectAnnotation = fGLSLShaderInstance->annotationAsString(parameterName, glslShaderAnnotation::kObject, opStatus);
int currentLightIndex = -1;
ELightType currentLightType = eUndefinedLight;;
ELightParameterType currentParamType = eUndefined;
bool hasLightTypeSemantic = false;
{
currentLightIndex = getIndexForLightName(objectAnnotation, true);
if(objectAnnotation.
rindexW(glslShaderAnnotationValue::kLight) >= 0 || objectAnnotation.
rindexW(glslShaderAnnotationValue::kLamp) >= 0)
{
currentLightType = eUndefinedLight;
if(objectAnnotation.
rindexW(glslShaderAnnotationValue::kPoint) >= 0)
{
currentLightType = ePointLight;
}
else if(objectAnnotation.
rindexW(glslShaderAnnotationValue::kSpot) >= 0)
{
currentLightType = eSpotLight;
}
else if(objectAnnotation.
rindexW(glslShaderAnnotationValue::kDirectional) >= 0)
{
currentLightType = eDirectionalLight;
}
else if(objectAnnotation.
rindexW(glslShaderAnnotationValue::kAmbient) >= 0)
{
currentLightType = eAmbientLight;
}
}
else
{
return;
}
}
else
{
return;
}
MString semanticValueRaw = fGLSLShaderInstance->parameterSemantic(parameterName, opStatus);
{
const char* semanticValue = semanticValueRaw.
asChar();
if( !STRICMP( semanticValue, glslShaderSemantic::kLightColor))
{
currentParamType = eLightColor;
}
if( !STRICMP( semanticValue, glslShaderSemantic::kLightEnable))
{
currentParamType = eLightEnable;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kLightIntensity))
{
currentParamType = eLightIntensity;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kLightFalloff) ||
!STRICMP( semanticValue, glslShaderSemantic::kFalloff))
{
currentLightType = eSpotLight;
currentParamType = eLightFalloff;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kLightDiffuseColor))
{
currentParamType = eLightDiffuseColor;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kLightAmbientColor))
{
currentParamType = eLightAmbientColor;
currentLightType = eAmbientLight;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kLightSpecularColor))
{
currentParamType = eLightSpecularColor;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kShadowMap))
{
currentParamType = eLightShadowMap;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kPointLightShadowMap))
{
currentParamType = ePointLightShadowMap;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kShadowMapBias))
{
currentParamType = eLightShadowMapBias;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kShadowFlag))
{
currentParamType = eLightShadowOn;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kShadowMapMatrix) ||
!STRICMP( semanticValue, glslShaderSemantic::kShadowMapXForm))
{
currentParamType = eLightShadowViewProj;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kShadowColor))
{
currentParamType = eLightShadowColor;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kHotspot))
{
currentParamType = eLightHotspot;
currentLightType = eSpotLight;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kLightType))
{
currentParamType = eLightType;
hasLightTypeSemantic = true;
}
else if (!STRICMP( semanticValue, glslShaderSemantic::kDecayRate))
{
currentParamType = eDecayRate;
}
else
{
bool isLight = (currentLightType != eInvalidLight || findSubstring(parameterName,
MString(glslShaderAnnotationValue::kLight)) >= 0);
if(isLight)
{
if( !STRICMP( semanticValue, glslShaderSemantic::kPosition))
{
currentParamType = eLightPosition;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kAreaPosition0))
{
currentParamType = eLightAreaPosition0;
currentLightType = eAreaLight;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kAreaPosition1))
{
currentParamType = eLightAreaPosition1;
currentLightType = eAreaLight;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kAreaPosition2))
{
currentParamType = eLightAreaPosition2;
currentLightType = eAreaLight;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kAreaPosition3))
{
currentParamType = eLightAreaPosition3;
currentLightType = eAreaLight;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kDirection))
{
currentParamType = eLightDirection;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kColor))
{
currentParamType = eLightColor;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kAmbient))
{
currentParamType = eLightAmbientColor;
currentLightType = eAmbientLight;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kDiffuse))
{
currentParamType = eLightDiffuseColor;
}
else if( !STRICMP( semanticValue, glslShaderSemantic::kSpecular))
{
currentParamType = eLightSpecularColor;
}
}
}
if(currentParamType != eUndefined && currentLightIndex == -1)
{
const char* objectName = parameterName.
asChar();
int truncationPos = -1;
int lightPos = findSubstring(parameterName,
MString(glslShaderAnnotationValue::kLight));
if (lightPos >= 0)
truncationPos = lightPos + 5;
if(truncationPos < 0)
{
unsigned int digitPos = 0;
for ( ; digitPos < parameterName.
numChars(); ++digitPos)
if ( isdigit(objectName[digitPos]) )
break;
if ( digitPos < parameterName.
numChars() )
truncationPos = digitPos;
}
if (truncationPos >= 0)
{
int maxChars = int(parameterName.
numChars());
while (truncationPos < maxChars && isdigit(objectName[truncationPos]))
++truncationPos;
currentLightIndex = getIndexForLightName(parameterName.
substring(0,truncationPos-1),
true);
}
}
}
if( currentParamType == eUndefined || currentLightIndex < 0)
return;
bool parameterFound = false;
for(unsigned int i = 0;i < fLightParameters.size();++i)
{
if (fLightParameters[i].mLightIndex == currentLightIndex)
{
fLightParameters[i].fConnectableParameters.insert(LightParameterInfo::TConnectableParameters::value_type(uniformParamIndex, currentParamType));
fLightParameters[i].fHasLightTypeSemantics |= hasLightTypeSemantic;
parameterFound = true;
break;
}
}
if (!parameterFound)
{
fLightParameters.push_back(LightParameterInfo(currentLightIndex, currentLightType, hasLightTypeSemantic));
fLightParameters[fLightParameters.size()-1].fConnectableParameters.insert(LightParameterInfo::TConnectableParameters::value_type(uniformParamIndex, currentParamType));
}
}
int GLSLShaderNode::getIndexForLightName(
const MString& lightName,
bool appendLight)
{
return findInArray(fLightNames, lightName, appendLight);
}
MStringArray GLSLShaderNode::getLightableParameters(
int lightIndex,
bool showSemantics)
{
if(lightIndex < (int)fLightParameters.size())
{
LightParameterInfo& currLight = fLightParameters[lightIndex];
for (LightParameterInfo::TConnectableParameters::const_iterator idxIter=currLight.fConnectableParameters.begin();
idxIter != currLight.fConnectableParameters.end();
++idxIter)
{
bool appended = appendParameterNameIfVisible((*idxIter).first, retVal);
if (appended && showSemantics) {
int paramType((*idxIter).second);
retVal.
append(getLightParameterSemantic(paramType));
}
}
}
return retVal;
}
bool GLSLShaderNode::appendParameterNameIfVisible(
int paramIndex,
MStringArray& paramArray)
const
{
if (uniformPlug.isNull())
return false;
if (uniformAttribute.isHidden())
return false;
paramArray.
append(uniformAttribute.shortName());
return true;
}
MString& GLSLShaderNode::getLightParameterSemantic(
int lightParameterType)
{
if (lightParameterType < 0 || lightParameterType >= eLastParameterType)
lightParameterType = eUndefined;
if (!semanticNames.
length()) {
semanticNames.
append(glslShaderSemantic::kUndefined);
semanticNames.
append(glslShaderSemantic::kPosition);
semanticNames.
append(glslShaderSemantic::kDirection);
semanticNames.
append(glslShaderSemantic::kLightColor);
semanticNames.
append(glslShaderSemantic::kLightSpecularColor);
semanticNames.
append(glslShaderSemantic::kLightAmbientColor);
semanticNames.
append(glslShaderSemantic::kLightDiffuseColor);
semanticNames.
append(glslShaderSemantic::kLightRange);
semanticNames.
append(glslShaderSemantic::kFalloff);
semanticNames.
append(glslShaderSemantic::kLightAttenuation0);
semanticNames.
append(glslShaderSemantic::kLightAttenuation1);
semanticNames.
append(glslShaderSemantic::kLightAttenuation2);
semanticNames.
append(glslShaderSemantic::kLightTheta);
semanticNames.
append(glslShaderSemantic::kLightPhi);
semanticNames.
append(glslShaderSemantic::kShadowMap);
semanticNames.
append(glslShaderSemantic::kPointLightShadowMap);
semanticNames.
append(glslShaderSemantic::kShadowMapBias);
semanticNames.
append(glslShaderSemantic::kShadowColor);
semanticNames.
append(glslShaderSemantic::kShadowMapMatrix);
semanticNames.
append(glslShaderSemantic::kShadowFlag);
semanticNames.
append(glslShaderSemantic::kLightIntensity);
semanticNames.
append(glslShaderSemantic::kHotspot);
semanticNames.
append(glslShaderSemantic::kLightEnable);
semanticNames.
append(glslShaderSemantic::kLightType);
semanticNames.
append(glslShaderSemantic::kDecayRate);
semanticNames.
append(glslShaderSemantic::kAreaPosition0);
semanticNames.
append(glslShaderSemantic::kAreaPosition1);
semanticNames.
append(glslShaderSemantic::kAreaPosition2);
semanticNames.
append(glslShaderSemantic::kAreaPosition3);
}
return semanticNames[lightParameterType];
}
void GLSLShaderNode::refreshLightConnectionAttributes(bool inSceneUpdateNotification)
{
{
for (size_t iLi=0; iLi<fLightParameters.size(); ++iLi)
{
LightParameterInfo& currLight(fLightParameters[iLi]);
MString sanitizedLightGroupName = sanitizeName(fLightNames[(
unsigned int)iLi]);
if (currLight.fAttrUseImplicit.isNull())
currLight.fAttrUseImplicit = fnDepThisNode.attribute(sanitizedLightGroupName + "_use_implicit_lighting");
if (currLight.fAttrUseImplicit.isNull())
{
MString attrName = sanitizedLightGroupName +
"_use_implicit_lighting";
if (!attrUseImplicit.
isNull())
{
status = implicitModifier.
addAttribute(thisMObject(), attrUseImplicit);
{
status = implicitModifier.
doIt();
{
currLight.fAttrUseImplicit = attrUseImplicit;
}
}
}
}
if (currLight.fAttrConnectedLight.isNull())
{
currLight.fAttrConnectedLight = fnDepThisNode.attribute(sanitizedLightGroupName + "_connected_light");;
}
if (currLight.fAttrConnectedLight.isNull())
{
MString attrName = sanitizedLightGroupName +
"_connected_light";
if (!attrConnectedLight.
isNull())
{
status = implicitModifier.
addAttribute(thisMObject(), attrConnectedLight);
{
status = implicitModifier.
doIt();
{
currLight.fAttrConnectedLight = attrConnectedLight;
}
}
}
}
}
}
else
{
PostSceneUpdateAttributeRefresher::add(this);
}
}
void GLSLShaderNode::updateImplicitLightConnections(
const MHWRender::MDrawContext& context, ERenderType renderType)
const
{
if(renderType != RENDER_SCENE && renderType != RENDER_SWATCH)
return;
bool ignoreLightLimit = true;
if (ignoreLightLimit)
{
}
unsigned int nbSceneLightsToBind = nbSceneLights;
bool implicitLightWasRebound = false;
if(renderType == RENDER_SCENE && nbSceneLights == 1)
{
const ELightType sceneLightType = getLightType(sceneLightParam);
if(sceneLightType == GLSLShaderNode::eDefaultLight )
{
renderType = RENDER_SCENE_DEFAULT_LIGHT;
}
}
unsigned int nbShaderLights = (unsigned int)fLightParameters.size();
unsigned int nbShaderLightsToBind = nbShaderLights;
std::vector<bool> shaderLightTreated(nbShaderLights, false);
std::vector<bool> shaderLightUsesImplicit(nbShaderLights, false);
std::vector<bool> sceneLightUsed(nbSceneLights, false);
if(renderType == RENDER_SCENE)
{
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind && nbSceneLightsToBind;
++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
MPlug thisLightConnectionPlug = depFn.findPlug(shaderLightInfo.fAttrConnectedLight,
true);
{
thisLightConnectionPlug.
connectedTo(srcCnxArray,
true,
false);
{
MPlug sourcePlug = srcCnxArray[0];
for(unsigned int sceneLightIndex = 0; sceneLightIndex < nbSceneLights; ++sceneLightIndex)
{
{
sceneLightUsed[sceneLightIndex] = true;
nbSceneLightsToBind--;
}
}
if (!shaderLightInfo.fCachedImplicitLight.isNull())
{
(
const_cast<LightParameterInfo&
>(shaderLightInfo)).fCachedImplicitLight =
MObject();
setLightParameterLocking(shaderLightInfo, true);
implicitLightWasRebound = true;
}
}
}
}
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind;
++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
MPlug useImplicitPlug = depFn.findPlug( shaderLightInfo.fAttrUseImplicit,
false );
if( !useImplicitPlug.
isNull() ) {
bool useImplicit;
useImplicitPlug.
getValue( useImplicit );
shaderLightUsesImplicit[shaderLightIndex] = useImplicit;
if (useImplicit)
{
if (!shaderLightInfo.fCachedImplicitLight.isNull())
{
MFnDagNode lightDagNode(shaderLightInfo.fCachedImplicitLight, &status);
unsigned int sceneLightIndex = 0;
for( ; sceneLightIndex < nbSceneLights; ++sceneLightIndex)
{
if( sceneLightParam->
lightPath().
node() == shaderLightInfo.fCachedImplicitLight )
{
matchingSceneLightParam = sceneLightParam;
break;
}
}
if (matchingSceneLightParam)
{
if (!sceneLightUsed[sceneLightIndex])
{
connectLight(shaderLightInfo, matchingSceneLightParam);
sceneLightUsed[sceneLightIndex] = true;
nbSceneLightsToBind--;
shaderLightTreated[shaderLightIndex] = true;
nbShaderLightsToBind--;
}
else
{
setLightRequiresShadows(shaderLightInfo.fCachedImplicitLight, false);
(
const_cast<LightParameterInfo&
>(shaderLightInfo)).fCachedImplicitLight =
MObject();
setLightParameterLocking(shaderLightInfo, false);
implicitLightWasRebound = true;
}
}
else
{
turnOffLight(shaderLightInfo);
shaderLightTreated[shaderLightIndex] = true;
nbShaderLightsToBind--;
}
}
else
{
(
const_cast<LightParameterInfo&
>(shaderLightInfo)).fCachedImplicitLight =
MObject();
setLightParameterLocking(shaderLightInfo, false);
implicitLightWasRebound = true;
}
}
}
else
{
nbShaderLightsToBind--;
}
}
}
}
else
{
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind && nbSceneLightsToBind;
++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
MPlug thisLightConnectionPlug = depFn.findPlug(shaderLightInfo.fAttrConnectedLight,
true);
bool useImplicit = true;
MPlug useImplicitPlug = depFn.findPlug( shaderLightInfo.fAttrUseImplicit,
false );
if( !useImplicitPlug.
isNull() ) {
useImplicitPlug.
getValue( useImplicit );
}
if (thisLightConnectionPlug.
isConnected() || useImplicit || renderType == RENDER_SCENE_DEFAULT_LIGHT )
{
shaderLightUsesImplicit[shaderLightIndex] = true;
}
else
{
nbShaderLightsToBind--;
}
}
}
if(renderType == RENDER_SCENE)
fImplicitAmbientLight = -1;
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind && nbSceneLightsToBind;
++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
const ELightType shaderLightType = shaderLightInfo.mLightType;
if(!shaderLightUsesImplicit[shaderLightIndex] || shaderLightTreated[shaderLightIndex] == true)
continue;
for(unsigned int sceneLightIndex = 0; sceneLightIndex < nbSceneLights; ++sceneLightIndex)
{
if(sceneLightUsed[sceneLightIndex] == true)
continue;
const ELightType sceneLightType = getLightType(sceneLightParam);
if( shaderLightType == sceneLightType || shaderLightInfo.fHasLightTypeSemantics )
{
connectLight(shaderLightInfo, sceneLightParam, renderType);
shaderLightTreated[shaderLightIndex] = true;
nbShaderLightsToBind--;
if (renderType != RENDER_SWATCH || shaderLightInfo.fHasLightTypeSemantics)
{
sceneLightUsed[sceneLightIndex] = true;
nbSceneLightsToBind--;
}
if(renderType == RENDER_SCENE)
{
setLightRequiresShadows(shaderLightInfo.fCachedImplicitLight, true);
(
const_cast<LightParameterInfo&
>(shaderLightInfo)).fCachedImplicitLight = sceneLightParam->
lightPath().
node();
setLightParameterLocking(shaderLightInfo, true);
implicitLightWasRebound = true;
if (sceneLightType == eAmbientLight && fImplicitAmbientLight < 0)
fImplicitAmbientLight = shaderLightIndex;
}
else
{
(const_cast<LightParameterInfo&>(shaderLightInfo)).fIsDirty = true;
}
break;
}
}
}
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind && nbSceneLightsToBind;
++shaderLightIndex )
{
if(!shaderLightUsesImplicit[shaderLightIndex] || shaderLightTreated[shaderLightIndex] == true)
continue;
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
const ELightType shaderLightType = shaderLightInfo.mLightType;
for(unsigned int sceneLightIndex = 0; sceneLightIndex < nbSceneLights; ++sceneLightIndex)
{
if(sceneLightUsed[sceneLightIndex] == true)
continue;
const ELightType sceneLightType = getLightType(sceneLightParam);
if( isLightAcceptable(shaderLightType, sceneLightType) )
{
connectLight(shaderLightInfo, sceneLightParam, renderType);
shaderLightTreated[shaderLightIndex] = true;
nbShaderLightsToBind--;
if (renderType != RENDER_SWATCH || shaderLightInfo.fHasLightTypeSemantics)
{
sceneLightUsed[sceneLightIndex] = true;
nbSceneLightsToBind--;
}
if(renderType == RENDER_SCENE)
{
(
const_cast<LightParameterInfo&
>(shaderLightInfo)).fCachedImplicitLight = sceneLightParam->
lightPath().
node();
setLightParameterLocking(shaderLightInfo, true);
implicitLightWasRebound = true;
setLightRequiresShadows(shaderLightInfo.fCachedImplicitLight, true);
}
else
{
(const_cast<LightParameterInfo&>(shaderLightInfo)).fIsDirty = true;
}
break;
}
}
}
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind;
++shaderLightIndex )
{
if(!shaderLightUsesImplicit[shaderLightIndex] || shaderLightTreated[shaderLightIndex] == true)
continue;
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
turnOffLight(shaderLightInfo);
if(renderType != RENDER_SCENE)
{
(const_cast<LightParameterInfo&>(shaderLightInfo)).fIsDirty = true;
}
}
if (implicitLightWasRebound)
IdleAttributeEditorImplicitRefresher::activate();
}
void GLSLShaderNode::updateImplicitLightParameterCache()
{
if ( updateConnectionAttributes ) {
if ( fLightParameters.size() == fLightNames.length() )
{
updateConnectionAttributes = false;
for (size_t iLi=0; iLi<fLightParameters.size(); ++iLi) {
MString newName = sanitizeName(fLightNames[(
unsigned int)iLi]) +
"_use_implicit_lighting";
MFnAttribute currentAttribute(fLightParameters[iLi].fAttrUseImplicit, &status);
updateConnectionAttributes = true;
break;
}
}
}
}
if ( updateConnectionAttributes ) {
for (size_t iLi=0; iLi<fLightParameters.size(); ++iLi)
{
if(fLightParameters[iLi].fAttrUseImplicit.isNull() == false)
implicitModifier.
removeAttribute(thisMObject(), fLightParameters[iLi].fAttrUseImplicit);
if(fLightParameters[iLi].fAttrConnectedLight.isNull() == false)
implicitModifier.
removeAttribute(thisMObject(), fLightParameters[iLi].fAttrConnectedLight);
}
}
refreshLightConnectionAttributes();
fLightDescriptions.clear();
LightParameterInfoVec::iterator iterLight = fLightParameters.begin();
unsigned int lightIndex = 0;
for(;iterLight != fLightParameters.end();++iterLight, ++lightIndex)
{
fLightDescriptions.append(fLightNames[lightIndex]);
static const MString kInvalid(
"invalid");
static const MString kUndefined(
"undefined");
static const MString kSpot(
"spot");
static const MString kPoint(
"point");
static const MString kDirectional(
"directional");
static const MString kAmbient(
"ambient");
static const MString kArea(
"area");
switch(iterLight->mLightType)
{
case eUndefinedLight:
lightType = kUndefined;
break;
case eSpotLight:
lightType = kSpot;
break;
case ePointLight:
lightType = kPoint;
break;
case eDirectionalLight:
lightType = kDirectional;
break;
case eAmbientLight:
lightType = kAmbient;
break;
case eAreaLight:
lightType = kArea;
break;
default:
break;
};
fLightDescriptions.append(lightType);
}
}
void GLSLShaderNode::updateExplicitLightConnections(
const MHWRender::MDrawContext& context, ERenderType renderType)
const
{
if(renderType != RENDER_SCENE)
return;
unsigned int nbShaderLights = (unsigned int)fLightParameters.size();
if(nbShaderLights == 0)
return;
bool ignoreLightLimit = true;
if (ignoreLightLimit)
{
}
for(size_t shaderLightIndex = 0; shaderLightIndex <nbShaderLights; ++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
MPlug thisLightConnectionPlug = thisDependNode.
findPlug(shaderLightInfo.fAttrConnectedLight,
true);
{
thisLightConnectionPlug.
connectedTo(srcCnxArray,
true,
false);
{
MPlug sourcePlug = srcCnxArray[0];
bool bHasAmbient = false;
bool bLightEnabled = false;
unsigned int sceneLightIndex = 0;
for(; sceneLightIndex < nbSceneLights; ++sceneLightIndex)
{
{
setLightRequiresShadows(sourceLight, true);
connectLight(shaderLightInfo, sceneLightParam);
static MString kLightOn(
"lightOn");
bLightEnabled = (floatVals.
length() == 0 || floatVals[0] > 0) ?
true :
false;
break;
}
if (eAmbientLight == getLightType(sceneLightParam))
{
bHasAmbient = true;
bLightEnabled = true;
}
}
if (bHasAmbient && sceneLightIndex == nbSceneLights)
bLightEnabled = connectExplicitAmbientLight(shaderLightInfo, sourceLight);
if (!bLightEnabled)
{
turnOffLight(shaderLightInfo);
}
}
}
}
}
bool GLSLShaderNode::connectExplicitAmbientLight(
const LightParameterInfo& lightInfo,
const MObject& sourceLight)
const
{
bool bDidConnect = false;
{
{
bDidConnect = true;
LightParameterInfo::TConnectableParameters::const_iterator it = lightInfo.fConnectableParameters.begin();
LightParameterInfo::TConnectableParameters::const_iterator itEnd = lightInfo.fConnectableParameters.end();
for (; it != itEnd; ++it)
{
const int parameterIndex = it->first;
const int parameterType = it->second;
switch (parameterType)
{
case eLightType:
fUniformParameters.getElement(parameterIndex).setAsInt((int)eAmbientLight);
break;
case eLightEnable:
fUniformParameters.getElement(parameterIndex).setAsBool(true);
break;
case eLightColor:
case eLightAmbientColor:
case eLightSpecularColor:
case eLightDiffuseColor:
{
MColor ambientColor(ambientLight.color());
float color[3];
fUniformParameters.getElement(parameterIndex).setAsFloatArray(color, 3);
}
break;
case eLightIntensity:
fUniformParameters.getElement(parameterIndex).setAsFloat(ambientLight.intensity());
break;
}
}
}
}
return bDidConnect;
}
void GLSLShaderNode::connectLight(
int lightIndex,
MDagPath lightPath)
{
if(lightIndex < (int)fLightParameters.size())
{
LightParameterInfo& currLight = fLightParameters[lightIndex];
MPlug paramPlug(thisMObject(),currLight.fAttrConnectedLight);
{
currLight.fIsDirty = true;
setLightParameterLocking(currLight, true);
currLight.fCachedImplicitLight =
MObject();
MPlug useImplicitPlug(thisMObject(), currLight.fAttrUseImplicit);
if( !useImplicitPlug.
isNull() ) {
}
refreshView();
}
}
}
void GLSLShaderNode::refreshView() const
{
{
}
}
void GLSLShaderNode::setLightParameterLocking(const LightParameterInfo& lightInfo, bool locked, bool refreshAE) const
{
for (LightParameterInfo::TConnectableParameters::const_iterator idxIter=lightInfo.fConnectableParameters.begin();
idxIter != lightInfo.fConnectableParameters.end();
++idxIter)
{
int parameterIndex((*idxIter).first);
if (!uniformPlug.isNull())
{
if (!uniformAttribute.isHidden()) {
uniformPlug.setLocked(locked);
if( refreshAE ) {
}
}
}
}
}
void GLSLShaderNode::turnOffLight(const LightParameterInfo& lightInfo) const
{
static const float kOffColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
LightParameterInfo::TConnectableParameters::const_iterator it;
for (it = lightInfo.fConnectableParameters.begin();
it != lightInfo.fConnectableParameters.end(); ++it)
{
const int parameterIndex = it->first;
const int parameterType = it->second;
switch (parameterType)
{
case eLightEnable:
fUniformParameters.getElement(parameterIndex).setAsBool(false);
break;
case eLightColor:
case eLightAmbientColor:
case eLightSpecularColor:
case eLightDiffuseColor:
fUniformParameters.getElement(parameterIndex).setAsFloatArray((float*)kOffColor,4);
break;
case eLightIntensity:
fUniformParameters.getElement(parameterIndex).setAsFloat(0.0f);
break;
}
}
}
{
unsigned int positionCount = 0;
float intensity = 1.0f;
float decayRate = 0.0f;
MColor color(1.0f, 1.0f, 1.0f);
bool globalShadowsOn = false;
bool localShadowsOn = false;
bool releaseShadowResource = true;
bool releaseShadowResource1 = true;
float shadowBias = 0.0f;
ELightType lightType = getLightType(lightParam);
LightParameterInfo::TConnectableParameters::const_iterator it = lightInfo.fConnectableParameters.begin();
LightParameterInfo::TConnectableParameters::const_iterator itEnd = lightInfo.fConnectableParameters.end();
for (; it != itEnd; ++it)
{
const int parameterIndex = it->first;
const int parameterType = it->second;
if (parameterType == eLightType) {
fUniformParameters.getElement(parameterIndex).setAsInt(lightType != eDefaultLight? (int)lightType : eDirectionalLight);
continue;
}
if (parameterType == eLightEnable) {
fUniformParameters.getElement(parameterIndex).setAsBool(true);
continue;
}
const MStringArray& params(drawContextParameterNames(lightType, parameterType, lightParam));
{
if (parameterType == eLightShadowOn)
{
fUniformParameters.getElement(parameterIndex).setAsBool(false);
}
continue;
}
for (
unsigned int p = 0; p < params.
length(); ++p)
{
switch (semantic)
{
position +=
MFloatPoint( floatVals[0], floatVals[1], floatVals[2] );
++positionCount;
break;
direction =
MFloatVector( floatVals[0], floatVals[1], floatVals[2] );
break;
intensity = floatVals[0];
break;
decayRate = floatVals[0];
break;
color[0] = floatVals[0];
color[1] = floatVals[1];
color[2] = floatVals[2];
break;
globalShadowsOn = (intVals[0] != 0) ? true : false;
break;
localShadowsOn = (intVals[0] != 0) ? true : false;
break;
break;
if ((shadowResource.texture == NULL)&&(parameterType == eLightShadowMap)&& (lightType != ePointLight))
{
}
if ((shadowResource1.texture == NULL)&&(parameterType == ePointLightShadowMap) && (lightType == ePointLight))
{
}
break;
shadowColor[0] = floatVals[0];
shadowColor[1] = floatVals[1];
shadowColor[2] = floatVals[2];
break;
shadowBias = floatVals[0];
break;
break;
default:
break;
}
}
if (positionCount > 1)
{
position[0] /= (float)positionCount;
position[1] /= (float)positionCount;
position[2] /= (float)positionCount;
}
switch (parameterType)
{
case eLightColor:
case eLightAmbientColor:
case eLightSpecularColor:
case eLightDiffuseColor:
{
if (renderType != RENDER_SCENE && lightInfo.mLightType == eAmbientLight)
{
color[0] *= 0.15f;
color[1] *= 0.15f;
color[2] *= 0.15f;
}
fUniformParameters.getElement(parameterIndex).setAsFloatArray((float*)&color[0], 3);
}
break;
case eLightPosition:
case eLightAreaPosition0:
case eLightAreaPosition1:
case eLightAreaPosition2:
case eLightAreaPosition3:
fUniformParameters.getElement(parameterIndex).setAsFloatArray((float*)&position[0], 3);
positionCount = 0;
break;
case eLightIntensity:
fUniformParameters.getElement(parameterIndex).setAsFloat(intensity);
break;
case eDecayRate:
fUniformParameters.getElement(parameterIndex).setAsFloat(decayRate);
break;
case eLightDirection:
fUniformParameters.getElement(parameterIndex).setAsFloatArray((float*)&direction[0], 3);
break;
case eLightShadowMapBias:
fUniformParameters.getElement(parameterIndex).setAsFloat(shadowBias);
break;
case eLightShadowColor:
fUniformParameters.getElement(parameterIndex).setAsFloatArray((float*)&shadowColor[0], 3);
break;
case eLightShadowOn:
{
bool localShadowsDirty = false;
localShadowsDirty = (intVals[0] != 0) ? true : false;
fUniformParameters.getElement(parameterIndex).setAsBool(globalShadowsOn && localShadowsOn && !localShadowsDirty);
break;
}
case eLightShadowViewProj:
float matrix[4][4];
shadowViewProj.
get(matrix);
fUniformParameters.getElement(parameterIndex).setAsFloatArray((float*)&matrix[0], 16);
break;
case eLightShadowMap:
{
UniformUserData* userData = (UniformUserData*)fUniformParameters.getElement(parameterIndex).userData();
if (userData && (lightType != ePointLight))
{
if (txtManager && userData->fTexture) {
}
userData->fTexture = shadowResource.texture;
releaseShadowResource = false;
fUniformParameters.getElement(parameterIndex).setDirty();
} else {
userData->fTexture = NULL;
fUniformParameters.getElement(parameterIndex).setDirty();
}
break;
}
case ePointLightShadowMap:
{
UniformUserData* userData = (UniformUserData*)fUniformParameters.getElement(parameterIndex).userData();
if (userData && (lightType == ePointLight))
{
if (txtManager && userData->fTexture) {
}
userData->fTexture = shadowResource1.texture;
releaseShadowResource1 = false;
fUniformParameters.getElement(parameterIndex).setDirty();
} else {
userData->fTexture = NULL;
fUniformParameters.getElement(parameterIndex).setDirty();
}
break;
}
case eLightHotspot:
fUniformParameters.getElement(parameterIndex).setAsFloat(float(hotspot.asRadians()));
break;
case eLightFalloff:
fUniformParameters.getElement(parameterIndex).setAsFloat(float(falloff.asRadians()));
break;
default:
break;
}
}
if(releaseShadowResource && txtManager && shadowResource.texture) {
}
if(releaseShadowResource1 && txtManager && shadowResource1.texture) {
}
}
void GLSLShaderNode::disconnectLight(int lightIndex)
{
if(lightIndex < (int)fLightParameters.size())
{
LightParameterInfo& currLight = fLightParameters[lightIndex];
currLight.fIsDirty = true;
setLightParameterLocking(currLight, false);
setLightRequiresShadows(currLight.fCachedImplicitLight, false);
currLight.fCachedImplicitLight =
MObject();
{
MPlug thisLightConnectionPlug = thisDependNode.
findPlug(currLight.fAttrConnectedLight,
true);
{
thisLightConnectionPlug.
connectedTo(srcCnxArray,
true,
false);
{
MPlug sourcePlug = srcCnxArray[0];
DG.
disconnect(sourcePlug, thisLightConnectionPlug);
setLightRequiresShadows(sourcePlug.
node(),
false);
refreshView();
}
}
}
}
}
void GLSLShaderNode::setLightRequiresShadows(
const MObject& lightObject,
bool requiresShadow)
const
{
{
}
}
{
for(size_t shaderLightIndex = 0; shaderLightIndex < fLightParameters.size(); ++shaderLightIndex )
{
LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
MPlug implicitLightPlug(thisMObject(), shaderLightInfo.fAttrUseImplicit);
if ( implicitLightPlug == plugBeingDirtied ) {
shaderLightInfo.fIsDirty = true;
}
MPlug connectedLightPlug(thisMObject(), shaderLightInfo.fAttrConnectedLight);
if ( connectedLightPlug == plugBeingDirtied ) {
shaderLightInfo.fIsDirty = true;
}
}
}
void GLSLShaderNode::getLightParametersToUpdate(std::set<int>& parametersToUpdate, ERenderType renderType) const
{
for(size_t shaderLightIndex = 0; shaderLightIndex < fLightParameters.size(); ++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
bool needUpdate = (shaderLightInfo.fIsDirty || renderType != RENDER_SCENE);
if(!needUpdate) {
MPlug thisLightConnectionPlug = thisDependNode.
findPlug(shaderLightInfo.fAttrConnectedLight,
true);
}
if (needUpdate)
{
LightParameterInfo::TConnectableParameters::const_iterator it = shaderLightInfo.fConnectableParameters.begin();
LightParameterInfo::TConnectableParameters::const_iterator itEnd = shaderLightInfo.fConnectableParameters.end();
for (; it != itEnd; ++it)
{
parametersToUpdate.insert(it->first);
}
if (renderType == RENDER_SCENE)
{
MPlug useImplicitPlug = depFn.findPlug( shaderLightInfo.fAttrUseImplicit,
false );
if( !useImplicitPlug.
isNull() ) {
bool useImplicit;
useImplicitPlug.
getValue( useImplicit );
if (!useImplicit)
{
(const_cast<LightParameterInfo&>(shaderLightInfo)).fIsDirty = false;
}
}
}
}
}
}
void GLSLShaderNode::clearLightConnectionData(bool refreshAE)
{
for (size_t i = 0; i < fLightParameters.size(); ++i) {
fLightParameters[i].fCachedImplicitLight =
MObject();
setLightParameterLocking(fLightParameters[i], false, refreshAE);
}
fLightNames.setLength(0);
fLightDescriptions.setLength(0);
}
MString GLSLShaderNode::getLightConnectionInfo(
int lightIndex)
{
if(lightIndex < (int)fLightParameters.size())
{
LightParameterInfo& currLight = fLightParameters[lightIndex];
MPlug thisLightConnectionPlug = thisDependNode.
findPlug(currLight.fAttrConnectedLight,
true);
{
thisLightConnectionPlug.
connectedTo(srcCnxArray,
true,
false);
{
MPlug sourcePlug = srcCnxArray[0];
return sourceTransform.name();
}
}
MPlug useImplicitPlug = thisDependNode.
findPlug( currLight.fAttrUseImplicit,
false );
if( !useImplicitPlug.
isNull() ) {
bool useImplicit;
useImplicitPlug.
getValue( useImplicit );
if (useImplicit)
{
if (!currLight.fCachedImplicitLight.isNull())
{
MFnDagNode lightDagNode(currLight.fCachedImplicitLight, &status);
return cachedTransform.
name();
}
}
else if (lightIndex == fImplicitAmbientLight)
return glslShaderStrings::getString( glslShaderStrings::kAmbient );
}
}
}
return "";
}
{
for (unsigned int passIndex = 0; passIndex < fTechniquePassCount; ++passIndex)
{
if( passHandlesContext(context, passIndex) )
return true;
}
return false;
}
bool GLSLShaderNode::passHandlesContext(
MHWRender::MDrawContext& context,
unsigned int passIndex,
const RenderItemDesc* renderItemDesc)
const
{
PassSpecMap::const_iterator it = fTechniquePassSpecs.find(passIndex);
if (it == fTechniquePassSpecs.end())
return false;
const PassSpec& passSpec = it->second;
bool isHandled = false;
for (
unsigned int passSemIdx = 0; passSemIdx < passSemantics.
length() && !isHandled; ++passSemIdx)
{
const MString& semantic = passSemantics[passSemIdx];
if (isColorPass)
{
{
if(renderItemDesc && renderItemDesc->isOverrideNonMaterialItem)
{
isHandled = (STRICMP(passSpec.drawContext.asChar(), glslShaderAnnotation::kNonMaterialItemsPass) == 0);
}
else
{
isHandled = (passSpec.drawContext.length() == 0) || (STRICMP(semantic.
asChar(), passSpec.drawContext.asChar()) == 0);
}
}
}
else
{
isHandled = (STRICMP(semantic.
asChar(), passSpec.drawContext.asChar()) == 0);
}
if (isHandled && renderItemDesc && renderItemDesc->isOverrideNonMaterialItem)
{
if (renderItemDesc->isFatLine)
{
if (!passSpec.forFatLine)
{
const PassSpec passSpecTest = { passSpec.drawContext, true, false };
isHandled = (findMatchingPass(context, passSpecTest) == (unsigned int)-1);
}
}
else if (renderItemDesc->isFatPoint)
{
if (!passSpec.forFatPoint)
{
const PassSpec passSpecTest = { passSpec.drawContext, false, true };
isHandled = (findMatchingPass(context, passSpecTest) == (unsigned int)-1);
}
}
else
{
isHandled = (!passSpec.forFatLine && !passSpec.forFatPoint);
}
}
}
return isHandled;
}
unsigned int GLSLShaderNode::findMatchingPass(
MHWRender::MDrawContext& context,
const PassSpec& passSpecTest)
const
{
PassSpecMap::const_iterator it = fTechniquePassSpecs.
begin();
PassSpecMap::const_iterator itEnd = fTechniquePassSpecs.end();
for(; it != itEnd; ++it)
{
const PassSpec& passSpec = it->second;
if( passSpec.forFatLine == passSpecTest.forFatLine &&
passSpec.forFatPoint == passSpecTest.forFatPoint &&
STRICMP(passSpec.drawContext.asChar(), passSpecTest.drawContext.asChar()) == 0)
{
return it->first;
}
}
return (unsigned int) -1;
}
MStringArray GLSLShaderNode::getUIGroupParameters(
int uiGroupIndex)
const
{
if(uiGroupIndex >= 0 && (unsigned int)uiGroupIndex < fUIGroupParameters.size())
return fUIGroupParameters[(unsigned int)uiGroupIndex];
}
int GLSLShaderNode::getIndexForUIGroupName(
const MString& uiGroupName)
const
{
return findInArray(const_cast<MStringArray&>(fUIGroupNames), uiGroupName, false );
}
void GLSLShaderNode::deleteUniformUserData()
{
std::vector<UniformUserData*>::iterator it = fUniformUserData.begin();
std::vector<UniformUserData*>::iterator itEnd = fUniformUserData.end();
for(; it != itEnd; ++it) {
if (txtManager && (*it)->fTexture) {
}
delete *it;
}
fUniformUserData.clear();
}
void* GLSLShaderNode::createUniformUserData(
const MString& parameterName)
{
UniformUserData* newData = new UniformUserData(parameterName);
fUniformUserData.push_back(newData);
return (void*)newData;
}
const MString& GLSLShaderNode::getParameterName(
void* userData)
const
{
return ((UniformUserData*)userData)->fParameterName;
}
{
return ((UniformUserData*)userData)->fTexture;
}