#if _MSC_VER >= 1700
#pragma warning( disable: 4005 )
#endif
#include "dx11Shader.h"
#include "dx11ShaderStrings.h"
#include "dx11ShaderCompileHelper.h"
#include "dx11ShaderUniformParamBuilder.h"
#include "dx11ConeAngleToHotspotConverter.h"
#include "crackFreePrimitiveGenerator.h"
#include "dx11ShaderSemantics.h"
#include <maya/MGlobal.h>
#include <maya/MFileIO.h>
#include <maya/MString.h>
#include <maya/MFnAmbientLight.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnStringData.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/MVaryingParameter.h>
#include <maya/MUniformParameter.h>
#include <maya/MRenderProfile.h>
#include <maya/MGeometryList.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 <maya/MHardwareRenderer.h>
#include <maya/MGLFunctionTable.h>
#include <maya/M3dView.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <stdio.h>
#define M_CHECK(assertion) if (assertion) ; else throw ((dx11Shader::InternalError*)__LINE__)
namespace dx11Shader
{
struct InternalError
{
char* message;
};
}
namespace
{
static MObject sEffectUniformParameters;
{
str.
set((
double)value, 0);
return str;
}
MString MStringFromUInt(
unsigned int value)
{
str.
set((
double)value, 0);
return str;
}
struct MUniformParameterData
{
unsigned int numElements;
};
struct MStringSorter
{
{
}
};
typedef std::set<MString, MStringSorter> SetOfMString;
{
std::string retVal(dirtyName.
asChar());
for (size_t i=0; i<retVal.size(); ++i)
if (!isalnum(retVal[i]))
retVal.replace(i, 1, "_");
}
{
std::string str(str_.
asChar());
std::string from(from_.
asChar());
std::size_t start = str.find(from);
while(start != std::string::npos)
{
std::size_t len = from.size();
std::size_t end = start + len;
if( ( start > 0 && isalnum(str.at(start-1)) ) ||
( end < (str.size() - 1) && isalnum(str.at(end+1)) ) )
{
start = str.find(from, end);
continue;
}
str.replace(start, len, to);
start = str.find(from, start + to.size());
}
}
class PostSceneUpdateAttributeRefresher
{
public:
static void add(dx11ShaderNode* node)
{
if (sInstance == NULL)
sInstance = new PostSceneUpdateAttributeRefresher();
sInstance->mNodeSet.insert(node);
};
static void remove(dx11ShaderNode* 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<dx11ShaderNode*> TNodeSet;
TNodeSet mNodeSet;
MCallbackId mSceneUpdateCallback;
MCallbackId mAfterCreateReference;
MCallbackId mAfterImport;
MCallbackId mAfterLoadReference;
static PostSceneUpdateAttributeRefresher *sInstance;
};
PostSceneUpdateAttributeRefresher *PostSceneUpdateAttributeRefresher::sInstance = NULL;
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;
template <typename ResourceType>
bool getNumAnnotations(ResourceType *resource, uint32_t *numAnnotation)
{
return false;
}
template <>
bool getNumAnnotations<ID3DX11EffectVariable>(ID3DX11EffectVariable *resource, uint32_t *numAnnotation)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
resource->GetDesc(&varDesc);
*numAnnotation = varDesc.Annotations;
return true;
}
template <>
bool getNumAnnotations<ID3DX11EffectShaderResourceVariable>(ID3DX11EffectShaderResourceVariable *resource, uint32_t *numAnnotation)
{
return getNumAnnotations<ID3DX11EffectVariable>(resource, numAnnotation);
}
template <>
bool getNumAnnotations<ID3DX11EffectPass>(ID3DX11EffectPass *resource, uint32_t *numAnnotation)
{
D3DX11_PASS_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_PASS_DESC));
resource->GetDesc(&varDesc);
*numAnnotation = varDesc.Annotations;
return true;
}
template <>
bool getNumAnnotations<ID3DX11EffectTechnique>(ID3DX11EffectTechnique *resource, uint32_t *numAnnotation)
{
D3DX11_TECHNIQUE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_TECHNIQUE_DESC));
resource->GetDesc(&varDesc);
*numAnnotation = varDesc.Annotations;
return true;
}
template <>
bool getNumAnnotations<ID3DX11EffectGroup>(ID3DX11EffectGroup *resource, uint32_t *numAnnotation)
{
D3DX11_GROUP_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_GROUP_DESC));
resource->GetDesc(&varDesc);
*numAnnotation = varDesc.Annotations;
return true;
}
template <typename ResourceType>
ID3DX11EffectVariable* findAnnotationByName(ResourceType *resource, const char* annotationName)
{
uint32_t numAnnotation = -1;
ID3DX11EffectVariable* retVal = NULL;
if (getNumAnnotations(resource, &numAnnotation))
{
for (uint32_t idx = 0; idx < numAnnotation; ++idx)
{
ID3DX11EffectVariable* var = resource->GetAnnotationByIndex(idx);
if (var)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
var->GetDesc(&varDesc);
if (varDesc.Name && strcmp(varDesc.Name, annotationName) == 0)
{
retVal = var;
break;
}
}
}
}
else
{
retVal = resource->GetAnnotationByName(annotationName);
}
return retVal;
}
template <typename ResourceType>
bool getAnnotation(ResourceType *resource,
const char* annotationName,
MString& annotationValue)
{
ID3DX11EffectVariable* annotation = findAnnotationByName(resource, annotationName);
if(annotation && annotation->IsValid())
{
ID3DX11EffectStringVariable* strVariable = annotation->AsString();
if(strVariable && strVariable->IsValid())
{
LPCSTR value;
if( SUCCEEDED ( strVariable->GetString( &value ) ) )
{
return true;
}
}
}
return false;
}
template <typename ResourceType>
bool getAnnotation(ResourceType *resource, const char* annotationName, float& annotationValue)
{
ID3DX11EffectVariable* annotation = findAnnotationByName(resource, annotationName);
if(annotation && annotation->IsValid())
{
ID3DX11EffectScalarVariable* scalarVariable = annotation->AsScalar();
if(scalarVariable && scalarVariable->IsValid())
{
float value;
if( SUCCEEDED ( scalarVariable->GetFloat( &value ) ) )
{
annotationValue = value;
return true;
}
}
}
return false;
}
template <typename ResourceType>
bool getAnnotation(ResourceType *resource, const char* annotationName, int& annotationValue)
{
ID3DX11EffectVariable* annotation = findAnnotationByName(resource, annotationName);
if(annotation && annotation->IsValid())
{
ID3DX11EffectScalarVariable* scalarVariable = annotation->AsScalar();
if(scalarVariable && scalarVariable->IsValid())
{
int value;
if( SUCCEEDED ( scalarVariable->GetInt( &value ) ) )
{
annotationValue = value;
return true;
}
}
}
return false;
}
template <typename ResourceType>
bool getAnnotation(ResourceType *resource, const char* annotationName, bool& annotationValue)
{
ID3DX11EffectVariable* annotation = findAnnotationByName(resource, annotationName);
if(annotation && annotation->IsValid())
{
ID3DX11EffectScalarVariable* scalarVariable = annotation->AsScalar();
if(scalarVariable && scalarVariable->IsValid())
{
#if defined(USE_BOOL)
BOOL value;
#else
bool value;
#endif
if( SUCCEEDED ( scalarVariable->GetBool( &value ) ) )
{
annotationValue = (value != 0);
return true;
}
}
else
{
ID3DX11EffectStringVariable* strVariable = annotation->AsString();
if(strVariable && strVariable->IsValid())
{
LPCSTR value;
if( SUCCEEDED ( strVariable->GetString( &value ) ) )
{
annotationValue = (_stricmp(value, dx11ShaderAnnotationValue::kTrue) == 0);
return true;
}
}
}
}
return false;
}
{
switch (semantic) {
}
}
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
{
}
if(alphaChannel.
length() > 0) {
alphaChannelIdx = 1;
if(alphaChannel != "Default") {
plug = dependNode.
findPlug(
"alphaList");
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;
}
}
}
}
}
}
}
}
}
MString getFileName(
const MString &filePath,
bool withExtension =
false)
{
if(withExtension == false)
{
if(idx > 0) fileName = fileName.
substringW( 0, idx-1 );
}
return fileName;
}
{
MString fileName1 = getFileName(filePath1);
MString fileName2 = getFileName(filePath2);
return (fileName1 == fileName2);
}
{
dx11ShaderNode::ELightType type = dx11ShaderNode::eUndefinedLight;
switch (lightType.
asChar()[2])
{
case 'o':
if (::strcmp(lightType.
asChar(),
"spotLight") == 0)
type = dx11ShaderNode::eSpotLight;
break;
case 'r':
if (::strcmp(lightType.
asChar(),
"directionalLight") == 0)
type = dx11ShaderNode::eDirectionalLight;
else
type = dx11ShaderNode::eDefaultLight;
break;
case 'i':
if (::strcmp(lightType.
asChar(),
"pointLight") == 0)
type = dx11ShaderNode::ePointLight;
break;
case 'b':
if (::strcmp(lightType.
asChar(),
"ambientLight") == 0)
type = dx11ShaderNode::eAmbientLight;
break;
case 'l':
if (::strcmp(lightType.
asChar(),
"volumeLight") == 0)
type = dx11ShaderNode::eVolumeLight;
break;
case 'e':
if (::strcmp(lightType.
asChar(),
"areaLight") == 0)
type = dx11ShaderNode::eAreaLight;
break;
}
}
return type;
}
bool isLightAcceptable(dx11ShaderNode::ELightType shaderLightType, dx11ShaderNode::ELightType sceneLightType)
{
if(sceneLightType == dx11ShaderNode::eSpotLight)
return true;
if(sceneLightType == dx11ShaderNode::eDirectionalLight || sceneLightType == dx11ShaderNode::eDefaultLight)
return (shaderLightType == dx11ShaderNode::eDirectionalLight || shaderLightType == dx11ShaderNode::eAmbientLight);
if(sceneLightType == dx11ShaderNode::ePointLight ||
sceneLightType == dx11ShaderNode::eAreaLight ||
sceneLightType == dx11ShaderNode::eVolumeLight)
return (shaderLightType == dx11ShaderNode::ePointLight || shaderLightType == dx11ShaderNode::eAmbientLight);
if(sceneLightType == dx11ShaderNode::eAmbientLight)
return (shaderLightType == dx11ShaderNode::eAmbientLight);
return false;
}
typedef std::vector<MStringArray> TNamesForSemantic;
typedef std::vector<TNamesForSemantic> TSemanticNamesForLight;
static TSemanticNamesForLight sSemanticNamesForLight(dx11ShaderNode::eLightCount);
{
TNamesForSemantic& namesForLight(sSemanticNamesForLight[lightType]);
namesForLight.resize(CUniformParameterBuilder::eLastParameterType);
for (
unsigned int p = 0; p < params.
length(); ++p)
{
switch (semantic)
{
namesForLight[CUniformParameterBuilder::eLightPosition].append(pname);
if (pname == "LP0")
namesForLight[CUniformParameterBuilder::eLightAreaPosition0].append(pname);
if (pname == "LP1")
namesForLight[CUniformParameterBuilder::eLightAreaPosition1].append(pname);
if (pname == "LP2")
namesForLight[CUniformParameterBuilder::eLightAreaPosition2].append(pname);
if (pname == "LP3")
namesForLight[CUniformParameterBuilder::eLightAreaPosition3].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightDirection].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightIntensity].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightColor].append(pname);
namesForLight[CUniformParameterBuilder::eLightAmbientColor].append(pname);
namesForLight[CUniformParameterBuilder::eLightSpecularColor].append(pname);
namesForLight[CUniformParameterBuilder::eLightDiffuseColor].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightShadowOn].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightShadowViewProj].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightShadowOn].append(pname);
namesForLight[CUniformParameterBuilder::eLightShadowMap].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightShadowColor].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightShadowMapBias].append(pname);
break;
namesForLight[CUniformParameterBuilder::eLightHotspot].append(pname);
namesForLight[CUniformParameterBuilder::eLightFalloff].append(pname);
break;
namesForLight[CUniformParameterBuilder::eDecayRate].append(pname);
break;
default:
break;
}
}
}
{
if (sSemanticNamesForLight[lightType].size() == 0)
buildDrawContextParameterNames(lightType, lightParam);
return sSemanticNamesForLight[lightType][paramType];
}
{
D3D11_PRIMITIVE_TOPOLOGY topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
switch (primitiveType)
{
topology = (containsHullShader ? D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST : D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
break;
topology = (containsHullShader ? D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST : D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
break;
topology = (containsHullShader ? D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST : D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP);
break;
topology = (containsHullShader ? D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
break;
topology = (containsHullShader ? D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
break;
if(primitiveStride >= 1 && primitiveStride <= 32)
topology = (D3D11_PRIMITIVE_TOPOLOGY)((int)(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) + primitiveStride - 1);
break;
default:
break;
};
return topology;
}
struct MatchingParameter
{
int semanticIndex;
int dimension;
int elementSize;
};
typedef std::vector<MatchingParameter> MatchingParameters;
{
for (
int varId=0; varId < varyingParameters.
length(); ++varId)
{
if (vbSemantics==varyingSemantics) {
const char* varyingMap = strstr(varyingName.
asChar(),
"map");
const char* descriptionMap = strstr(descriptionName.
asChar(),
"map");
int varyingBufferIndex = 0;
bool bMatchFound = false;
if ( varyingName.
length() > 0 ) {
bMatchFound = (descriptionName==varyingName);
if (bMatchFound) {
const char* firstDigit = varyingDestName.
asChar();
while (*firstDigit && !isdigit(*firstDigit))
++firstDigit;
if (!isColorSet)
varyingBufferIndex = *firstDigit ? atoi(firstDigit)-1 : 0;
else
varyingBufferIndex = *firstDigit ? atoi(firstDigit) : 0;
}
}
else
{
varyingBufferIndex = varyingMap ? atoi(varyingMap+3)-1 : 0;
int descriptionIndex = descriptionMap ? atoi(descriptionMap+3)-1 : 0;
bMatchFound = (descriptionIndex==varyingBufferIndex);
}
if (bMatchFound) {
parameters.push_back(param);
}
}
}
}
struct dx11SemanticInfo
{
const char* Name;
int MinElements;
int MaxElements;
};
{
static const dx11SemanticInfo gDx11SemanticInfo[] =
{
};
static int dx11SemanticInfoCount = sizeof(gDx11SemanticInfo) / sizeof(dx11SemanticInfo);
static int dx11SemanticTextCoordId = 2;
int semanticInfoId = 0;
for (; semanticInfoId < dx11SemanticInfoCount; ++semanticInfoId) {
if (::_stricmp(paramDesc.SemanticName, gDx11SemanticInfo[semanticInfoId].Name ) == 0) break;
}
bool isCustomSemantic = false;
if(semanticInfoId >= dx11SemanticInfoCount)
{
isCustomSemantic = true;
static bool enableCustomPrimitiveGenerator = (getenv("MAYA_USE_CUSTOMPRIMITIVEGENERATOR") != NULL);
if(enableCustomPrimitiveGenerator && ::_stricmp(paramDesc.SemanticName, dx11ShaderSemanticValue::kCustomPositionStream) == 0) {
semanticInfoId = 0;
customIndexBufferType = dx11ShaderSemanticValue::kCustomPrimitiveTest;
}
else if(enableCustomPrimitiveGenerator && ::_stricmp(paramDesc.SemanticName, dx11ShaderSemanticValue::kCustomNormalStream) == 0) {
semanticInfoId = 1;
customIndexBufferType = dx11ShaderSemanticValue::kCustomPrimitiveTest;
}
else {
semanticInfoId = dx11SemanticTextCoordId;
}
}
int minWidth = gDx11SemanticInfo[semanticInfoId].MinElements;
int maxWidth = gDx11SemanticInfo[semanticInfoId].MaxElements;
const char* semanticName = isCustomSemantic ? paramDesc.SemanticName : gDx11SemanticInfo[semanticInfoId].Name;
int fieldWidth = 0;
switch (paramDesc.Mask)
{
case 15: fieldWidth = 4; break;
case 7: fieldWidth = 3; break;
case 3: fieldWidth = 2; break;
case 1: fieldWidth = 1; break;
default: fieldWidth = 0; break;
}
switch (paramDesc.ComponentType)
{
}
std::ostringstream destinationSet;
std::ostringstream name;
switch (fieldType)
{
{
destinationSet << "map" << (paramDesc.SemanticIndex+1);
name << semanticName << int(paramDesc.SemanticIndex);
}
break;
{
destinationSet << "colorSet";
if ( paramDesc.SemanticIndex > 0 )
destinationSet << paramDesc.SemanticIndex;
name << semanticName << int(paramDesc.SemanticIndex);
break;
}
default:
{
name << semanticName;
if (paramDesc.SemanticIndex > 0)
{
MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorIndexVaryingParameter, args );
errorLog += msg;
}
}
break;
}
dataType,
minWidth,
maxWidth,
fieldWidth,
fieldType,
MString(destinationSet.str().c_str()),
false,
);
varyingParameters.
append(varying);
if (!isCustomSemantic)
{
if ((int(fieldWidth)<gDx11SemanticInfo[semanticInfoId].MinElements) || (int(fieldWidth)>gDx11SemanticInfo[semanticInfoId].MaxElements) ) {
args.
append( paramDesc.SemanticName );
args.
append( MStringFromUInt(paramDesc.SemanticIndex) );
args.
append( MStringFromInt(gDx11SemanticInfo[semanticInfoId].MinElements) );
args.
append( MStringFromInt(gDx11SemanticInfo[semanticInfoId].MaxElements) );
args.
append( MStringFromInt(fieldWidth) );
MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorVertexRequirement, args );
errorLog += msg;
}
}
}
void buildVaryingParameterList(dx11ShaderDX11EffectTechnique* dxTechnique,
unsigned int numPasses,
MVaryingParameterList& varyingParameters,
MString &errorLog,
MString &warningLog,
MString &customIndexBufferType)
{
SetOfMString registeredSemantics;
for (unsigned int passId = 0; passId < numPasses; ++passId)
{
dx11ShaderDX11Pass* dxPass = dxTechnique->GetPassByIndex(passId);
if(dxPass == NULL || dxPass->IsValid() == false)
continue;
D3DX11_PASS_SHADER_DESC vertexShaderDesc;
memset(&vertexShaderDesc, 0, sizeof(D3DX11_PASS_SHADER_DESC));
dxPass->GetVertexShaderDesc(&vertexShaderDesc);
ID3DX11EffectShaderVariable* shaderVar = vertexShaderDesc.pShaderVariable;
if(shaderVar == NULL)
continue;
unsigned int shaderIndex = vertexShaderDesc.ShaderIndex;
D3DX11_EFFECT_SHADER_DESC shaderDesc;
memset(&shaderDesc, 0, sizeof(D3DX11_EFFECT_SHADER_DESC));
shaderVar->GetShaderDesc(shaderIndex, &shaderDesc);
for (unsigned int varId = 0; varId < shaderDesc.NumInputSignatureEntries; ++varId)
{
D3D11_SIGNATURE_PARAMETER_DESC paramDesc;
shaderVar->GetInputSignatureElementDesc(shaderIndex, varId, ¶mDesc);
uniqueName.
set( (
double)paramDesc.SemanticIndex, 0 );
uniqueName =
MString(paramDesc.SemanticName) +
MString(
"_") + uniqueName;
if( registeredSemantics.count(uniqueName) == 0 )
{
appendVaryingParameter(paramDesc, varyingParameters, errorLog, warningLog, customIndexBufferType);
registeredSemantics.insert(uniqueName);
}
}
}
}
bool buildTemporaryEffect(dx11ShaderNode *shaderNode, dx11ShaderDX11Device *dxDevice, const char* bufferData, unsigned int bufferSize,
dx11ShaderDX11Effect*& dxEffect, dx11ShaderDX11EffectTechnique*& dxTechnique, unsigned int& numPasses,
{
dxEffect = CDX11EffectCompileHelper::build(shaderNode, dxDevice, bufferData, bufferSize, errorLog);
if(dxEffect == NULL)
return false;
dxTechnique = dxEffect->GetTechniqueByIndex(0);
if(dxTechnique != NULL && dxTechnique->IsValid())
{
D3DX11_TECHNIQUE_DESC desc;
memset(&desc, 0, sizeof(D3DX11_TECHNIQUE_DESC));
dxTechnique->GetDesc(&desc);
numPasses = desc.Passes;
}
if(numPasses == 0)
{
CDX11EffectCompileHelper::releaseEffect(shaderNode, dxEffect, "TemporaryEffect");
dxEffect = NULL;
dxTechnique = NULL;
return false;
}
{
D3DX11_EFFECT_DESC effectDesc;
memset(&effectDesc, 0, sizeof(D3DX11_EFFECT_DESC));
dxEffect->GetDesc(&effectDesc);
for (unsigned int varId = 0; varId < effectDesc.GlobalVariables; ++varId)
{
ID3DX11EffectVariable* dxVar = dxEffect->GetVariableByIndex(varId);
CUniformParameterBuilder builder;
builder.init(dxVar, shaderNode, varId);
if(builder.build())
uniformParameters->
append(builder.getParameter());
}
}
{
buildVaryingParameterList(dxTechnique, numPasses, *varyingParameters, errorLog, warningLog, customIndexBufferType);
}
return true;
}
{
{
typedef std::map<MHWRender::MGeometry::Semantic, SetOfMString> RegisteredVaryingParameters;
RegisteredVaryingParameters registeredVaryingParameters;
for(
int paramId = 0; paramId < varyingParameters.
length(); ++paramId)
{
if(registeredVaryingParameters[sourceSemantic].count(sourceSetName) > 0)
continue;
registeredVaryingParameters[sourceSemantic].insert(sourceSetName);
sourceSetName,
sourceSemantic,
}
{
MHWRender::MIndexBufferDescriptor::kTriangle,
}
}
}
#ifdef USE_GL_TEXTURE_CACHING
{
if(_GLFT == NULL)
return 0;
if(textureTarget == NULL)
return 0;
return 0;
int targetRowPitch = 0;
size_t targetSlicePitch = 0;
unsigned char* targetData = (
unsigned char*)(textureTarget->
rawData(targetRowPitch, targetSlicePitch));
if(targetData == NULL)
return 0;
unsigned int targetWidth = targetDesc.
width();
unsigned int targetHeight = targetDesc.
height();
MGLsizei textureWidth = targetWidth;
MGLsizei textureHeight = targetHeight;
scaleU = scaleV = 1.0f;
int bytesPerPixel = 4;
int realTargetRowPitch = bytesPerPixel * targetWidth;
if(_GLFT->
extensionExists(kMGLext_ARB_texture_non_power_of_two) ==
false || realTargetRowPitch != targetRowPitch)
{
int pow2Width = 1;
while(pow2Width < textureWidth)
pow2Width <<= 1;
int pow2Height = 1;
while(pow2Height < textureHeight)
pow2Height <<= 1;
if(pow2Width != textureWidth || pow2Height != textureHeight || realTargetRowPitch != targetRowPitch )
{
int pow2RowPitch = bytesPerPixel * pow2Width;
unsigned int pow2DataSize = pow2RowPitch * pow2Height;
unsigned char* pow2Data = new unsigned char[pow2DataSize];
memset(pow2Data, 0, pow2DataSize);
unsigned int targetOffset = 0;
unsigned int pow2DataOffset = 0;
for(unsigned int row = 0; row < targetHeight; ++row)
{
memcpy(pow2Data + pow2DataOffset, targetData + targetOffset, realTargetRowPitch);
pow2DataOffset += pow2RowPitch;
targetOffset += targetRowPitch;
}
scaleU = (float) textureWidth / (float) pow2Width;
scaleV = (float) textureHeight / (float) pow2Height;
textureWidth = pow2Width;
textureHeight = pow2Height;
delete [] targetData;
targetData = pow2Data;
}
}
MGLuint glTextureId = 0;
_GLFT->
glGenTextures(1, &glTextureId);
_GLFT->
glBindTexture(MGL_TEXTURE_2D, glTextureId);
_GLFT->
glTexParameteri(MGL_TEXTURE_2D, MGL_GENERATE_MIPMAP_SGIS, MGL_TRUE);
_GLFT->
glTexImage2D(MGL_TEXTURE_2D, 0, MGL_RGBA, textureWidth, textureHeight, 0, MGL_RGBA, MGL_UNSIGNED_BYTE, targetData);
delete [] targetData;
return glTextureId;
}
void releaseGLTexture(unsigned int textId)
{
if(_GLFT == NULL)
return;
if(textId == 0)
return;
MGLuint glTextureId = textId;
glDeleteTextures(1, &glTextureId);
}
bool renderGLTexture(unsigned int textId, float scaleU, float scaleV, floatRegion region, bool unfiltered)
{
if(_GLFT == NULL)
return false;
if(textId == 0)
return false;
MGLuint glTextureId = textId;
_GLFT->
glPushAttrib(MGL_TEXTURE_BIT | MGL_COLOR_BUFFER_BIT | MGL_ENABLE_BIT);
_GLFT->
glPushClientAttrib(MGL_CLIENT_VERTEX_ARRAY_BIT);
_GLFT->
glEnable(MGL_TEXTURE_2D);
_GLFT->glBindTexture(MGL_TEXTURE_2D, glTextureId);
_GLFT->glTexParameteri(MGL_TEXTURE_2D, MGL_TEXTURE_WRAP_S, MGL_REPEAT);
_GLFT->glTexParameteri(MGL_TEXTURE_2D, MGL_TEXTURE_WRAP_T, MGL_REPEAT);
if(unfiltered)
_GLFT->glTexParameteri(MGL_TEXTURE_2D, MGL_TEXTURE_MAG_FILTER, MGL_NEAREST);
else
_GLFT->glTexParameteri(MGL_TEXTURE_2D, MGL_TEXTURE_MAG_FILTER, MGL_LINEAR);
_GLFT->
glBlendFunc(MGL_SRC_ALPHA, MGL_ONE_MINUS_SRC_ALPHA);
_GLFT->glEnable(MGL_BLEND);
_GLFT->
glBegin(MGL_QUADS);
_GLFT->
glTexCoord2f(region[0][0] * scaleU, region[0][1] * scaleV);
_GLFT->
glVertex2f(region[0][0], region[0][1]);
_GLFT->glTexCoord2f(region[0][0] * scaleU, region[1][1] * scaleV);
_GLFT->glVertex2f(region[0][0], region[1][1]);
_GLFT->glTexCoord2f(region[1][0] * scaleU, region[1][1] * scaleV);
_GLFT->glVertex2f(region[1][0], region[1][1]);
_GLFT->glTexCoord2f(region[1][0] * scaleU, region[0][1] * scaleV);
_GLFT->glVertex2f(region[1][0], region[0][1]);
_GLFT->glBindTexture(MGL_TEXTURE_2D, 0);
_GLFT->
glPopClientAttrib();
return true;
}
#endif //USE_GL_TEXTURE_CACHING
bool resetTechniqueEnumAttribute(const dx11ShaderNode& 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;
}
MObject buildTechniqueEnumAttribute(
const dx11ShaderNode& 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;
}
{
for(
int i = 0; i < parameters.
length(); ++i )
{
{
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)parameter.
userData();
if( effectVariable )
{
D3DX11_EFFECT_TYPE_DESC descType;
memset(&descType, 0, sizeof(D3DX11_EFFECT_TYPE_DESC));
effectVariable->GetType()->GetDesc(&descType);
if( descType.Class == variableClass)
{
return effectVariable;
}
}
}
return NULL;
}
}
return NULL;
}
{
{
for (
unsigned int i = 0; i < passSemantics.
length(); )
{
{
continue;
}
++i;
}
}
return passSemantics;
}
}
dx11ShaderNode::LightParameterInfo::LightParameterInfo(ELightType lightType, bool hasLightTypeSemantics)
: fLightType(lightType)
, fHasLightTypeSemantics(hasLightTypeSemantics)
, fIsDirty(true)
{
}
dx11ShaderNode::ELightType dx11ShaderNode::LightParameterInfo::lightType() const
{
ELightType type = fLightType;
if( type == dx11ShaderNode::eUndefinedLight )
{
bool requiresPosition = false;
bool requiresSquarePosition = false;
bool requiresDirection = false;
LightParameterInfo::TConnectableParameters::const_iterator it = fConnectableParameters.begin();
LightParameterInfo::TConnectableParameters::const_iterator itEnd = fConnectableParameters.end();
for (; it != itEnd; ++it)
{
const int parameterType = it->second;
if( parameterType == CUniformParameterBuilder::eLightPosition )
requiresPosition = true;
if( parameterType == CUniformParameterBuilder::eLightAreaPosition0 )
requiresSquarePosition = true;
else if( parameterType == CUniformParameterBuilder::eLightDirection )
requiresDirection = true;
}
if( requiresPosition && requiresDirection )
type = dx11ShaderNode::eSpotLight;
else if (requiresSquarePosition)
type = dx11ShaderNode::eAreaLight;
else if ( requiresPosition )
type = dx11ShaderNode::ePointLight;
else if ( requiresDirection )
type = dx11ShaderNode::eDirectionalLight;
else
type = dx11ShaderNode::eAmbientLight;
(const_cast<LightParameterInfo*>(this))->fLightType = type;
}
return type;
}
dx11ShaderNode::dx11ShaderNode()
: fGeometryVersionId(0)
, fLastFrameStamp((MUint64)-1)
, fDuplicateNodeSource(NULL)
, fPostDuplicateCallBackId(NULL)
, fEffect(NULL)
, fTechniqueTextureMipMapLevels(1)
, fTechniqueIndexBufferType()
, fVaryingParametersUpdateId(0)
, fVaryingParametersGeometryVersionId(size_t(-1))
, fForceUpdateTexture(true)
, fFixedTextureMipMapLevels(-1)
, fUVEditorTexture(NULL)
#ifdef USE_GL_TEXTURE_CACHING
, fUVEditorLastAlphaChannel(-1)
, fUVEditorGLTextureId(0)
#endif
, fBBoxExtraScalePlugName()
, fBBoxExtraScaleValue(0.0f)
, fMayaSwatchRenderVar(NULL)
, fErrorCount(0)
, fShaderChangesGeo(false)
, fIgnoreLightLimits(true)
, fLastTime(0)
, fVariableNameAsAttributeName(true)
, fMayaGammaCorrectVar(NULL)
, fMayaHwFogEnabled(NULL)
, fMayaHwFogMode(NULL)
, fMayaHwFogStart(NULL)
, fMayaHwFogEnd(NULL)
, fMayaHwFogDensity(NULL)
, fMayaHwFogColor(NULL)
, fDepthRange(NULL)
, fImplicitAmbientLight(-1)
{
resetData();
fErrorLog.clear();
static bool addedResourcePath = false;
if (!addedResourcePath)
{
if (theRenderer)
{
if (txtManager)
{
MString resourceLocation(
MString(
"${MAYA_LOCATION}\\presets\\HLSL11\\examples").expandEnvironmentVariablesAndTilde());
}
}
addedResourcePath = true;
}
}
dx11ShaderNode::~dx11ShaderNode()
{
PostSceneUpdateAttributeRefresher::remove(this);
resetData();
fErrorLog.clear();
}
{
return sId;
}
void* dx11ShaderNode::creator()
{
return new dx11ShaderNode();
}
MStatus dx11ShaderNode::initialize()
{
try
{
initializeNodeAttrs();
}
catch ( ... )
{
ms = MS::kFailure;
}
return ms;
}
void dx11ShaderNode::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);
}
{
return sProfile;
}
void dx11ShaderNode::copyInternalData(
MPxNode* pSrc )
{
const dx11ShaderNode & src = *(dx11ShaderNode*)pSrc;
fEffectName = src.fEffectName;
fTechniqueIdx = src.fTechniqueIdx;
fTechniqueName = src.fTechniqueName;
if(src.fEffect != NULL && src.fEffect->IsValid())
{
fDuplicateNodeSource = (dx11ShaderNode*)pSrc;
}
}
void dx11ShaderNode::postDuplicateCB( void* data )
{
dx11ShaderNode* shader = (dx11ShaderNode*)data;
shader->fPostDuplicateCallBackId = NULL;
std::vector< std::pair< MPlug, MUniformParameterData > > attributesToConnect;
std::vector< std::pair< MPlug, unsigned int > > lightAttributesToConnect;
unsigned int plugCount = shader->fDuplicatedConnections.length();
if(plugCount > 0)
{
unsigned int nUniform = uniformParameters.
length();
const LightParameterInfoVec& lightParameters = shader->fDuplicateNodeSource->fLightParameters;
unsigned int nLight = (unsigned int)lightParameters.size();
for(unsigned int i = 0; i < plugCount; )
{
const MPlug& plug = shader->fDuplicatedConnections[i++];
const MPlug& dstPlug = shader->fDuplicatedConnections[i++];
MString dstPlugAttrName = dstPlugAttr.name();
bool isConnectedLightAttr = ( dstPlugAttrName.indexW("_connected_light") > -1 );
if(isConnectedLightAttr)
{
for( unsigned int l = 0; l < nLight; ++l )
{
const LightParameterInfo& lightInfo = lightParameters[l];
MFnAttribute connectedLightAttr(lightInfo.fAttrConnectedLight);
MString connectedLightAttrName = connectedLightAttr.name();
if(connectedLightAttrName == dstPlugAttrName)
{
lightAttributesToConnect.push_back( std::make_pair( plug, l ) );
break;
}
}
}
else
{
for( unsigned int u = 0; u < nUniform; ++u )
{
if(elemPlug.
isNull() ==
false)
{
MString elemPlugAttrName = elemPlugAttr.name();
if(elemPlugAttrName == dstPlugAttrName)
{
attributesToConnect.push_back( std::make_pair( plug, param ) );
printf(" uniform <<%s>>\n", param.name.asChar());
break;
}
}
}
}
}
}
shader->reload();
unsigned int attributesToConnectCount = (unsigned int)attributesToConnect.size();
unsigned int lightAttributesToConnectCount = (unsigned int)lightAttributesToConnect.size();
if(attributesToConnectCount > 0 || lightAttributesToConnectCount > 0)
{
unsigned int nUniform = uniformParameters.
length();
for(unsigned int i = 0; i < attributesToConnectCount; ++i)
{
const MPlug& srcPlug = attributesToConnect[i].first;
const MUniformParameterData& duplicatedElement = attributesToConnect[i].second;
for( unsigned int u = 0; u < nUniform; ++u )
{
if( elem.
type() == duplicatedElement.type &&
elem.
name() == duplicatedElement.name )
{
break;
}
}
}
LightParameterInfoVec& lightParameters = shader->fLightParameters;
unsigned int nLight = (unsigned int)lightParameters.size();
for(unsigned int i = 0; i < lightAttributesToConnectCount; ++i)
{
const MPlug& srcPlug = lightAttributesToConnect[i].first;
unsigned int l = lightAttributesToConnect[i].second;
if(l < nLight)
{
LightParameterInfo& lightInfo = lightParameters[l];
dgModifier.
connect(srcPlug.
node(), srcPlug.
attribute(), shader->thisMObject(), lightInfo.fAttrConnectedLight);
}
}
}
shader->fDuplicateNodeSource = NULL;
shader->fDuplicatedConnections.clear();
}
bool dx11ShaderNode::setInternalValue(
const MPlug& plug,
const MDataHandle& handle)
{
bool retVal = true;
try
{
if (plug == sShader)
{
}
else if (plug == sTechnique)
{
}
else if (plug == fTechniqueEnumAttr)
{
M_CHECK(fTechniqueNames.length() < (unsigned int)std::numeric_limits<int>::max());
if (index >= 0 && index < (int)fTechniqueNames.length() && index != fTechniqueIdx)
{
setTechnique(index);
}
}
else
{
if (fBBoxExtraScalePlugName.length() > 0)
{
if (plugName == fBBoxExtraScalePlugName)
{
fBBoxExtraScaleValue = handle.
asFloat();
}
}
}
}
catch( ... )
{
reportInternalError( __FILE__, __LINE__ );
retVal = false;
}
return retVal;
}
{
bool retVal = true;
try
{
if (plug == sShader)
{
handle.
set( fEffectName );
}
else if (plug == sTechnique)
{
const MString tname = activeTechniqueName();
}
else if (plug == fTechniqueEnumAttr)
{
if (fTechniqueIdx >= 0)
{
handle.
set((
short)fTechniqueIdx);
}
}
else if (plug == sTechniques)
{
if (tlist)
else
}
else
{
}
}
catch ( ... )
{
reportInternalError( __FILE__, __LINE__ );
retVal = false;
}
return retVal;
}
MStatus dx11ShaderNode::connectionMade(
const MPlug& plug,
const MPlug& otherPlug,
bool asSrc )
{
if( fDuplicateNodeSource != NULL && asSrc == false)
{
fDuplicatedConnections.append(otherPlug);
fDuplicatedConnections.append(plug);
}
return MS::kUnknownParameter;
}
MStatus dx11ShaderNode::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;
}
{
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;
}
}
bool dx11ShaderNode::hasUpdatedVaryingInput() const
{
unsigned int varyingUpdateId = 0;
for (int i=0; i < fVaryingParameters.length(); ++i)
{
}
if (fVaryingParametersUpdateId != varyingUpdateId)
{
dx11ShaderNode* nonConstThis = const_cast<dx11ShaderNode*>(this);
nonConstThis->fVaryingParametersUpdateId = varyingUpdateId;
nonConstThis->setTopoDirty();
return true;
}
return false;
}
void dx11ShaderNode::setTopoDirty()
{
++fGeometryVersionId;
}
bool dx11ShaderNode::reloadAll(
const MString& effectName)
{
CDX11EffectCompileHelper::ShaderNodeList nodes;
CDX11EffectCompileHelper::getNodesUsingEffect(effectName, nodes);
CDX11EffectCompileHelper::ShaderNodeList::const_iterator it = nodes.begin();
CDX11EffectCompileHelper::ShaderNodeList::const_iterator itEnd = nodes.end();
if (it != itEnd)
{
for(; it != itEnd; ++it)
{
dx11ShaderNode* node = *it;
node->reload();
}
}
else
{
while(!it.isDone())
{
if( fn.typeId() == typeId() ) {
dx11ShaderNode* shaderNode = (dx11ShaderNode*)(fn.userNode());
if(shaderNode && shaderNode->effectName() == effectName)
{
shaderNode->reload();
}
}
it.next();
}
}
return true;
}
bool dx11ShaderNode::reload()
{
int currTechnique = fTechniqueIdx;
loadEffect(fEffectName);
if(currTechnique >= 0 && currTechnique < techniqueCount())
{
setTechnique(currTechnique);
}
for (size_t i = 0; i < fLightParameters.size(); ++i) {
fLightParameters[i].fCachedImplicitLight =
MObject();
setLightParameterLocking(fLightParameters[i], false);
}
IdleAttributeEditorImplicitRefresher::activate();
return true;
}
bool dx11ShaderNode::loadEffect(
const MString& shader)
{
{
clearParameters();
resetData(true);
setUniformParameters( fUniformParameters, true );
setVaryingParameters( fVaryingParameters, true );
resetTechniqueEnumAttribute(*this);
fEffectName = shader;
return true;
}
bool loadedEffect = false;
bool fileExits = true;
MString resolvedFileName = CDX11EffectCompileHelper::resolveShaderFileName(shader, &fileExits);
if(!fileExits)
{
MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorFileNotFound, resolvedFileName );
fErrorLog += msg;
displayErrorAndWarnings();
}
}
{
if (dxDevice)
{
MPlug diagnosticsPlug( thisMObject(), sDiagnostics);
diagnosticsPlug.setValue(
MString(
""));
{
bool fileExits = false;
MString resolvedFileName = CDX11EffectCompileHelper::resolveShaderFileName(shader, &fileExits);
if(fileExits == false)
{
MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorFileNotFound, resolvedFileName );
fErrorLog += msg;
displayErrorAndWarnings();
return false;
}
loadedEffect = loadFromFile( shader, dxDevice );
if (loadedEffect)
{
fEffectName = CDX11EffectCompileHelper::resolveShaderFileName(shader);
if (techniqueCount() > 0) {
MPlug techniquePlug( thisMObject(), sTechnique);
techniquePlug.setValue( techniques()[0] );
}
}
MPlug descriptionPlug( thisMObject(), sDescription);
descriptionPlug.setValue( "" );
}
if(loadedEffect) {
setTopoDirty();
}
}
}
if(loadedEffect == false)
{
fEffectName = shader;
}
return loadedEffect;
}
bool dx11ShaderNode::loadFromFile(
const MString &fileName, dx11ShaderDX11Device* dxDevice )
{
if (!dxDevice)
return false;
resetData();
fEffect = CDX11EffectCompileHelper::build(this, dxDevice, fileName, fErrorLog);
if( fEffect == NULL )
{
displayErrorAndWarnings();
return false;
}
if (!initializeEffect())
{
displayErrorAndWarnings();
resetData();
return false;
}
fEffectName = fileName;
return true;
}
bool dx11ShaderNode::loadFromBuffer(
const MString &identifier,
const void *pData,
unsigned int dataSize, dx11ShaderDX11Device* dxDevice )
{
if (!dxDevice || !pData || dataSize == 0)
return false;
resetData();
fEffect = CDX11EffectCompileHelper::build(this, dxDevice, pData, dataSize, fErrorLog);
if( fEffect == NULL )
{
displayErrorAndWarnings();
return false;
}
if (!initializeEffect())
{
displayErrorAndWarnings();
resetData();
return false;
}
fEffectName = identifier;
return true;
}
bool dx11ShaderNode::initializeEffect()
{
resetData( false );
if (!fEffect)
return false;
initializeTechniques();
if (techniqueCount() == 0)
{
displayErrorAndWarnings();
return false;
}
return true;
}
void dx11ShaderNode::resetData(bool clearEffect)
{
fMayaSwatchRenderVar = NULL;
fMayaGammaCorrectVar = NULL;
fMayaHwFogEnabled = NULL;
fMayaHwFogMode = NULL;
fMayaHwFogStart = NULL;
fMayaHwFogEnd = NULL;
fMayaHwFogDensity = NULL;
fMayaHwFogColor = NULL;
fDepthRange = NULL;
fTechnique = NULL;
if (clearEffect && fEffect)
{
CDX11EffectCompileHelper::releaseEffect(this, fEffect, fEffectName);
fEffect = NULL;
releaseAllTextures();
}
fTechniqueIdx = -1;
fTechniqueName.clear();
fTechniqueNames.clear();
fTechniquePassCount = 0;
fTechniquePassSpecs.clear();
clearLightConnectionData();
fUniformParameters.setLength(0);
fVaryingParametersUpdateId = 0;
fVaryingParameters.setLength(0);
fVaryingParametersVertexDescriptorList.clear();
fTechniqueIndexBufferType.clear();
fTechniqueTextureMipMapLevels = 1;
fTechniqueIsTransparent = eOpaque;
fOpacityPlugName = "";
fTransparencyTestProcName = "";
fTechniqueSupportsAdvancedTransparency = false;
fTechniqueOverridesNonMaterialItems = false;
fTechniqueHandlesConsolidatedGeometry = false;
fTechniqueIsSelectable = false;
fTechniqueOverridesDrawState = false;
fForceUpdateTexture = true;
fFixedTextureMipMapLevels = -1;
releaseTexture(fUVEditorTexture);
fUVEditorTexture = NULL;
#ifdef USE_GL_TEXTURE_CACHING
fUVEditorLastTexture.clear();
fUVEditorLastLayer.clear();
fUVEditorLastAlphaChannel = -1;
fUVEditorBaseColor[0] = fUVEditorBaseColor[1] = fUVEditorBaseColor[2] = fUVEditorBaseColor[3] = 0;
fUVEditorShowAlphaMask = false;
releaseGLTexture(fUVEditorGLTextureId);
fUVEditorGLTextureId = 0;
fUVEditorGLTextureScaleU = fUVEditorGLTextureScaleV = 1.0f;
#endif //USE_GL_TEXTURE_CACHING
fPassHasHullShaderMap.clear();
{
PassInputLayoutMap::iterator it = fPassInputLayoutMap.begin();
PassInputLayoutMap::iterator itEnd = fPassInputLayoutMap.end();
for(; it != itEnd; ++it)
{
InputLayoutData& data = it->second;
data.inputLayout->Release();
delete [] data.layoutDesc;
}
fPassInputLayoutMap.clear();
}
}
{
MStringArray passSemantics = getPassSemanticsRemovingColorPassIfNecessary(context);
for (unsigned int passIndex = 0; passIndex < fTechniquePassCount; ++passIndex)
{
if( passHandlesContext(passSemantics, passIndex, RENDER_SCENE) )
return true;
}
return false;
}
bool dx11ShaderNode::passHandlesContext(
const MStringArray& passSemantics,
unsigned int passIndex, ERenderType renderType,
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(isRenderNonMaterialItem(renderType))
{
isHandled = (::_stricmp(passSpec.drawContext.asChar(), dx11ShaderAnnotation::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 && isRenderNonMaterialItem(renderType))
{
if (renderItemDesc && renderItemDesc->isFatLine)
{
if (!passSpec.forFatLine)
{
const PassSpec passSpecTest = { passSpec.drawContext, true, false };
isHandled = (findMatchingPass(passSpecTest) == (unsigned int)-1);
}
}
else if (renderItemDesc && renderItemDesc->isFatPoint)
{
if (!passSpec.forFatPoint)
{
const PassSpec passSpecTest = { passSpec.drawContext, false, true };
isHandled = (findMatchingPass(passSpecTest) == (unsigned int)-1);
}
}
else
{
isHandled = (!passSpec.forFatLine && !passSpec.forFatPoint);
}
}
}
return isHandled;
}
unsigned int dx11ShaderNode::findMatchingPass(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;
}
bool dx11ShaderNode::initializeTechniques()
{
fTechnique = NULL;
fTechniqueIdx = -1;
fTechniqueName.clear();
fTechniqueNames.clear();
resetTechniqueEnumAttribute(*this);
if (!fEffect)
return false;
D3DX11_EFFECT_DESC descEffect;
memset(&descEffect, 0, sizeof(D3DX11_EFFECT_DESC));
HRESULT hr = fEffect->GetDesc(&descEffect);
if (FAILED(hr) || descEffect.Techniques == 0)
{
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorNoValidTechniques );
displayErrorAndWarnings();
return false;
}
for (unsigned int i = 0; i < descEffect.Techniques; ++i)
{
ID3DX11EffectTechnique* dxTechnique = fEffect->GetTechniqueByIndex(i);
if (!dxTechnique->IsValid()) continue;
D3DX11_TECHNIQUE_DESC desc;
memset(&desc, 0, sizeof(D3DX11_TECHNIQUE_DESC));
dxTechnique->GetDesc(&desc);
fTechniqueNames.append( desc.Name );
}
fTechniqueEnumAttr = buildTechniqueEnumAttribute(*this);
if (techniqueCount() == 0)
{
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorNoValidTechniques );
displayErrorAndWarnings();
return false;
}
return true;
}
bool dx11ShaderNode::setTechnique(
const MString & techniqueName )
{
if (!fEffect && fEffectName.length() > 0)
{
fTechniqueName = techniqueName;
fTechniqueNames.append( techniqueName );
fTechniqueEnumAttr = buildTechniqueEnumAttribute(*this);
return false;
}
if (!fEffect)
return false;
int numTechniques = techniqueCount();
for (int i=0; i<numTechniques; ++i) {
if (fTechniqueNames[i] == techniqueName) {
return setTechnique(i);
}
}
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorSetTechniqueByName, techniqueName );
displayErrorAndWarnings();
return false;
}
bool dx11ShaderNode::setTechnique( int techniqueNumber )
{
setTopoDirty();
if (!fEffect)
return false;
if (techniqueNumber < 0 || techniqueNumber >= techniqueCount())
{
MString techniqueNumberStr = MStringFromInt(techniqueNumber);
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorSetTechniqueByIndex, techniqueNumberStr );
displayErrorAndWarnings();
return false;
}
if (fTechniqueIdx == techniqueNumber)
return true;
fTechnique = fEffect->GetTechniqueByName( fTechniqueNames[techniqueNumber].asChar() );
if (!fTechnique)
{
MString techniqueNumberStr = MStringFromInt(techniqueNumber);
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorSetTechniqueByIndex, techniqueNumberStr );
displayErrorAndWarnings();
return false;
}
fTechniqueIdx = techniqueNumber;
fTechniqueName = fTechniqueNames[fTechniqueIdx];
D3DX11_TECHNIQUE_DESC desc;
memset(&desc, 0, sizeof(D3DX11_TECHNIQUE_DESC));
fTechnique->GetDesc(&desc);
fTechniquePassCount = desc.Passes;
fTechniquePassSpecs.clear();
for (unsigned int passIndex = 0; passIndex < fTechniquePassCount; ++passIndex)
{
ID3DX11EffectPass *dxPass = fTechnique->GetPassByIndex(passIndex);
if(dxPass && dxPass->IsValid())
{
getAnnotation(dxPass, dx11ShaderAnnotation::kDrawContext, passDrawContext);
fTechniqueIsSelectable = true;
getAnnotation(dxPass, dx11ShaderAnnotation::kPrimitiveFilter, passPrimitiveFilter);
const bool passIsForFatLine = (::_stricmp(passPrimitiveFilter.
asChar(), dx11ShaderAnnotationValue::kFatLine) == 0);
const bool passIsForFatPoint = (::_stricmp(passPrimitiveFilter.
asChar(), dx11ShaderAnnotationValue::kFatPoint) == 0);
PassSpec spec = { passDrawContext, passIsForFatLine, passIsForFatPoint };
fTechniquePassSpecs.insert( std::make_pair(passIndex, spec) );
}
}
clearLightConnectionData();
buildUniformParameterList();
setUniformParameters( fUniformParameters );
initMayaParameters();
storeDefaultTextureNames();
buildVaryingParameterList();
setVaryingParameters(fVaryingParameters);
initTechniqueParameters();
restoreDefaultTextureNames();
return true;
}
void dx11ShaderNode::storeDefaultTextureNames()
{
fDefaultTextureNames.clear();
fDefaultTextureNames.setLength( fVaryingParameters.length() );
for (int iVar = 0; iVar < fVaryingParameters.length(); ++iVar)
{
continue;
attrName += "_DefaultTexture";
MPlug defaultTexPlug = depFn.findPlug( attrName );
continue;
fDefaultTextureNames[iVar] = texName;
}
}
void dx11ShaderNode::restoreDefaultTextureNames()
{
for (int iVar = 0; iVar < fVaryingParameters.length(); ++iVar)
{
if (iVar >= (int)fDefaultTextureNames.length())
return;
continue;
if (fDefaultTextureNames[iVar].length() == 0)
continue;
attrName += "_DefaultTexture";
MPlug defaultTexPlug = depFn.findPlug( attrName );
continue;
defaultTexPlug.
setValue( fDefaultTextureNames[iVar] );
}
}
void dx11ShaderNode::initTechniqueParameters()
{
getAnnotation(fTechnique, dx11ShaderAnnotation::kIndexBufferType, newIndexBufferType);
if(fTechniqueIndexBufferType != newIndexBufferType)
{
fTechniqueIndexBufferType = newIndexBufferType;
setTopoDirty();
}
int mipmapLevels = 1;
getAnnotation(fTechnique, dx11ShaderAnnotation::kTextureMipmaplevels, mipmapLevels);
if(fTechniqueTextureMipMapLevels != mipmapLevels)
{
fTechniqueTextureMipMapLevels = mipmapLevels;
fForceUpdateTexture = true;
}
fTechniqueOverridesDrawState = false;
getAnnotation(fTechnique, dx11ShaderAnnotation::kOverridesDrawState, fTechniqueOverridesDrawState);
fTechniqueSupportsAdvancedTransparency = false;
getAnnotation(fTechnique, dx11ShaderAnnotation::kSupportsAdvancedTransparency, fTechniqueSupportsAdvancedTransparency);
fTechniqueOverridesNonMaterialItems = false;
getAnnotation(fTechnique, dx11ShaderAnnotation::kOverridesNonMaterialItems, fTechniqueOverridesNonMaterialItems);
fTechniqueHandlesConsolidatedGeometry = true;
getAnnotation(fTechnique, dx11ShaderAnnotation::kHandlesConsolidatedGeometry, fTechniqueHandlesConsolidatedGeometry);
fTechniqueIsTransparent = eOpaque;
int techniqueTransparentAnnotation = 0;
if( getAnnotation(fTechnique, dx11ShaderAnnotation::kIsTransparent, techniqueTransparentAnnotation) == false )
{
ID3D11Device *device;
if( S_OK == fEffect->GetDevice(&device) )
{
ID3D11DeviceContext *deviceContext;
if( S_OK == device->CreateDeferredContext(0, &deviceContext) )
{
for( unsigned int passId = 0; passId < fTechniquePassCount; ++passId)
{
ID3DX11EffectPass *dxPass = fTechnique->GetPassByIndex(passId);
if( dxPass == NULL || dxPass->IsValid() == false )
continue;
if( S_OK == dxPass->Apply(0, deviceContext) == false )
continue;
ID3D11BlendState *blendState;
FLOAT blendFactor[4];
UINT sampleMask;
deviceContext->OMGetBlendState(&blendState, blendFactor, &sampleMask);
if(blendState)
{
D3D11_BLEND_DESC blendDesc;
blendState->GetDesc(&blendDesc);
if( blendDesc.RenderTarget[0].BlendEnable != FALSE )
{
if( blendDesc.RenderTarget[0].SrcBlend > D3D11_BLEND_ONE ||
blendDesc.RenderTarget[0].DestBlend > D3D11_BLEND_ONE )
{
fTechniqueIsTransparent = eTransparent;
break;
}
}
}
}
deviceContext->Release();
}
device->Release();
}
}
else
{
switch (techniqueTransparentAnnotation)
{
case eOpaque:
fTechniqueIsTransparent = eOpaque;
break;
case eTransparent:
fTechniqueIsTransparent = eTransparent;
break;
case eScriptedTest:
fTechniqueIsTransparent = eScriptedTest;
{
if (getAnnotation(fTechnique, dx11ShaderAnnotation::kTransparencyTest, procBody) &&
{
#ifdef MAYA_PRINT_DEBUG_INFO
printf(
"-- transparencyTest <<%s>>.\n", procBody.
asChar());
#endif
unsigned int paramCount = fUniformParameters.
length();
for( unsigned int i = 0; i < paramCount; ++i )
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if(effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
const MString varName(varDesc.Name);
const MString attrName = attr.name();
static const MString queryFormat (
"`getAttr($shader + \".^1s\")`" );
query.
format( queryFormat, attrName );
procBody = replaceAll(procBody, varName, query);
}
}
static const MString procNameFormat (
"dx11Shader^1sTransparencyTest" );
fTransparencyTestProcName = getFileName(fEffectName);
fTransparencyTestProcName = sanitizeName(fTransparencyTestProcName);
fTransparencyTestProcName.format( procNameFormat, fTransparencyTestProcName );
static const MString procBodyFormat (
"global proc int ^1s(string $shader) { return (^2s); }" );
procBody.
format( procBodyFormat, fTransparencyTestProcName, procBody );
#ifdef MAYA_PRINT_DEBUG_INFO
printf(
"-- transparencyTest <<%s>>.\n", procBody.
asChar());
#endif
{
break;
}
}
fTransparencyTestProcName = "";
}
case eTestOpacitySemantics:
fTechniqueIsTransparent = eTestOpacitySemantics;
{
bool foundOpacity = false;
unsigned int paramCount = fUniformParameters.length();
for( unsigned int i = 0; i < paramCount && !foundOpacity; ++i )
{
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if(effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
foundOpacity = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kOpacity, varDesc.Semantic) == 0 );
if(foundOpacity == false)
{
bool boolValue = 0;
foundOpacity = (getAnnotation(effectVariable, dx11ShaderSemantic::kOpacity, boolValue) && boolValue);
}
if(foundOpacity)
{
}
}
}
}
if (!foundOpacity)
{
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorIsTransparentOpacity );
}
}
break;
default:
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorUnknownIsTransparent );
}
}
int bestIndex = INT_MAX;
unsigned int numUniform = fUniformParameters.
length();
for( unsigned int i = 0; i < numUniform; i++ ) {
if (uniformPlug.isNull())
continue;
if (uniformAttribute.isHidden())
continue;
int currentIndex = bestIndex - numUniform + i;
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)elem.
userData();
if (effectVariable)
{
int uvEditorOrder;
if (getAnnotation(effectVariable, "UVEditorOrder", uvEditorOrder))
{
currentIndex = uvEditorOrder;
}
}
if (currentIndex < bestIndex)
{
bestIndex = currentIndex;
defaultTex = elem.
name();
}
}
}
{
for (int iVar = 0; iVar < fVaryingParameters.length(); ++iVar)
{
attrName += "_DefaultTexture";
MPlug defaultTexPlug = depFn.findPlug( attrName );
if( !defaultTexPlug.
isNull() ) {
}
}
}
}
}
bool dx11ShaderNode::techniqueIsTransparent() const
{
switch (fTechniqueIsTransparent)
{
case eTransparent:
return true;
case eOpaque:
return false;
case eScriptedTest:
{
int result = 0;
return (result == 0 ? false : true);
}
default:
break;
}
if (fOpacityPlugName != "")
{
MPlug opacityPlug = depFn.findPlug( fOpacityPlugName );
float currentOpacity = 1.0f;
return currentOpacity < 1.0f;
}
}
return false;
}
dx11ShaderDX11Pass* dx11ShaderNode::activatePass( dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int passId, ERenderType renderType ) const
{
return activatePass( dxDevice, dxContext, dxTechnique, passId, colorSem, renderType );
}
dx11ShaderDX11Pass* dx11ShaderNode::activatePass( dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique,
unsigned int passId,
const MStringArray& passSem, ERenderType renderType,
const RenderItemDesc* renderItemDesc )
const
{
dx11ShaderDX11Pass* dxPass = dxTechnique->GetPassByIndex(passId);
if(dxPass == NULL || dxPass->IsValid() == false)
{
args.
append( MStringFromInt(passId) );
args.
append( fTechniqueName );
fErrorLog += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorSetPass, args );
displayErrorAndWarnings();
return NULL;
}
if( !passHandlesContext( passSem, passId, renderType, renderItemDesc ) )
return NULL;
D3DX11_STATE_BLOCK_MASK stateBlockMask;
memset(&stateBlockMask, 0, sizeof(D3DX11_STATE_BLOCK_MASK));
dxPass->ComputeStateBlockMask(&stateBlockMask);
D3D11_RASTERIZER_DESC orgRasterizerDesc;
if(stateBlockMask.RSRasterizerState)
{
ID3D11RasterizerState* orgRasterizerState;
dxContext->RSGetState(&orgRasterizerState);
orgRasterizerState->GetDesc(&orgRasterizerDesc);
orgRasterizerState->Release();
}
else
{
memset(&orgRasterizerDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
}
dxPass->Apply(0, dxContext);
if(stateBlockMask.RSRasterizerState || overrideRasterizerState(renderType))
{
ID3D11RasterizerState* newRasterizerState;
dxContext->RSGetState(&newRasterizerState);
D3D11_RASTERIZER_DESC newRasterizerDesc;
newRasterizerDesc.FillMode = D3D11_FILL_SOLID;
newRasterizerDesc.CullMode = D3D11_CULL_BACK;
newRasterizerDesc.FrontCounterClockwise = FALSE;
newRasterizerDesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS;
newRasterizerDesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
newRasterizerDesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
newRasterizerDesc.DepthClipEnable = TRUE;
newRasterizerDesc.ScissorEnable = FALSE;
newRasterizerDesc.MultisampleEnable = FALSE;
newRasterizerDesc.AntialiasedLineEnable = FALSE;
if (NULL != newRasterizerState)
{
newRasterizerState->GetDesc(&newRasterizerDesc);
newRasterizerState->Release();
}
bool createNewRasterizeState = false;
if( stateBlockMask.RSRasterizerState &&
( newRasterizerDesc.DepthBias != orgRasterizerDesc.DepthBias ||
newRasterizerDesc.SlopeScaledDepthBias != orgRasterizerDesc.SlopeScaledDepthBias ) )
{
newRasterizerDesc.DepthBias = orgRasterizerDesc.DepthBias;
newRasterizerDesc.SlopeScaledDepthBias = orgRasterizerDesc.SlopeScaledDepthBias;
createNewRasterizeState = true;
}
if( isRenderScene(renderType) &&
techniqueIsTransparent() &&
fTechniqueOverridesDrawState == false &&
( newRasterizerDesc.CullMode != orgRasterizerDesc.CullMode ||
newRasterizerDesc.FrontCounterClockwise != orgRasterizerDesc.FrontCounterClockwise ) )
{
newRasterizerDesc.CullMode = orgRasterizerDesc.CullMode;
newRasterizerDesc.FrontCounterClockwise = orgRasterizerDesc.FrontCounterClockwise;
createNewRasterizeState = true;
}
if( !isRenderScene(renderType) &&
newRasterizerDesc.FillMode == D3D11_FILL_SOLID &&
newRasterizerDesc.CullMode == D3D11_CULL_NONE )
{
newRasterizerDesc.CullMode = D3D11_CULL_BACK;
newRasterizerDesc.FrontCounterClockwise = true;
createNewRasterizeState = true;
}
if( createNewRasterizeState && SUCCEEDED( dxDevice->CreateRasterizerState( &newRasterizerDesc, &newRasterizerState ) ) )
{
dxContext->RSSetState( newRasterizerState );
newRasterizerState->Release();
}
}
if(!isRenderScene(renderType))
{
ID3D11BlendState* newBlendState;
FLOAT newBlendFactor[4];
UINT newSampleMask;
dxContext->OMGetBlendState(&newBlendState, newBlendFactor, &newSampleMask);
D3D11_BLEND_DESC newBlendDesc;
newBlendState->GetDesc(&newBlendDesc);
newBlendState->Release();
bool createNewBlendState = false;
if( newBlendDesc.RenderTarget[0].BlendEnable != FALSE &&
newBlendDesc.RenderTarget[0].DestBlendAlpha != D3D11_BLEND_ONE )
{
newBlendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
createNewBlendState = true;
}
if( createNewBlendState && SUCCEEDED( dxDevice->CreateBlendState( &newBlendDesc, &newBlendState ) ) )
{
dxContext->OMSetBlendState(newBlendState, newBlendFactor, newSampleMask);
newBlendState->Release();
}
}
return dxPass;
}
bool dx11ShaderNode::passHasHullShader(dx11ShaderDX11Pass* dxPass) const
{
PassHasHullShaderMap::const_iterator it = fPassHasHullShaderMap.find(dxPass);
if(it != fPassHasHullShaderMap.end())
return it->second;
D3DX11_PASS_SHADER_DESC hullShaderDesc;
memset(&hullShaderDesc, 0, sizeof(D3DX11_PASS_SHADER_DESC));
HRESULT hr = dxPass->GetHullShaderDesc(&hullShaderDesc);
bool bContainsHullShader = false;
if(SUCCEEDED(hr) && hullShaderDesc.pShaderVariable && hullShaderDesc.pShaderVariable->IsValid())
{
D3DX11_EFFECT_SHADER_DESC hullEffectDesc;
memset(&hullEffectDesc, 0, sizeof(D3DX11_EFFECT_SHADER_DESC));
hr = hullShaderDesc.pShaderVariable->GetShaderDesc(hullShaderDesc.ShaderIndex,&hullEffectDesc);
if (SUCCEEDED(hr) && hullEffectDesc.BytecodeLength)
{
ID3D11HullShader* pHullShader = NULL;
hullShaderDesc.pShaderVariable->GetHullShader(hullShaderDesc.ShaderIndex,&pHullShader);
if(pHullShader)
{
bContainsHullShader = true;
pHullShader->Release();
}
}
}
fPassHasHullShaderMap[dxPass] = bContainsHullShader;
return bContainsHullShader;
}
dx11ShaderDX11InputLayout* dx11ShaderNode::getInputLayout(dx11ShaderDX11Device* dxDevice, dx11ShaderDX11Pass* dxPass, unsigned int numLayouts, const dx11ShaderDX11InputElementDesc* layoutDesc) const
{
PassInputLayoutMap::iterator it = fPassInputLayoutMap.find(dxPass);
if(it != fPassInputLayoutMap.end())
{
InputLayoutData& data = it->second;
if( numLayouts == data.numLayouts )
{
bool isEqual = true;
for(unsigned int i = 0; isEqual && i < numLayouts; ++i)
{
const CachedInputElementDesc &haveDesc = data.layoutDesc[i];
const dx11ShaderDX11InputElementDesc &wantDesc = layoutDesc[i];
isEqual = ( haveDesc.SemanticIndex == wantDesc.SemanticIndex &&
haveDesc.Format == wantDesc.Format &&
haveDesc.InputSlot == wantDesc.InputSlot &&
haveDesc.AlignedByteOffset == wantDesc.AlignedByteOffset &&
haveDesc.InputSlotClass == wantDesc.InputSlotClass &&
haveDesc.InstanceDataStepRate == wantDesc.InstanceDataStepRate &&
strcmp(haveDesc.SemanticName.asChar(), wantDesc.SemanticName) == 0 );
}
if(isEqual)
return data.inputLayout;
}
data.inputLayout->Release();
delete [] data.layoutDesc;
fPassInputLayoutMap.erase(it);
}
D3DX11_PASS_DESC descPass;
memset(&descPass, 0, sizeof(D3DX11_PASS_DESC));
dxPass->GetDesc(&descPass);
ID3D11InputLayout* inputLayout = NULL;
dxDevice->CreateInputLayout(layoutDesc, numLayouts, descPass.pIAInputSignature, descPass.IAInputSignatureSize, &inputLayout);
if(inputLayout != NULL)
{
InputLayoutData data;
data.inputLayout = inputLayout;
data.numLayouts = numLayouts;
data.layoutDesc = new CachedInputElementDesc[numLayouts];
for(unsigned int i = 0; i < numLayouts; ++i)
{
const dx11ShaderDX11InputElementDesc &wantDesc = layoutDesc[i];
CachedInputElementDesc &cacheDesc = data.layoutDesc[i];
cacheDesc.SemanticIndex = wantDesc.SemanticIndex;
cacheDesc.Format = wantDesc.Format;
cacheDesc.InputSlot = wantDesc.InputSlot;
cacheDesc.AlignedByteOffset = wantDesc.AlignedByteOffset;
cacheDesc.InputSlotClass = wantDesc.InputSlotClass;
cacheDesc.InstanceDataStepRate = wantDesc.InstanceDataStepRate;
cacheDesc.SemanticName =
MString(wantDesc.SemanticName);
}
fPassInputLayoutMap[dxPass] = data;
}
return inputLayout;
}
{
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glPushAttrib(GL_CURRENT_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glColor4f(0.7f, 0.1f, 0.1f, 1.0f);
glDisable(GL_LIGHTING);
for( ; iterator.
isDone() ==
false; iterator.
next())
{
{
GLint size = 0;
{
default: continue;
}
const GLvoid* data = position.
data();
glVertexPointer(size, GL_FLOAT, 0, data);
}
{
const GLvoid* data = normal.
data();
glNormalPointer(GL_FLOAT, 0, data);
}
for(
unsigned int primitiveIdx = 0; primitiveIdx < geometry.
primitiveArrayCount(); ++primitiveIdx)
{
GLenum mode = GL_TRIANGLES;
{
default: continue;
};
GLenum format = GL_UNSIGNED_INT;
{
default: continue;
}
const GLvoid* indices = primitive.
data();
glDrawElements(mode, count, format, indices);
}
}
glPopAttrib();
glPopClientAttrib();
return result;
}
{
unsigned int width, height;
if (!context) {
}
ID3DX11Effect *dxEffect = NULL;
ID3DX11EffectTechnique *dxTechnique = fTechnique;
ResourceTextureMap* resourceTexture = &fResourceTextureMap;
MString indexBufferType = fTechniqueIndexBufferType;
unsigned int numPasses = fTechniquePassCount;
ERenderType renderType = RENDER_SWATCH;
if(numPasses == 0 || dxTechnique == NULL || dxTechnique->IsValid() == false || (fUniformParameters.length() == 0 && fVaryingParameters.length() == 0))
{
static const char* simpleShaderCode = "// transform object vertices to view space and project them in perspective: \r\n" \
"float4x4 gWvpXf : WorldViewProjection; \r\n" \
"struct appdata \r\n" \
"{ \r\n" \
" float3 Pos : POSITION; \r\n" \
" float4 Color : COLOR0; \r\n" \
"}; \r\n" \
"struct vertexOutput \r\n" \
"{ \r\n" \
" float4 Pos : POSITION; \r\n" \
" float4 Color : COLOR0; \r\n" \
"}; \r\n" \
"vertexOutput BasicVS(appdata IN, uniform float4x4 WvpXf) \r\n" \
"{ \r\n" \
" vertexOutput OUT; \r\n" \
" float4 Po = float4(IN.Pos,1); \r\n" \
" OUT.Pos = mul(Po,WvpXf); \r\n" \
" OUT.Color = IN.Color; \r\n" \
" return OUT; \r\n" \
"} \r\n" \
"float4 BasicPS(vertexOutput IN) : COLOR \r\n" \
"{ \r\n" \
" return IN.Color; \r\n" \
"} \r\n" \
"technique10 simple \r\n" \
"{ \r\n" \
" pass p0 \r\n" \
" { \r\n" \
" SetVertexShader( CompileShader( vs_4_0, BasicVS(gWvpXf) ) ); \r\n" \
" SetGeometryShader( NULL ); \r\n" \
" SetPixelShader( CompileShader( ps_4_0, BasicPS() ) ); \r\n" \
" } \r\n" \
"} \r\n";
static const unsigned int simpleShaderLength = (unsigned int)strlen(simpleShaderCode);
buildTemporaryEffect(this,
dxDevice, simpleShaderCode, simpleShaderLength,
dxEffect, dxTechnique, numPasses,
varyingParameters, uniformParameters, indexBufferType);
renderType = RENDER_SWATCH_PROXY;
resourceTexture = new ResourceTextureMap;
}
if(numPasses > 0)
{
if(geometry != NULL)
{
updateParameters(*context, *uniformParameters, *resourceTexture, renderType);
float clearColor[4];
if( renderTechnique(dxDevice, dxTechnique, numPasses,
textureTarget, width, height, clearColor,
*varyingParameters, renderType, indexBufferType) )
{
}
}
}
if(dxEffect)
{
CDX11EffectCompileHelper::releaseEffect(this, dxEffect, "TemporaryEffect");
delete uniformParameters;
delete varyingParameters;
releaseAllTextures(*resourceTexture);
delete resourceTexture;
}
return result;
}
{
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 );
if( !defaultTexPlug.
isNull() ) {
}
}
std::multimap<int, MString> sortedTextures;
std::vector<MString> unsortedTextures;
unsigned int nUniform = fUniformParameters.length();
if( imageNames.
length() == 0 ) {
for( unsigned int i = 0; i < nUniform; i++ ) {
if (uniformPlug.isNull())
continue;
if (uniformAttribute.isHidden())
continue;
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)elem.
userData();
if (effectVariable)
{
int uvEditorOrder;
if (getAnnotation(effectVariable, "UVEditorOrder", uvEditorOrder))
{
sortedTextures.insert(std::pair<int, MString>(uvEditorOrder, elem.
name()));
continue;
}
}
unsortedTextures.push_back(elem.
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 );
}
}
}
{
int alphaChannelIdx, mipmapLevels;
MHWRender::MTexture* texture = getUVTexture(context, imageName, imageWidth, imageHeight, textureName, layerName, alphaChannelIdx, mipmapLevels);
if(texture == NULL)
{
}
if(region[0][0] == 0 && region[0][1] == 0 && region[1][0] == 0 && region[1][1] == 0)
{
}
float baseColor[4] = {parameters.
baseColor.
r, parameters.baseColor.
g, parameters.baseColor.
b, parameters.baseColor.
a };
bool unfiltered = parameters.
unfiltered;
bool showAlphaMask = parameters.
showAlphaMask;
#ifdef USE_GL_TEXTURE_CACHING
if(fUVEditorGLTextureId > 0 &&
fUVEditorLastTexture == textureName &&
fUVEditorLastLayer == layerName &&
fUVEditorLastAlphaChannel == alphaChannelIdx &&
fUVEditorShowAlphaMask == showAlphaMask &&
fUVEditorBaseColor[0] == baseColor[0] &&
fUVEditorBaseColor[1] == baseColor[1] &&
fUVEditorBaseColor[2] == baseColor[2] &&
fUVEditorBaseColor[3] == baseColor[3] )
{
if( renderGLTexture(fUVEditorGLTextureId, fUVEditorGLTextureScaleU, fUVEditorGLTextureScaleV, region, unfiltered) )
return result;
}
if(fUVEditorGLTextureId > 0)
{
releaseGLTexture(fUVEditorGLTextureId);
fUVEditorGLTextureId = 0;
}
fUVEditorLastTexture = textureName;
fUVEditorLastLayer = layerName;
fUVEditorLastAlphaChannel = alphaChannelIdx;
fUVEditorShowAlphaMask = showAlphaMask;
fUVEditorBaseColor[0] = baseColor[0];
fUVEditorBaseColor[1] = baseColor[1];
fUVEditorBaseColor[2] = baseColor[2];
fUVEditorBaseColor[3] = baseColor[3];
fUVEditorGLTextureScaleU = fUVEditorGLTextureScaleV = 1.0f;
#endif //USE_GL_TEXTURE_CACHING
ID3DX11Effect *dxEffect = NULL;
ID3DX11EffectTechnique *dxTechnique = NULL;
ResourceTextureMap* resourceTexture = NULL;
unsigned int numPasses = 0;
ERenderType renderType = RENDER_UVTEXTURE;
{
static const char* simpleShaderCode = "float4x4 gWvpXf : WorldViewProjection; \r\n" \
"SamplerState SamplerLinear \r\n" \
"{ \r\n" \
" Filter = MIN_MAG_MIP_LINEAR; \r\n" \
" AddressU = Wrap; \r\n" \
" AddressV = Wrap; \r\n" \
"}; \r\n" \
"Texture2D myTexture; \r\n" \
"float4 baseColor = { 1.0f, 1.0f, 1.0f, 1.0f }; \r\n" \
"bool showAlphaMask = false; \r\n" \
"struct appdata \r\n" \
"{ \r\n" \
" float3 Pos : POSITION; \r\n" \
" float2 Uv : TEXTCOORD; \r\n" \
"}; \r\n" \
"struct vertexOutput \r\n" \
"{ \r\n" \
" float4 Pos : POSITION; \r\n" \
" float2 Uv : TEXTCOORD; \r\n" \
"}; \r\n" \
"vertexOutput BasicVS(appdata IN, uniform float4x4 WvpXf) \r\n" \
"{ \r\n" \
" vertexOutput OUT; \r\n" \
" float4 Po = float4(IN.Pos,1); \r\n" \
" OUT.Pos = mul(Po,WvpXf); \r\n" \
" OUT.Uv = IN.Uv; \r\n" \
" return OUT; \r\n" \
"} \r\n" \
"float4 BasicPS(vertexOutput IN) : COLOR \r\n" \
"{ \r\n" \
" float4 color = myTexture.Sample(SamplerLinear, IN.Uv); \r\n" \
" color *= baseColor; \r\n" \
" if(showAlphaMask) \r\n" \
" color = float4(color.www, 1.0f); \r\n" \
" return color; \r\n" \
"} \r\n" \
"technique10 simple \r\n" \
"{ \r\n" \
" pass p0 \r\n" \
" { \r\n" \
" SetVertexShader( CompileShader( vs_4_0, BasicVS(gWvpXf) ) ); \r\n" \
" SetGeometryShader( NULL ); \r\n" \
" SetPixelShader( CompileShader( ps_4_0, BasicPS() ) ); \r\n" \
" } \r\n" \
"} \r\n";
static const unsigned int simpleShaderLength = (unsigned int)strlen(simpleShaderCode);
buildTemporaryEffect(this,
dxDevice, simpleShaderCode, simpleShaderLength,
dxEffect, dxTechnique, numPasses,
varyingParameters, uniformParameters, indexBufferType);
resourceTexture = new ResourceTextureMap;
fFixedTextureMipMapLevels = mipmapLevels;
}
for(
int u = 0; u < uniformParameters->
length(); ++u )
{
{
if(alphaChannelIdx != -1 || layerName.
length() > 0) {
fullName +=
MString(&layerNameSeparator, 1) + layerName;
fullName +=
MString(&layerNameSeparator, 1) + alphaChannelIdx;
}
}
}
{
}
{
}
}
if(numPasses > 0)
{
if(geometry != NULL)
{
if(textureTarget != NULL)
{
updateParameters(*context, *uniformParameters, *resourceTexture, renderType);
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
if( renderTechnique(dxDevice, dxTechnique, numPasses,
textureTarget, imageWidth, imageHeight, clearColor,
*varyingParameters, renderType, indexBufferType) )
{
#ifdef USE_GL_TEXTURE_CACHING
fUVEditorGLTextureId = createGLTextureFromTarget(textureTarget, fUVEditorGLTextureScaleU, fUVEditorGLTextureScaleV);
if(fUVEditorGLTextureId > 0 && renderGLTexture(fUVEditorGLTextureId, fUVEditorGLTextureScaleU, fUVEditorGLTextureScaleV, region, unfiltered) )
#else
#endif //USE_GL_TEXTURE_CACHING
}
}
}
}
if(dxEffect)
{
CDX11EffectCompileHelper::releaseEffect(this, dxEffect, "TemporaryEffect");
delete uniformParameters;
delete varyingParameters;
releaseAllTextures(*resourceTexture);
delete resourceTexture;
}
fFixedTextureMipMapLevels = -1;
return result;
}
{
if(texture == NULL)
{
}
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 );
}
{
int alphaChannelIdx, mipmapLevels;
return getUVTexture(context, imageName, imageWidth, imageHeight, textureName, layerName, alphaChannelIdx, mipmapLevels);
}
{
unsigned int nUniform = fUniformParameters.length();
for( unsigned int i = 0; i < nUniform; i++ ) {
imageParam = elem;
break;
}
}
return NULL;
}
fForceUpdateTexture = true;
getTextureDesc(*context, imageParam, textureName, layerName, alphaChannelIdx);
mipmapLevels = 1;
{
mipmapLevels = fTechniqueTextureMipMapLevels;
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)imageParam.
userData();
if(effectVariable)
{
ID3DX11EffectShaderResourceVariable* resourceVar = effectVariable->AsShaderResource();
if(resourceVar)
getAnnotation(resourceVar, dx11ShaderAnnotation::kMipmaplevels, mipmapLevels);
}
texture = loadTexture(textureName, layerName, alphaChannelIdx, mipmapLevels);
}
releaseTexture(fUVEditorTexture);
fUVEditorTexture = texture;
if(texture)
{
imageWidth = (int)desc.
fWidth;
}
return texture;
}
{
if(fTechnique == NULL || fTechnique->IsValid() == false)
return false;
if (!theRenderer) return false;
if (!dxDevice) return false;
ID3D11DeviceContext* dxContext = NULL;
dxDevice->GetImmediateContext(&dxContext);
if (!dxContext) return false;
ERenderType renderType = RENDER_SCENE;
updateParameters(context, fUniformParameters, fResourceTextureMap, renderType);
TshadowFlagBackupState shadowFlagBackupState;
initShadowFlagBackupState(shadowFlagBackupState);
MStringArray passSem = getPassSemanticsRemovingColorPassIfNecessary(context);
bool result = false;
RenderItemList shadowOnRenderVec, shadowOffRenderVec, nonMaterialOverrideRenderVec;
int numRenderItems = renderItemList.
length();
for (int renderItemIdx=0; renderItemIdx < numRenderItems; ++renderItemIdx)
{
if (renderItem)
{
nonMaterialOverrideRenderVec.push_back(renderItem);
}
shadowOnRenderVec.push_back(renderItem);
}
else {
shadowOffRenderVec.push_back(renderItem);
}
}
}
if (!shadowOnRenderVec.empty())
{
if (!shadowFlagBackupState.empty())
setPerGeometryShadowOnFlag(true, shadowFlagBackupState);
result |= renderTechnique(dxDevice, dxContext, fTechnique, fTechniquePassCount, passSem, shadowOnRenderVec, fVaryingParameters, renderType, fTechniqueIndexBufferType);
}
if (!shadowOffRenderVec.empty())
{
if (!shadowFlagBackupState.empty())
setPerGeometryShadowOnFlag(false, shadowFlagBackupState);
result |= renderTechnique(dxDevice, dxContext, fTechnique, fTechniquePassCount, passSem, shadowOffRenderVec, fVaryingParameters, renderType, fTechniqueIndexBufferType);
}
if (!nonMaterialOverrideRenderVec.empty())
{
renderType = RENDER_SCENE_NON_MATERIAL;
result |= renderTechnique(dxDevice, dxContext, fTechnique, fTechniquePassCount, passSem, nonMaterialOverrideRenderVec, fVaryingParameters, renderType, fTechniqueIndexBufferType);
}
dxContext->Release();
return result;
}
bool dx11ShaderNode::renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique,
const RenderItemList& renderItemList,
const MVaryingParameterList& varyingParameters, ERenderType renderType,
const MString& indexBufferType)
const
{
bool result = false;
if( isRenderNonMaterialItem(renderType) )
{
size_t numRenderItems = renderItemList.size();
for (size_t renderItemIdx = 0; renderItemIdx < numRenderItems; ++renderItemIdx)
{
if(renderItem)
{
if(geometry)
{
RenderItemDesc renderItemDesc = { false, false };
updateOverrideNonMaterialItemParameters(renderItem, renderItemDesc);
int primitiveStride;
for(unsigned int passId = 0; passId < numPasses; ++passId)
{
dx11ShaderDX11Pass* dxPass = activatePass(dxDevice, dxContext, dxTechnique, passId, passSem, renderType, &renderItemDesc);
if(dxPass)
{
result |= renderPass(dxDevice, dxContext, dxPass, geometry, primitiveType, primitiveStride, varyingParameters, renderType, indexBufferType);
}
}
}
}
}
}
else
{
for(unsigned int passId = 0; passId < numPasses; ++passId)
{
dx11ShaderDX11Pass* dxPass = activatePass(dxDevice, dxContext, dxTechnique, passId, passSem, renderType);
if(dxPass)
{
result |= renderPass(dxDevice, dxContext, dxPass, renderItemList, varyingParameters, renderType, indexBufferType);
}
}
}
return result;
}
bool dx11ShaderNode::renderPass(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11Pass* dxPass,
const RenderItemList& renderItemList,
{
bool result = false;
size_t numRenderItems = renderItemList.size();
for (size_t renderItemIdx = 0; renderItemIdx < numRenderItems; ++renderItemIdx)
{
if(renderItem)
{
if(geometry)
{
int primitiveStride;
result |= renderPass(dxDevice, dxContext, dxPass, geometry, primitiveType, primitiveStride, varyingParameters, renderType, indexBufferType);
}
}
}
return result;
}
bool dx11ShaderNode::renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int numPasses,
{
bool result = false;
for(unsigned int passId = 0; passId < numPasses; ++passId)
{
dx11ShaderDX11Pass* dxPass = activatePass(dxDevice, dxContext, dxTechnique, passId, renderType);
if(dxPass)
{
result |= renderPass(dxDevice, dxContext, dxPass, geometry, primitiveType, primitiveStride, varyingParameters, renderType, indexBufferType);
}
}
return result;
}
bool dx11ShaderNode::renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int numPasses,
{
ID3D11RenderTargetView* textureView = (ID3D11RenderTargetView*)(textureTarget->
resourceHandle());
if(textureView == NULL)
return false;
if(fMayaSwatchRenderVar && needUpdateMayaSwatchRenderVar(renderType))
fMayaSwatchRenderVar->AsScalar()->SetBool( true );
ID3D11DeviceContext* dxContext = NULL;
dxDevice->GetImmediateContext(&dxContext);
ContextStates contextStates;
backupStates(dxContext, contextStates, nullptr);
dxContext->OMSetRenderTargets( 1, &textureView, NULL );
const D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (float)(width), (float)(height), 0.0f, 1.0f };
dxContext->RSSetViewports( 1, &viewport );
dxContext->ClearRenderTargetView( textureView, clearColor );
bool result = renderTechnique(dxDevice, dxContext, dxTechnique, numPasses,
varyingParameters, renderType, indexBufferType);
restoreStates(dxContext, contextStates, nullptr);
dxContext->Release();
if(fMayaSwatchRenderVar && needUpdateMayaSwatchRenderVar(renderType))
fMayaSwatchRenderVar->AsScalar()->SetBool( false );
return result;
}
bool dx11ShaderNode::renderPass(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11Pass* dxPass,
{
unsigned int vtxBufferCount = (geometry != NULL ? geometry->
vertexBufferCount() : 0);
unsigned int idxBufferCount = (geometry != NULL ? geometry->
indexBufferCount() : 0);
if(vtxBufferCount == 0 || vtxBufferCount >= D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT)
return false;
bool bContainsHullShader = passHasHullShader(dxPass);
bool bAddPNAENAdjacentEdges = false;
bool bAddPNAENDominantEdges = false;
bool bAddPNAENDominantPosition = false;
std::vector<float> floatPNAENPositionBuffer;
std::vector<float> floatPNAENUVBuffer;
if(isRenderSwatch(renderType))
{
if(indexBufferType == "PNAEN18") {
bAddPNAENAdjacentEdges = true;
bAddPNAENDominantEdges = true;
bAddPNAENDominantPosition = true;
}
else if (indexBufferType == "PNAEN9") {
bAddPNAENAdjacentEdges = true;
}
}
D3D11_INPUT_ELEMENT_DESC layout[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
ID3D11Buffer* vtxBuffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
unsigned int strides[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
unsigned int offsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
int numBoundBuffers = 0;
unsigned int vertexCount = 0;
for (unsigned int vtxId = 0; vtxId < vtxBufferCount; ++vtxId)
{
if (buffer == NULL)
continue;
if (vertexCount == 0)
if (vtxBuffer == NULL)
continue;
unsigned int fieldOffset = desc.
offset();
unsigned int fieldStride = desc.
stride();
#ifdef MAYA_PRINT_DEBUG_INFO
fprintf(
stderr,
);
#endif
MatchingParameters matchingParameters;
getDstSemanticsFromSrcVertexDescriptor(varyingParameters, desc, matchingParameters);
size_t semanticBufferCount = matchingParameters.size();
if (semanticBufferCount > 1 && isCustomSemantic)
{
for (
unsigned int iSeen = 0; iSeen < mappedVertexBuffers.
length(); ++iSeen)
{
if (mappedVertexBuffers[iSeen] == desc.
name())
{
semanticBufferCount = 0;
break;
}
}
}
if(semanticBufferCount == 0)
continue;
if (bAddPNAENAdjacentEdges &&
{
data.resize(size);
const void* values = nonConstBuffer->
map();
memcpy(&data[0], values, size * sizeof(float));
}
int inputSlot = numBoundBuffers;
for (size_t semanticId = 0; semanticId < semanticBufferCount; ++semanticId)
{
const MatchingParameter& param = matchingParameters[semanticId];
switch (vertexDataType)
{
{
fieldStride *= sizeof(float);
switch (dimension) {
case 1: layout[numBoundBuffers].Format = DXGI_FORMAT_R32_FLOAT; break;
case 2: layout[numBoundBuffers].Format = DXGI_FORMAT_R32G32_FLOAT; break;
case 3: layout[numBoundBuffers].Format = DXGI_FORMAT_R32G32B32_FLOAT; break;
case 4: layout[numBoundBuffers].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; break;
default: continue;
}
break;
}
{
fieldStride *= sizeof(int);
switch (dimension) {
case 1: layout[numBoundBuffers].Format = DXGI_FORMAT_R32_UINT; break;
case 2: layout[numBoundBuffers].Format = DXGI_FORMAT_R32G32_UINT; break;
case 3: layout[numBoundBuffers].Format = DXGI_FORMAT_R32G32B32_UINT; break;
case 4: layout[numBoundBuffers].Format = DXGI_FORMAT_R32G32B32A32_UINT; break;
default: continue;
}
break;
}
default:
continue;
}
ID3D11Buffer* customVtxBuffer = vtxBuffer;
unsigned int customFieldOffset = fieldOffset;
unsigned int customFieldStride = fieldStride;
if (isCustomSemantic)
{
layout[numBoundBuffers].SemanticIndex = 0;
if(dimension != param.dimension || elementSize != param.elementSize)
{
int bufferSize = elementSize * dimension * buffer->
vertexCount();
char *bufferData = new char[bufferSize];
::memset(bufferData, bufferSize, 0);
const D3D11_BUFFER_DESC bufDesc = { bufferSize, D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0, 0, 0 };
const D3D11_SUBRESOURCE_DATA bufData = { bufferData, 0, 0 };
customVtxBuffer = NULL;
dxDevice->CreateBuffer(&bufDesc, &bufData, &customVtxBuffer);
delete [] bufferData;
}
}
else
{
semantic = param.semantic;
int semanticIndex = param.semanticIndex;
switch (semantic) {
default: continue;
}
layout[numBoundBuffers].SemanticIndex = semanticIndex;
}
if(customVtxBuffer)
{
#ifdef MAYA_PRINT_DEBUG_INFO
fprintf(
stderr,
"VTX_BUFFER_INFO: Buffer(%d), Name(%s), BufferType(%s), BufferDimension(%d), BufferSemantic(%s), Offset(%d), Stride(%d), Handle(%p)\n",
vtxId,
dimension,
fieldOffset,
fieldStride,
vtxBuffer);
#endif
layout[numBoundBuffers].InputSlot = inputSlot;
layout[numBoundBuffers].AlignedByteOffset = 0;
layout[numBoundBuffers].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
layout[numBoundBuffers].InstanceDataStepRate = 0;
vtxBuffers[numBoundBuffers] = customVtxBuffer;
strides[numBoundBuffers] = customFieldStride;
offsets[numBoundBuffers] = customFieldOffset;
if(customVtxBuffer != vtxBuffer)
customVtxBuffer->Release();
++numBoundBuffers;
}
}
}
if (numBoundBuffers <= 0) return false;
dxContext->IASetVertexBuffers(0, numBoundBuffers, vtxBuffers, strides, offsets);
ID3D11InputLayout* inputLayout = getInputLayout(dxDevice, dxPass, numBoundBuffers, layout);
if (inputLayout == NULL) return false;
dxContext->IASetInputLayout(inputLayout);
bool result = false;
if( idxBufferCount == 0 )
{
D3D11_PRIMITIVE_TOPOLOGY topo = getPrimitiveTopology(primitiveType, primitiveStride, bContainsHullShader);
dxContext->IASetPrimitiveTopology(topo);
dxContext->Draw(vertexCount, 0);
result |= true;
}
else
{
for (unsigned int idxId = 0; idxId < idxBufferCount; ++idxId)
{
if (buffer == NULL)
continue;
if (idxBuffer == NULL)
continue;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
unsigned int formatSize = 0;
switch (indexDataType)
{
format = DXGI_FORMAT_R8_UINT;
formatSize = 1;
break;
format = DXGI_FORMAT_R16_UINT;
formatSize = 2;
break;
format = DXGI_FORMAT_R32_UINT;
formatSize = 4;
break;
default:
continue;
}
unsigned int indexBufferSize = buffer->
size();
ID3D11Buffer* customIdxBuffer = idxBuffer;
if (bAddPNAENAdjacentEdges && floatPNAENPositionBuffer.empty() == false && floatPNAENUVBuffer.empty() == false && formatSize != 2)
{
unsigned int indexCount = indexBufferSize;
void* indices = nonConstBuffer->
map();
for (unsigned int iidx = 0; iidx < indexCount; ++iidx)
{
switch (indexDataType)
{
default: continue;
}
}
unsigned int numTri = indexCount/3;
unsigned int triSize = CrackFreePrimitiveGenerator::computeTriangleSize(bAddPNAENAdjacentEdges, bAddPNAENDominantEdges, bAddPNAENDominantPosition);
indexBufferSize = numTri * triSize;
unsigned int dataBufferSize = indexBufferSize * formatSize;
indices = new char[dataBufferSize];
CrackFreePrimitiveGenerator::mutateIndexBuffer( currentIndexBuffer, &floatPNAENPositionBuffer[0], &floatPNAENUVBuffer[0],
bAddPNAENAdjacentEdges, bAddPNAENDominantEdges, bAddPNAENDominantPosition,
primitiveStride = triSize;
const D3D11_BUFFER_DESC bufDesc = { dataBufferSize, D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0, 0, 0 };
const D3D11_SUBRESOURCE_DATA bufData = { indices, 0, 0 };
customIdxBuffer = NULL;
dxDevice->CreateBuffer(&bufDesc, &bufData, &customIdxBuffer);
delete [] indices;
}
if (customIdxBuffer)
{
D3D11_PRIMITIVE_TOPOLOGY topo = getPrimitiveTopology(primitiveType, primitiveStride, bContainsHullShader);
if(topo == D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) continue;
#ifdef MAYA_PRINT_DEBUG_INFO
fprintf(stderr, "IDX_BUFFER_INFO: Buffer(%d), IndexingPrimType(%s), IndexType(%s), IndexCount(%d), Handle(%p)\n",
idxId,
indexBufferSize,
customIdxBuffer);
#endif
dxContext->IASetIndexBuffer(customIdxBuffer, format, 0);
dxContext->IASetPrimitiveTopology(topo);
dxContext->DrawIndexed(indexBufferSize, 0, 0);
result |= true;
if(customIdxBuffer != idxBuffer)
customIdxBuffer->Release();
}
}
}
return result;
}
void dx11ShaderNode::backupStates(dx11ShaderDX11DeviceContext *dxContext, ContextStates &states, const MStateManager* mayaStates) const
{
dxContext->RSGetState(&(states.rasterizerState));
dxContext->OMGetDepthStencilState(&(states.depthStencilState), &(states.stencilRef));
dxContext->OMGetBlendState(&(states.blendState), states.blendFactor, &(states.sampleMask));
if (mayaStates)
{
states.mayaBlendState = mayaStates->getBlendState();
states.mayaRasterizerState = mayaStates->getRasterizerState();
states.mayaDepthStencilState = mayaStates->getDepthStencilState();
}
}
void dx11ShaderNode::restoreStates(dx11ShaderDX11DeviceContext *dxContext, ContextStates &states, MStateManager* mayaStates) const
{
if(states.rasterizerState) {
dxContext->RSSetState(states.rasterizerState);
states.rasterizerState->Release();
states.rasterizerState = NULL;
}
if(states.depthStencilState) {
dxContext->OMSetDepthStencilState(states.depthStencilState, states.stencilRef);
states.depthStencilState->Release();
states.depthStencilState = NULL;
}
if(states.blendState) {
dxContext->OMSetBlendState(states.blendState, states.blendFactor, states.sampleMask);
states.blendState->Release();
states.blendState = NULL;
}
if (mayaStates)
{
mayaStates->setBlendState(states.mayaBlendState);
mayaStates->setDepthStencilState(states.mayaDepthStencilState);
mayaStates->setRasterizerState(states.mayaRasterizerState);
mayaStates->releaseBlendState(states.mayaBlendState);
mayaStates->releaseDepthStencilState(states.mayaDepthStencilState);
mayaStates->releaseRasterizerState(states.mayaRasterizerState);
states.mayaBlendState = nullptr;
states.mayaDepthStencilState = nullptr;
states.mayaRasterizerState = nullptr;
}
}
{
bool updateLightParameters = true;
bool updateViewParams = false;
bool updateTextures = fForceUpdateTexture;
if(isRenderScene(renderType))
{
updateLightParameters = (currentFrameStamp != fLastFrameStamp);
updateViewParams = (currentFrameStamp != fLastFrameStamp);
fLastFrameStamp = currentFrameStamp;
fForceUpdateTexture = false;
updateLightParameters = false;
}
else if(isRenderSwatch(renderType))
{
fLastFrameStamp = (MUint64)-1;
fForceUpdateTexture = false;
}
else
{
fLastFrameStamp = (MUint64)-1;
updateLightParameters = false;
updateTextures = true;
}
bool updateTransparencyTextures = false;
{
if( isRenderScene(renderType) && 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 (updateViewParams)
{
updateViewportGlobalParameters( context );
}
D3DX11_EFFECT_TYPE_DESC descType;
memset(&descType, 0, sizeof(D3DX11_EFFECT_TYPE_DESC));
for(
int u = uniformParameters.
length(); u--; ) {
if( uniform.
hasChanged(context) || lightParametersToUpdate.count(u) || (updateTextures && uniform.
isATexture()) ) {
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (!effectVariable) break;
effectVariable->GetType()->GetDesc(&descType);
switch( uniform.
type()) {
int width, height;
const float data[] = { (float)width, (float)height };
effectVariable->AsVector()->SetFloatVector( data );
}
float data = status ? tuple[0] : 0.1f ;
effectVariable->AsScalar()->SetFloat( data );
}
float data = status ? tuple[0] : 10000.0f ;
effectVariable->AsScalar()->SetFloat( data );
}
else {
if (data) {
if (descType.Class == D3D10_SVC_SCALAR) {
effectVariable->AsScalar()->SetFloat( data[0] );
} else if (descType.Class == D3D10_SVC_VECTOR) {
effectVariable->AsVector()->SetFloatVector( (float*)data );
} else if (descType.Class == D3D10_SVC_MATRIX_COLUMNS) {
effectVariable->AsMatrix()->SetMatrix( (float*)data );
} else if (descType.Class == D3D10_SVC_MATRIX_ROWS) {
effectVariable->AsMatrix()->SetMatrixTranspose( (float*)data );
} else {
}
}
}
} break;
{
if (descType.Class == D3D10_SVC_SCALAR) {
effectVariable->AsScalar()->SetInt( uniform.
getAsInt(context) );
} else {
}
} break;
if (descType.Class == D3D10_SVC_SCALAR) {
effectVariable->AsScalar()->SetBool( uniform.
getAsBool(context) );
} else {
}
} break;
} break;
default: {
ID3DX11EffectShaderResourceVariable* resourceVar = effectVariable->AsShaderResource();
if (resourceVar) {
if(updateTransparencyTextures) {
if (tex) {
resourceVar->SetResource((ID3D11ShaderResourceView*)tex->
resourceHandle());
}
}
}
if(updateTransparencyTextures) {
if (tex) {
resourceVar->SetResource((ID3D11ShaderResourceView*)tex->
resourceHandle());
}
}
} else {
int alphaChannelIdx;
getTextureDesc(context, uniform, textureName, layerName, alphaChannelIdx);
assignTexture(resourceVar, textureName, layerName, alphaChannelIdx, resourceTexture, uniform.
getSource().
node());
}
}
}
} break;
}
}
}
if(updateLightParameters)
{
updateExplicitLightConnections(context, renderType);
updateImplicitLightConnections(context, renderType);
}
return true;
}
void dx11ShaderNode::updateOverrideNonMaterialItemParameters(
const MHWRender::MRenderItem* item, RenderItemDesc& renderItemDesc )
const
{
return;
unsigned int size;
{
static const MString defaultColorParameter(
"defaultColor");
if(defaultColor && size == 4) {
static const MString solidColorUniform(
"gsSolidColor");
ID3DX11EffectVariable* effectVariable = findEffectVariable(fUniformParameters, solidColorUniform,
MUniformParameter::kTypeFloat, D3D10_SVC_VECTOR);
if( effectVariable != NULL ) {
effectVariable->AsVector()->SetFloatVector( defaultColor );
}
}
}
static const MString lineWidthParameter(
"lineWidth");
if(lineWidth && size == 2 && lineWidth[0] > 1.f && lineWidth[1] > 1.f) {
renderItemDesc.isFatLine = true;
static const MString fatLineWidthUniform(
"gsFatLineWidth");
ID3DX11EffectVariable* effectVariable = findEffectVariable(fUniformParameters, fatLineWidthUniform,
MUniformParameter::kTypeFloat, D3D10_SVC_VECTOR);
if( effectVariable != NULL ) {
effectVariable->AsVector()->SetFloatVector( lineWidth );
}
}
}
static const MString pointSizeParameter(
"pointSize");
if(pointSize && size == 2 && pointSize[0] > 1.f && pointSize[1] > 1.f) {
renderItemDesc.isFatPoint = true;
static const MString fatPointSizeUniform(
"gsFatPointSize");
ID3DX11EffectVariable* effectVariable = findEffectVariable(fUniformParameters, fatPointSizeUniform,
MUniformParameter::kTypeFloat, D3D10_SVC_VECTOR);
if( effectVariable != NULL ) {
effectVariable->AsVector()->SetFloatVector( pointSize );
}
}
}
}
{
if(fMayaGammaCorrectVar)
{
fMayaGammaCorrectVar->AsScalar()->SetBool( isGammaEnabled );
}
if (fMayaHwFogEnabled)
{
fMayaHwFogEnabled->AsScalar()->SetBool( hwFogParams.
HwFogEnabled );
if (fMayaHwFogMode)
fMayaHwFogMode->AsScalar()->SetInt( hwFogParams.
HwFogMode );
if (fMayaHwFogStart)
fMayaHwFogStart->AsScalar()->SetFloat( hwFogParams.
HwFogStart );
if (fMayaHwFogEnd)
fMayaHwFogEnd->AsScalar()->SetFloat( hwFogParams.
HwFogEnd );
if (fMayaHwFogDensity)
fMayaHwFogDensity->AsScalar()->SetFloat( hwFogParams.
HwFogDensity );
if (fMayaHwFogColor)
fMayaHwFogColor->AsVector()->SetFloatVector(&hwFogParams.
HwFogColor[0]);
}
if (fDepthRange)
{
float vNear = 0.01f;
float vFar = 100000.0f;
fDepthRange->AsScalar()->SetFloat(float(vFar-vNear));
}
}
void dx11ShaderNode::initShadowFlagBackupState(TshadowFlagBackupState& stateBackup ) const
{
if (stateBackup.empty()) {
for(size_t shaderLightIndex = 0; shaderLightIndex < fLightParameters.size(); ++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
LightParameterInfo::TConnectableParameters::const_iterator it = shaderLightInfo.fConnectableParameters.begin();
LightParameterInfo::TConnectableParameters::const_iterator itEnd = shaderLightInfo.fConnectableParameters.end();
for (; it != itEnd; ++it)
{
const int parameterType = it->second;
if (parameterType == CUniformParameterBuilder::eLightShadowOn)
{
const int parameterIndex = it->first;
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable) {
#if defined(USE_BOOL)
BOOL currentState;
#else
bool currentState;
#endif
effectVariable->AsScalar()->GetBool( ¤tState );
stateBackup.insert(TshadowFlagBackupState::value_type(parameterIndex, currentState != 0));
}
}
}
}
}
}
void dx11ShaderNode::setPerGeometryShadowOnFlag(bool receivesShadows, TshadowFlagBackupState& stateBackup ) const
{
TshadowFlagBackupState::const_iterator it = stateBackup.begin();
TshadowFlagBackupState::const_iterator itEnd = stateBackup.end();
for (; it != itEnd; ++it)
{
setParameterAsScalar(it->first, it->second && receivesShadows);
}
}
void dx11ShaderNode::clearParameters()
{
clearLightConnectionData();
fUniformParameters.setLength(0);
setUniformParameters( fUniformParameters, true );
fVaryingParametersUpdateId = 0;
fVaryingParameters.setLength(0);
setVaryingParameters( fVaryingParameters, true );
fTechniqueIsTransparent = eOpaque;
fOpacityPlugName = "";
fTransparencyTestProcName = "";
initMayaParameters();
}
void dx11ShaderNode::preBuildUniformParameterList()
{
if (!fEffect || !fTechnique) {
return;
}
fVariableNameAsAttributeName = true;
getAnnotation(fTechnique, dx11ShaderAnnotation::kVariableNameAsAttributeName, fVariableNameAsAttributeName);
}
bool dx11ShaderNode::buildUniformParameterList()
{
preBuildUniformParameterList();
setTopoDirty();
if (!fEffect) {
return false;
}
D3DX11_EFFECT_DESC desc;
memset(&desc, 0, sizeof(D3DX11_EFFECT_DESC));
fEffect->GetDesc(&desc);
fUniformParameters.setLength(0);
std::vector< CUniformParameterBuilder > builders;
std::vector< CUniformParameterBuilder* > successfulBuilder;
builders.resize(desc.GlobalVariables);
for (unsigned int i = 0; i < desc.GlobalVariables; i++)
{
ID3DX11EffectVariable* pD3DVar = fEffect->GetVariableByIndex(i);
CUniformParameterBuilder& builder = builders[i];
builder.init(pD3DVar,this,i);
if(builder.build())
{
successfulBuilder.push_back(&builder);
}
else
{
fWarningLog += builder.getWarnings();
}
}
std::sort(successfulBuilder.begin(),successfulBuilder.end(),CUniformParameterBuilder::compareUIOrder );
fUIGroupParameters.clear();
fUIGroupParameters.resize(fUIGroupNames.length());
std::vector<int> uiGroupRemapping;
uiGroupRemapping.resize(fUIGroupNames.length(), -1);
int numRemapped = 0;
std::vector< CUniformParameterBuilder* >::iterator iter = successfulBuilder.
begin();
for(; iter != successfulBuilder.end();++iter)
{
CUniformParameterBuilder* pBuilder(*iter);
fUniformParameters.append(pBuilder->getParameter());
int uiGroupIndex = pBuilder->getUIGroupIndex();
if (uiGroupIndex >= 0)
{
if (uiGroupRemapping[uiGroupIndex] == -1) {
sortedUIGroupNames.
append(fUIGroupNames[(
unsigned int)uiGroupIndex]);
uiGroupRemapping[uiGroupIndex] = numRemapped;
++numRemapped;
}
uiGroupIndex = uiGroupRemapping[uiGroupIndex];
fUIGroupParameters[uiGroupIndex].push_back(fUniformParameters.length() - 1);
}
}
fUIGroupNames = sortedUIGroupNames;
updateImplicitLightParameterCache( successfulBuilder);
displayErrorAndWarnings();
return true;
}
bool dx11ShaderNode::buildVaryingParameterList()
{
if (!fEffect) {
return false;
}
fVaryingParametersUpdateId = 0;
fVaryingParameters.setLength(0);
ID3DX11EffectTechnique* dxTechnique = fEffect->GetTechniqueByIndex( fTechniqueIdx );
if (dxTechnique)
{
D3DX11_TECHNIQUE_DESC descTechnique;
memset(&descTechnique, 0, sizeof(D3DX11_TECHNIQUE_DESC));
dxTechnique->GetDesc(&descTechnique);
::buildVaryingParameterList(dxTechnique, descTechnique.Passes, fVaryingParameters, fErrorLog, fWarningLog, fTechniqueIndexBufferType);
}
buildVertexDescriptorFromVaryingParameters();
displayErrorAndWarnings();
return true;
}
bool dx11ShaderNode::buildVertexDescriptorFromVaryingParameters()
{
fVaryingParametersVertexDescriptorList.clear();
for (int i=0; i<fVaryingParameters.length(); i++) {
sourceSetName,
sourceSemantic,
bool addDescriptor = true;
for (int iVB=0; iVB < fVaryingParametersVertexDescriptorList.length(); ++iVB) {
fVaryingParametersVertexDescriptorList.getDescriptor(iVB, existingDesc);
if (existingDesc.
name() == desc.name() &&
existingDesc.
semantic() == desc.semantic() &&
existingDesc.
dataType() == desc.dataType() &&
existingDesc.
dimension() == desc.dimension() &&
existingDesc.
offset() == desc.offset() &&
existingDesc.
stride() == desc.stride() )
{
addDescriptor = false;
break;
}
}
if (addDescriptor)
fVaryingParametersVertexDescriptorList.append(desc);
#ifdef MAYA_PRINT_DEBUG_INFO
fprintf(
stderr,
"PrepareVertexBuffer: Name(%s), SourceSemantics(%s)\n",
);
#endif
}
return true;
}
void dx11ShaderNode::initMayaParameters()
{
bool foundBBoxExtraScale = false;
float bboxExtraScaleValueFromEffect = 0.0f;
bool foundMayaSwatchRender = false;
fMayaSwatchRenderVar = NULL;
bool foundMayaGammaCorrect = false;
fMayaGammaCorrectVar = NULL;
bool foundMayaHwFogEnabled = false;
fMayaHwFogEnabled = NULL;
bool foundMayaHwFogMode = false;
fMayaHwFogMode = NULL;
bool foundMayaHwFogStart = false;
fMayaHwFogStart = NULL;
bool foundMayaHwFogEnd = false;
fMayaHwFogEnd = NULL;
bool foundMayaHwFogDensity = false;
fMayaHwFogDensity = NULL;
bool foundMayaHwFogColor = false;
fMayaHwFogColor = NULL;
bool foundDepthRange = false;
fDepthRange = NULL;
fShaderChangesGeo = false;
fIgnoreLightLimits = true;
unsigned int paramCount = fUniformParameters.length();
for( unsigned int i = 0; i < paramCount; ++i )
{
if ((foundBBoxExtraScale == false ||
foundMayaHwFogStart == false ||
foundMayaHwFogEnd == false ||
foundMayaHwFogDensity == false||
fDepthRange) &&
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if(effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
foundBBoxExtraScale = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kBboxExtraScale, varDesc.Semantic) == 0 );
if (foundBBoxExtraScale == false)
{
bool boolValue = 0;
foundBBoxExtraScale = (getAnnotation(effectVariable, dx11ShaderSemantic::kBboxExtraScale, boolValue) && boolValue);
}
if (foundBBoxExtraScale)
{
effectVariable->AsScalar()->GetFloat( &bboxExtraScaleValueFromEffect );
continue;
}
foundMayaHwFogStart = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kHwFogStart, varDesc.Semantic) == 0 );
if (foundMayaHwFogStart)
{
fMayaHwFogStart = effectVariable;
fMayaHwFogStart->AsScalar()->SetFloat( 0.0f );
continue;
}
foundMayaHwFogEnd = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kHwFogEnd, varDesc.Semantic) == 0 );
if (foundMayaHwFogEnd)
{
fMayaHwFogEnd = effectVariable;
fMayaHwFogEnd->AsScalar()->SetFloat( 100.0f );
continue;
}
foundMayaHwFogDensity = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kHwFogDensity, varDesc.Semantic) == 0 );
if (foundMayaHwFogDensity)
{
fMayaHwFogDensity = effectVariable;
fMayaHwFogDensity->AsScalar()->SetFloat( 0.1f );
continue;
}
foundDepthRange = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kLightRange, varDesc.Semantic) == 0 );
if (foundDepthRange)
{
fDepthRange = effectVariable;
fDepthRange->AsScalar()->SetFloat( 100000.0f );
continue;
}
}
}
if (foundMayaHwFogColor == false &&
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if(effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
foundMayaHwFogColor = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kHwFogColor, varDesc.Semantic) == 0 );
if (foundMayaHwFogColor)
{
fMayaHwFogColor = effectVariable;
fMayaHwFogColor->AsVector()->SetFloatVector(&fogColor[0]);
continue;
}
}
}
if( (foundMayaSwatchRender == false ||
foundMayaGammaCorrect == false ||
foundMayaHwFogEnabled == false) &&
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if(effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
foundMayaSwatchRender = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kMayaSwatchRender, varDesc.Semantic) == 0 );
if(foundMayaSwatchRender)
{
fMayaSwatchRenderVar = effectVariable;
fMayaSwatchRenderVar->AsScalar()->SetBool( false );
continue;
}
foundMayaGammaCorrect = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kMayaGammaCorrection, varDesc.Semantic) == 0 );
if(foundMayaGammaCorrect)
{
fMayaGammaCorrectVar = effectVariable;
fMayaGammaCorrectVar->AsScalar()->SetBool( false );
continue;
}
foundMayaHwFogEnabled = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kHwFogEnabled, varDesc.Semantic) == 0 );
if (foundMayaHwFogEnabled)
{
fMayaHwFogEnabled = effectVariable;
fMayaHwFogEnabled->AsScalar()->SetBool( false );
continue;
}
}
}
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if (effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
foundMayaHwFogMode = ( varDesc.Semantic != NULL && ::_stricmp(dx11ShaderSemantic::kHwFogMode, varDesc.Semantic) == 0 );
if (foundMayaHwFogMode)
{
fMayaHwFogMode = effectVariable;
fMayaHwFogMode->AsScalar()->SetInt(0);
continue;
}
}
}
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)param.
userData();
if(effectVariable)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
memset(&varDesc, 0, sizeof(D3DX11_EFFECT_VARIABLE_DESC));
effectVariable->GetDesc(&varDesc);
fShaderChangesGeo = ( varDesc.Semantic != NULL &&
( ::_stricmp(dx11ShaderSemantic::kTime, varDesc.Semantic) == 0 ||
::_stricmp(dx11ShaderSemantic::kAnimationTime, varDesc.Semantic) == 0 ||
::_stricmp(dx11ShaderSemantic::kFrameNumber, varDesc.Semantic) == 0 ||
::_stricmp(dx11ShaderSemantic::kFrame, varDesc.Semantic) == 0)
);
}
}
if(foundBBoxExtraScale && foundMayaSwatchRender && foundMayaGammaCorrect && fShaderChangesGeo)
break;
}
if(bboxExtraScalePlugName.
length() == 0)
{
fBBoxExtraScalePlugName.clear();
fBBoxExtraScaleValue = 0.0f;
return;
}
fBBoxExtraScalePlugName = bboxExtraScalePlugName;
if(fBBoxExtraScaleValue < 1.0f)
fBBoxExtraScaleValue = bboxExtraScaleValueFromEffect;
}
MStringArray dx11ShaderNode::getUIGroupParameters(
int uiGroupIndex)
const
{
if(uiGroupIndex < (int)fUIGroupParameters.size())
{
const std::vector<int> &groupParams(fUIGroupParameters[uiGroupIndex]);
for (size_t iParam=0; iParam < groupParams.size(); ++iParam)
{
appendParameterNameIfVisible(groupParams[iParam], retVal);
}
}
return retVal;
}
int dx11ShaderNode::getIndexForUIGroupName(
const MString& uiGroupName,
bool appendGroup) {
unsigned int index = 0;
for ( ; index < fUIGroupNames.length(); index++)
if ( fUIGroupNames[index] == uiGroupName || sanitizeName(fUIGroupNames[index]) == uiGroupName)
return index;
if (appendGroup)
{
fUIGroupNames.
append(uiGroupName);
return index;
}
return -1;
}
MString dx11ShaderNode::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 dx11ShaderStrings::getString( dx11ShaderStrings::kAmbient );
}
}
}
return "";
}
MStringArray dx11ShaderNode::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(CUniformParameterBuilder::getLightParameterSemantic(paramType));
}
}
}
return retVal;
}
int dx11ShaderNode::getIndexForLightName(
const MString& lightName,
bool appendLight) {
unsigned int index = 0;
for ( ; index < fLightNames.length(); index++)
if ( fLightNames[index] == lightName || sanitizeName(fLightNames[index]) == lightName)
return index;
if (appendLight)
{
fLightNames.
append(lightName);
return index;
}
return -1;
}
bool dx11ShaderNode::appendParameterNameIfVisible(
int paramIndex,
MStringArray& paramArray)
const
{
if (uniformPlug.isNull())
return false;
if (uniformAttribute.isHidden())
return false;
paramArray.
append(uniformAttribute.shortName());
return true;
}
void dx11ShaderNode::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;
}
}
}
}
MFnAttribute lAttrUseImplicitLight(fnDepThisNode.attribute(sanitizedLightGroupName +
"_use_implicit_lighting"));
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;
}
}
}
}
MFnAttribute lAttrConnectLight(fnDepThisNode.attribute(sanitizedLightGroupName +
"_connected_light"));
}
}
else
{
PostSceneUpdateAttributeRefresher::add(this);
}
}
void dx11ShaderNode::updateShaderBasedGeoChanges()
{
if (!fShaderChangesGeo)
return;
if ( abs(currentTime - fLastTime) > 0.000000001 )
{
fLastTime = currentTime;
}
}
void dx11ShaderNode::updateLightsInformation()
{
if ( fIgnoreLightLimits )
}
void dx11ShaderNode::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 dx11ShaderNode::refreshView() const
{
{
}
}
void dx11ShaderNode::setLightRequiresShadows(
const MObject& lightObject,
bool requiresShadow)
const
{
{
#ifdef MAYA_PRINT_DEBUG_INFO
fprintf(stderr,
"Clear implicit light path on disconnect light: %s\n",
MFnDagNode( lightObject ).fullPathName().asChar());
#endif
}
}
void dx11ShaderNode::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 dx11ShaderNode::updateImplicitLightConnections(
const MHWRender::MDrawContext& context, ERenderType renderType)
const
{
if(!needUpdateImplicitLightConnections(renderType))
return;
unsigned int nbSceneLightsToBind = nbSceneLights;
bool implicitLightWasRebound = false;
bool useDefaultLight = false;
if(isRenderScene(renderType) && nbSceneLights == 1)
{
const ELightType sceneLightType = getLightType(sceneLightParam);
if(sceneLightType == eDefaultLight )
{
useDefaultLight = true;
}
}
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(isRenderScene(renderType) && !useDefaultLight)
{
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 || useDefaultLight )
{
shaderLightUsesImplicit[shaderLightIndex] = true;
}
else
{
nbShaderLightsToBind--;
}
}
}
if(isRenderScene(renderType) && !useDefaultLight)
fImplicitAmbientLight = -1;
for(unsigned int shaderLightIndex = 0;
shaderLightIndex < nbShaderLights && nbShaderLightsToBind && nbSceneLightsToBind;
++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
const ELightType shaderLightType = shaderLightInfo.lightType();
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 (isRenderScene(renderType) || shaderLightInfo.fHasLightTypeSemantics)
{
sceneLightUsed[sceneLightIndex] = true;
nbSceneLightsToBind--;
}
if(isRenderScene(renderType) && !useDefaultLight)
{
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.lightType();
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 (isRenderScene(renderType) || shaderLightInfo.fHasLightTypeSemantics)
{
sceneLightUsed[sceneLightIndex] = true;
nbSceneLightsToBind--;
}
if(isRenderScene(renderType) && !useDefaultLight)
{
(
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(isRenderSwatch(renderType) || useDefaultLight)
{
(const_cast<LightParameterInfo&>(shaderLightInfo)).fIsDirty = true;
}
}
if (implicitLightWasRebound)
IdleAttributeEditorImplicitRefresher::activate();
}
void dx11ShaderNode::updateExplicitLightConnections(
const MHWRender::MDrawContext& context, ERenderType renderType)
const
{
if(!needUpdateExplicitLightConnections(renderType))
return;
unsigned int nbShaderLights = (unsigned int)fLightParameters.size();
if(nbShaderLights < 0)
return;
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);
}
}
}
}
}
void dx11ShaderNode::updateImplicitLightParameterCache(std::vector<CUniformParameterBuilder*>& builders)
{
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);
}
}
fLightParameters.
clear();
fLightParameters.resize(fLightNames.length());
refreshLightConnectionAttributes();
std::vector<CUniformParameterBuilder*>::iterator iter = builders.begin();
int index = 0;
CUniformParameterBuilder::ELightType currLightType = CUniformParameterBuilder::eNotLight;
CUniformParameterBuilder::ELightParameterType paramType;
for(;iter != builders.end();++iter,++index)
{
CUniformParameterBuilder* currBuilder = *iter;
if(!currBuilder->isValidUniformParameter())
continue;
int lightIndex = currBuilder->getLightIndex();
if (lightIndex < 0)
continue;
LightParameterInfo& currLight(fLightParameters[lightIndex]);
if(currBuilder->getLightType() != CUniformParameterBuilder::eNotLight)
{
if(currLightType == CUniformParameterBuilder::eNotLight)
{
currLightType = currBuilder->getLightType();
}
paramType = currBuilder->getLightParameterType();
if (paramType == CUniformParameterBuilder::eLightType)
{
currLight.fHasLightTypeSemantics = true;
}
currLight.fConnectableParameters.insert(LightParameterInfo::TConnectableParameters::value_type(index, paramType));
switch(currBuilder->getLightType())
{
case CUniformParameterBuilder::eUndefinedLight:
currLight.fLightType = eUndefinedLight;
break;
case CUniformParameterBuilder::eSpotLight:
currLight.fLightType = eSpotLight;
break;
case CUniformParameterBuilder::ePointLight:
currLight.fLightType = ePointLight;
break;
case CUniformParameterBuilder::eDirectionalLight:
currLight.fLightType = eDirectionalLight;
break;
case CUniformParameterBuilder::eAmbientLight:
currLight.fLightType = eAmbientLight;
break;
case CUniformParameterBuilder::eAreaLight:
currLight.fLightType = eAreaLight;
break;
default:
break;
};
}
}
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->fLightType)
{
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 dx11ShaderNode::clearLightConnectionData()
{
for (size_t i = 0; i < fLightParameters.size(); ++i) {
fLightParameters[i].fCachedImplicitLight =
MObject();
setLightParameterLocking(fLightParameters[i], false);
}
fLightNames.setLength(0);
fUIGroupNames.setLength(0);
fUIGroupParameters.clear();
fLightDescriptions.setLength(0);
}
void dx11ShaderNode::getLightParametersToUpdate(std::set<int>& parametersToUpdate, ERenderType renderType) const
{
for(size_t shaderLightIndex = 0; shaderLightIndex < fLightParameters.size(); ++shaderLightIndex )
{
const LightParameterInfo& shaderLightInfo = fLightParameters[shaderLightIndex];
if (shaderLightInfo.fIsDirty || !isRenderScene(renderType))
{
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 (isRenderScene(renderType))
{
MPlug useImplicitPlug = depFn.findPlug( shaderLightInfo.fAttrUseImplicit,
false );
if( !useImplicitPlug.
isNull() ) {
bool useImplicit;
useImplicitPlug.
getValue( useImplicit );
if (!useImplicit)
{
(const_cast<LightParameterInfo&>(shaderLightInfo)).fIsDirty = false;
}
}
}
}
}
}
{
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;
ID3D11ShaderResourceView *shadowResource = NULL;
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 == CUniformParameterBuilder::eLightType) {
setParameterAsScalar(parameterIndex, lightType != dx11ShaderNode::eDefaultLight? (int)lightType : dx11ShaderNode::eDirectionalLight);
continue;
}
if (parameterType == CUniformParameterBuilder::eLightEnable) {
setParameterAsScalar(parameterIndex, true);
continue;
}
const MStringArray& params(drawContextParameterNames(lightType, parameterType, lightParam));
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;
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 CUniformParameterBuilder::eLightColor:
case CUniformParameterBuilder::eLightAmbientColor:
case CUniformParameterBuilder::eLightSpecularColor:
case CUniformParameterBuilder::eLightDiffuseColor:
{
if (!isRenderScene(renderType) && lightInfo.fLightType == eAmbientLight)
{
color[0] *= 0.15f;
color[1] *= 0.15f;
color[2] *= 0.15f;
}
setParameterAsVector(parameterIndex, (float*)&color[0]);
}
break;
case CUniformParameterBuilder::eLightPosition:
case CUniformParameterBuilder::eLightAreaPosition0:
case CUniformParameterBuilder::eLightAreaPosition1:
case CUniformParameterBuilder::eLightAreaPosition2:
case CUniformParameterBuilder::eLightAreaPosition3:
setParameterAsVector(parameterIndex, (float*)&position[0]);
positionCount = 0;
break;
case CUniformParameterBuilder::eLightIntensity:
setParameterAsScalar(parameterIndex, intensity);
break;
case CUniformParameterBuilder::eDecayRate:
setParameterAsScalar(parameterIndex, decayRate);
break;
case CUniformParameterBuilder::eLightDirection:
setParameterAsVector(parameterIndex, (float*)&direction[0]);
break;
case CUniformParameterBuilder::eLightShadowMapBias:
setParameterAsScalar(parameterIndex, shadowBias);
break;
case CUniformParameterBuilder::eLightShadowColor:
setParameterAsVector(parameterIndex, (float*)&shadowColor[0]);
break;
case CUniformParameterBuilder::eLightShadowOn:
{
bool localShadowsDirty = false;
localShadowsDirty = (intVals[0] != 0) ? true : false;
setParameterAsScalar(parameterIndex, globalShadowsOn && localShadowsOn && shadowResource &&
!localShadowsDirty);
break;
}
case CUniformParameterBuilder::eLightShadowViewProj:
setParameterAsMatrix(parameterIndex, shadowViewProj);
break;
case CUniformParameterBuilder::eLightShadowMap:
setParameterAsResource(parameterIndex, shadowResource);
break;
case CUniformParameterBuilder::eLightHotspot:
setParameterAsScalar(parameterIndex, float(hotspot.asRadians()));
break;
case CUniformParameterBuilder::eLightFalloff:
setParameterAsScalar(parameterIndex, float(falloff.asRadians()));
break;
default:
break;
}
}
}
bool dx11ShaderNode::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 CUniformParameterBuilder::eLightType:
setParameterAsScalar(parameterIndex, (int)eAmbientLight);
break;
case CUniformParameterBuilder::eLightEnable:
setParameterAsScalar(parameterIndex, true);
break;
case CUniformParameterBuilder::eLightColor:
case CUniformParameterBuilder::eLightAmbientColor:
case CUniformParameterBuilder::eLightSpecularColor:
case CUniformParameterBuilder::eLightDiffuseColor:
{
MColor ambientColor(ambientLight.color());
float color[3];
setParameterAsVector(parameterIndex, color);
}
break;
case CUniformParameterBuilder::eLightIntensity:
setParameterAsScalar(parameterIndex, ambientLight.intensity());
break;
}
}
}
}
return bDidConnect;
}
void dx11ShaderNode::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 CUniformParameterBuilder::eLightEnable:
setParameterAsScalar(parameterIndex, false);
break;
case CUniformParameterBuilder::eLightColor:
case CUniformParameterBuilder::eLightAmbientColor:
case CUniformParameterBuilder::eLightSpecularColor:
case CUniformParameterBuilder::eLightDiffuseColor:
setParameterAsVector(parameterIndex, (float*)kOffColor);
break;
case CUniformParameterBuilder::eLightIntensity:
setParameterAsScalar(parameterIndex, 0.0f);
break;
}
}
}
void dx11ShaderNode::setLightParameterLocking(const LightParameterInfo& lightInfo, bool locked) 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);
}
}
}
{
return NULL;
if(theRenderer == NULL)
return NULL;
if(txtManager == NULL)
return NULL;
int idx = textureName.
rindexW(L
'.');
if(idx > 0)
{
}
bool isEXR = (extension == "exr");
args.setFileTextureNode(node);
#ifdef MAYA_PRINT_DEBUG_INFO
if(texture == NULL)
{
printf(
"-- Texture %s not found.\n", textureName.
asChar());
}
#endif
return texture;
}
{
if (texture)
{
if (theRenderer)
{
{
if (txtManager)
{
}
}
}
}
}
void dx11ShaderNode::assignTexture(dx11ShaderDX11EffectShaderResourceVariable* resourceVar,
const MString& textureName,
const MString& layerName,
int alphaChannelIdx, ResourceTextureMap& resourceTexture,
MObject node)
const
{
int mipmapLevels = fFixedTextureMipMapLevels;
if(mipmapLevels < 0)
{
mipmapLevels = fTechniqueTextureMipMapLevels;
getAnnotation(resourceVar, dx11ShaderAnnotation::kMipmaplevels, mipmapLevels);
}
MHWRender::MTexture* texture = loadTexture(textureName, layerName, alphaChannelIdx, mipmapLevels, node);
ID3D11ShaderResourceView* resource = NULL;
if(texture != NULL)
{
#ifdef MAYA_PRINT_DEBUG_INFO
printf(
"-- Texture activate : new texture %s loaded and bound.\n", textureName.
asChar());
#endif
}
resourceVar->SetResource( resource );
ResourceTextureMap::iterator it = resourceTexture.find(resourceVar);
if(it != resourceTexture.end()) {
releaseTexture(it->second);
resourceTexture.erase(it);
}
if(texture != NULL) {
resourceTexture[resourceVar] = texture;
}
}
void dx11ShaderNode::releaseAllTextures(ResourceTextureMap& resourceTexture) const
{
ResourceTextureMap::iterator it = resourceTexture.begin();
ResourceTextureMap::iterator itEnd = resourceTexture.end();
for(; it != itEnd; ++it) {
releaseTexture(it->second);
}
resourceTexture.clear();
}
void dx11ShaderNode::releaseAllTextures()
{
releaseAllTextures(fResourceTextureMap);
}
bool dx11ShaderNode::getTextureFile(
const MString& uniformName,
MString& textureFile)
const
{
if(fDuplicateNodeSource)
{
return true;
}
return false;
}
void dx11ShaderNode::setParameterAsVector(int inParamIndex, float* data) const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
effectVariable->AsVector()->SetFloatVector( data );
}
}
void dx11ShaderNode::setParameterAsScalar(int inParamIndex, float data) const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
effectVariable->AsScalar()->SetFloat( data );
}
}
void dx11ShaderNode::setParameterAsScalar(int inParamIndex, bool data) const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
effectVariable->AsScalar()->SetBool( data );
}
}
void dx11ShaderNode::setParameterAsScalar(int inParamIndex, int data) const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
effectVariable->AsScalar()->SetInt( data );
}
}
void dx11ShaderNode::setParameterAsMatrix(
int inParamIndex,
MMatrix& data)
const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
{
float matrix[4][4];
effectVariable->AsMatrix()->SetMatrix( (float*)&matrix[0] );
}
}
}
void dx11ShaderNode::setParameterAsResource(int inParamIndex, ID3D11ShaderResourceView* inResource) const
{
if( inParamIndex > -1 && inResource)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
effectVariable->AsShaderResource()->SetResource( inResource );
}
}
void dx11ShaderNode::setParameterFromUniformAsVector(
int inParamIndex,
const MHWRender::MDrawContext& context,
const float *data)
const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
{
if(data == NULL)
effectVariable->AsVector()->SetFloatVector( data );
}
}
}
void dx11ShaderNode::setParameterFromUniformAsScalar(
int inParamIndex,
const MHWRender::MDrawContext& context)
const
{
if( inParamIndex > -1)
{
ID3DX11EffectVariable* effectVariable = (ID3DX11EffectVariable *)uniform.
userData();
if (effectVariable)
effectVariable->AsScalar()->SetFloat( uniform.
getAsFloat(context) );
}
}
{
if (isDirty(fVaryingParametersGeometryVersionId))
{
buildVertexDescriptorFromVaryingParameters();
fVaryingParametersGeometryVersionId = fGeometryVersionId;
}
return &fVaryingParametersVertexDescriptorList;
}
void dx11ShaderNode::displayErrorAndWarnings() const
{
MPlug diagnosticsPlug( thisMObject(), sDiagnostics);
diagnosticsPlug.getValue(currentDiagnostic);
if(fErrorLog.length())
{
currentDiagnostic += dx11ShaderStrings::getString( dx11ShaderStrings::kErrorLog, fErrorLog );
diagnosticsPlug.setValue( currentDiagnostic );
{
AfterOpenErrorCB::addError(fErrorLog);
}
else
{
}
fErrorLog.clear();
}
if(fWarningLog.length())
{
currentDiagnostic += dx11ShaderStrings::getString( dx11ShaderStrings::kWarningLog, fWarningLog );
diagnosticsPlug.setValue( currentDiagnostic );
fWarningLog.clear();
}
}
#define DX11SHADER_ERROR_LIMIT 20
void dx11ShaderNode::reportInternalError( const char* function, size_t errcode ) const
{
try
{
if ( this )
{
if ( ++fErrorCount > DX11SHADER_ERROR_LIMIT )
return;
s += "\"";
s += name();
s += "\": ";
s += typeName();
es = s;
}
}
catch ( ... )
{}
es += " internal error ";
es += (int)errcode;
es += " in ";
es += function;
}
{
addExternalContentForFileAttr(table, sShader);
}
{
setExternalContentForFileAttr(sShader, table);
}