#if _MSC_VER >= 1700
#pragma warning( disable: 4005 )
#endif
#include "dx11ShaderUniformParamBuilder.h"
#include "dx11Shader.h"
#include "dx11ShaderStrings.h"
#include "dx11ShaderCompileHelper.h"
#include "dx11ShaderSemantics.h"
namespace
{
{
int at = haystack.
indexW(needle);
if(at < 0)
{
at = haystack.
indexW(needleLowerCase);
}
return at;
}
}
CUniformParameterBuilder::CUniformParameterBuilder()
:mEffectVariable(NULL)
,mShader(NULL)
,mParamType(eUndefined)
,mLightType(eNotLight)
,mLightIndex(-1)
,mUIGroupIndex(-1)
,mValidUniformParameter(false)
,mUIOrder(-1)
,mAnnotationIndex()
{}
void CUniformParameterBuilder::init(ID3DX11EffectVariable* inEffectVariable,dx11ShaderNode* inShader, int order)
{
mEffectVariable = inEffectVariable;
mShader = inShader;
mUIOrder = order;
if(mEffectVariable)
{
mEffectVariable->GetDesc(&mDesc);
mEffectVariable->GetType()->GetDesc(&mDescType);
}
}
bool CUniformParameterBuilder::build()
{
updateLightInfoFromSemantic();
{
if (mDesc.Semantic && _stricmp(mDesc.Semantic, dx11ShaderSemantic::kSTANDARDSGLOBAL)==0)
{
return false;
}
}
if (mUIGroupIndex == -1)
{
LPCSTR pszUIGroupName;
if( getAnnotation( dx11ShaderAnnotation::kUIGroup, pszUIGroupName) && *pszUIGroupName)
{
MString uiGroupName(pszUIGroupName);
mUIGroupIndex = mShader->getIndexForUIGroupName(uiGroupName, true);
}
}
LPCSTR paramName = NULL;
bool varAsAttr = false;
if (mShader)
varAsAttr = mShader->getVariableNameAsAttributeName();
LPCSTR uiName = NULL ;
bool hasUIName = getAnnotation( dx11ShaderAnnotation::kUIName, uiName);
if( varAsAttr || !hasUIName )
paramName = mDesc.Name;
else
paramName = uiName;
LPCSTR uiFieldNames = NULL ;
{
fieldNames = uiFieldNames;
}
MUniformParameter uniform( paramName, type, semantic, mDescType.Rows, mDescType.Columns, (
void*)mEffectVariable);
mParam = uniform;
if (varAsAttr && hasUIName)
mParam.setUINiceName( uiName );
updateRangeFromAnnotation();
updateUIVisibilityFromAnnotation();
{
mParam.setEnumFieldNames(fieldNames);
}
getAnnotation(dx11ShaderAnnotation::kUIOrder, mUIOrder);
mParam.setKeyable(!mParam.UIHidden() && !mParam.isATexture());
bool result = setParameterValueFromEffect();
if(result)
{
mValidUniformParameter = true;
}
return result;
}
void CUniformParameterBuilder::updateUIVisibilityFromAnnotation()
{
BOOL visible = TRUE;
if( getBOOLAnnotation( dx11ShaderAnnotation::kSasUiVisible, visible))
{
mParam.setUIHidden(!visible);
}
else
{
LPCSTR uiTypeValue = NULL;
bool foundUIType = getAnnotation( dx11ShaderAnnotation::kUIType,uiTypeValue);
if (foundUIType && !_stricmp(uiTypeValue, dx11ShaderAnnotationValue::kNone))
{
mParam.setUIHidden(true);
}
foundUIType = getAnnotation( dx11ShaderAnnotation::kUIWidget,uiTypeValue);
if (foundUIType && !_stricmp(uiTypeValue, dx11ShaderAnnotationValue::kNone))
{
mParam.setUIHidden(true);
}
}
}
void CUniformParameterBuilder::updateRangeFromAnnotation()
{
switch(mParam.type())
{
{
float uiMinFloat = NULL;
if(getAnnotation( dx11ShaderAnnotation::kSasUiMin,uiMinFloat) ||
getAnnotation( dx11ShaderAnnotation::kUIMin,uiMinFloat) ||
getAnnotation( dx11ShaderAnnotation::kuimin,uiMinFloat) )
{
mParam.setRangeMin(uiMinFloat);
}
float uiMaxFloat = NULL;
if(getAnnotation( dx11ShaderAnnotation::kSasUiMax,uiMaxFloat) ||
getAnnotation( dx11ShaderAnnotation::kUIMax,uiMaxFloat) ||
getAnnotation( dx11ShaderAnnotation::kuimax,uiMaxFloat) )
{
mParam.setRangeMax(uiMaxFloat);
}
float uiSoftMinFloat = NULL;
if(getAnnotation( dx11ShaderAnnotation::kSasUiSoftMin,uiSoftMinFloat) ||
getAnnotation( dx11ShaderAnnotation::kUISoftMin,uiSoftMinFloat) ||
getAnnotation( dx11ShaderAnnotation::kuisoftmin,uiSoftMinFloat) )
{
mParam.setSoftRangeMin(uiSoftMinFloat);
}
float uiSoftMaxFloat = NULL;
if(getAnnotation( dx11ShaderAnnotation::kSasUiSoftMax,uiSoftMaxFloat) ||
getAnnotation( dx11ShaderAnnotation::kUISoftMax,uiSoftMaxFloat) ||
getAnnotation( dx11ShaderAnnotation::kuisoftmax,uiSoftMaxFloat) )
{
mParam.setSoftRangeMax(uiSoftMaxFloat);
}
}
break;
default:
break;
};
}
bool CUniformParameterBuilder::setParameterValueFromEffect()
{
int length = getLength();
switch( type )
{
{
std::vector<FLOAT> values;
values.resize(length);
FLOAT* Value = &values[0];
switch(mDescType.Class)
{
case D3D10_SVC_SCALAR:
mEffectVariable->AsScalar()->GetFloat( Value );
break;
case D3D10_SVC_VECTOR:
mEffectVariable->AsVector()->GetFloatVector( Value );
break;
case D3D10_SVC_MATRIX_COLUMNS:
mEffectVariable->AsMatrix()->GetMatrix( Value );
break;
case D3D10_SVC_MATRIX_ROWS:
mEffectVariable->AsMatrix()->GetMatrixTranspose( Value );
break;
default:
return false;
};
mParam.setAsFloatArray( Value, length);
}
break;
{
if (length==1)
{
LPCSTR Value;
if( mEffectVariable->AsString()->GetString( &Value) == S_OK)
{
mParam.setAsString(
MString( Value));
}
}
else
{
logUnsupportedTypeWarning(dx11ShaderStrings::kTypeStringVector);
return false;
}
}
break;
{
if (length==1)
{
#if defined(USE_BOOL)
BOOL Value;
#else
bool Value;
#endif
if( mEffectVariable->AsScalar()->GetBool( &Value) == S_OK)
{
mParam.setAsBool( Value ? true : false);
}
}
else
{
logUnsupportedTypeWarning(dx11ShaderStrings::kTypeBoolVector);
return false;
}
}
break;
{
if (length==1)
{
INT Value;
if( mEffectVariable->AsScalar()->GetInt( &Value) == S_OK)
{
mParam.setAsInt( Value);
}
}
else
{
logUnsupportedTypeWarning(dx11ShaderStrings::kTypeIntVector);
return false;
}
}
break;
default:
{
LPCSTR resource;
if( mShader->getTextureFile( paramName, textureFile ) )
{
mParam.setAsString( textureFile );
}
else if( getAnnotation( dx11ShaderAnnotation::kResourceName, resource) && *resource)
{
mParam.setAsString( mShader->findResource(
MString( resource), CDX11EffectCompileHelper::resolveShaderFileName(mShader->effectName()) ));
}
else if( getAnnotation( dx11ShaderAnnotation::kSasResourceAddress, resource) && *resource)
{
mParam.setAsString( mShader->findResource(
MString( resource), CDX11EffectCompileHelper::resolveShaderFileName(mShader->effectName()) ));
}
}
else
{
return false;
}
}
return true;
}
{
switch( mDescType.Type) {
case D3D10_SVT_UINT8:
logUnsupportedTypeWarning(dx11ShaderStrings::kTypeIntUInt8);
break;
case D3D11_SVT_DOUBLE:
logUnsupportedTypeWarning(dx11ShaderStrings::kTypeDouble);
break;
case D3D11_SVT_RWTEXTURE1D:
case D3D11_SVT_RWTEXTURE2D:
case D3D11_SVT_RWTEXTURE3D:
case D3D10_SVT_TEXTURE:
{
LPCSTR textureType;
if( ( getAnnotation( dx11ShaderAnnotation::kTextureType, textureType) || getAnnotation( dx11ShaderAnnotation::kResourceType, textureType)) && textureType) {
else {
mWarnings += dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownTextureSemantic, args );
}
}
mWarnings += dx11ShaderStrings::getString( dx11ShaderStrings::kNoTextureType, mDesc.Name );
}
break;
}
case D3D10_SVT_TEXTURE1DARRAY:
case D3D10_SVT_TEXTURE2DARRAY:
case D3D10_SVT_TEXTURE2DMS:
case D3D10_SVT_TEXTURE2DMSARRAY:
case D3D10_SVT_TEXTURECUBEARRAY:
case D3D11_SVT_RWTEXTURE1DARRAY:
case D3D11_SVT_RWTEXTURE2DARRAY:
logUnsupportedTypeWarning(dx11ShaderStrings::kTypeTextureArray);
break;
case D3D10_SVT_VOID:
case D3D10_SVT_SAMPLER:
case D3D10_SVT_PIXELSHADER:
case D3D10_SVT_VERTEXSHADER:
case D3D10_SVT_GEOMETRYSHADER:
case D3D10_SVT_RASTERIZER:
case D3D10_SVT_DEPTHSTENCIL:
case D3D10_SVT_BLEND:
case D3D10_SVT_BUFFER:
case D3D10_SVT_CBUFFER:
case D3D10_SVT_TBUFFER:
case D3D11_SVT_HULLSHADER:
case D3D11_SVT_DOMAINSHADER:
case D3D11_SVT_INTERFACE_POINTER:
case D3D11_SVT_COMPUTESHADER:
case D3D11_SVT_BYTEADDRESS_BUFFER:
case D3D11_SVT_RWBYTEADDRESS_BUFFER:
case D3D11_SVT_STRUCTURED_BUFFER:
case D3D11_SVT_RWSTRUCTURED_BUFFER:
case D3D11_SVT_APPEND_STRUCTURED_BUFFER:
case D3D11_SVT_CONSUME_STRUCTURED_BUFFER:
case D3D10_SVT_RENDERTARGETVIEW:
case D3D10_SVT_DEPTHSTENCILVIEW:
case D3D11_SVT_RWBUFFER:
break;
default:
break;
}
return paramType;
}
{
LPCSTR ann;
if( getAnnotation( dx11ShaderAnnotation::kSpace, ann) && ann)
{
else
{
mWarnings += dx11ShaderStrings::getString( dx11ShaderStrings::kUnknowSpace, args );
}
}
return space;
}
{
if( mDesc.Semantic)
{
else
{
logUnrecognisedSemantic(mDesc.Semantic);
}
}
{
LPCSTR sasSemantic;
if( getAnnotation( dx11ShaderAnnotation::kSasBindAddress, sasSemantic) && sasSemantic && *sasSemantic)
{
else if( str.rindexW( dx11ShaderAnnotationValue::k_Direction) >= 0 &&
str.rindexW( dx11ShaderAnnotationValue::k_Direction) != str.rindexW( dx11ShaderAnnotationValue::k_Directional)) paramSemantic = convertSpace(
MUniformParameter::kSemanticViewDir);
else
{
logUnrecognisedSemantic(sasSemantic);
}
}
}
{
LPCSTR sasSemantic;
if( (getAnnotation( dx11ShaderAnnotation::kSasUiControl, sasSemantic) || getAnnotation( dx11ShaderAnnotation::kUIWidget, sasSemantic)) && *sasSemantic)
{
}
}
mDescType.Class == D3D_SVC_VECTOR && (mDescType.Type == D3D_SVT_FLOAT || mDescType.Type == D3D_SVT_DOUBLE) &&
mDescType.Rows == 1 && mDescType.Columns >= 3 && mDescType.Columns <= 4 )
{
else if( name.rindexW( dx11ShaderAnnotationValue::kDirection) >= 0 &&
name.rindexW( dx11ShaderAnnotationValue::kDirection) != name.rindexW( dx11ShaderAnnotationValue::kDirectional)) paramSemantic = convertSpace(
MUniformParameter::kSemanticWorldDir);
else if( name.rindexW( dx11ShaderAnnotationValue::kColor) >= 0 ||
name.rindexW( dx11ShaderAnnotationValue::kColour) >= 0 ||
name.rindexW( dx11ShaderAnnotationValue::kDiffuse) >= 0 ||
name.rindexW( dx11ShaderAnnotationValue::kSpecular) >= 0 ||
}
return paramSemantic;
}
void CUniformParameterBuilder::updateLightInfoFromSemantic()
{
LPCSTR objectType;
if( getAnnotation( dx11ShaderAnnotation::kObject, objectType) && *objectType)
{
MString objectAnnotation(objectType);
mLightIndex = mShader->getIndexForLightName(objectAnnotation, true);
mUIGroupIndex = mShader->getIndexForUIGroupName(objectAnnotation, true);
if(objectAnnotation.rindexW(dx11ShaderAnnotationValue::kLight) >= 0 || objectAnnotation.rindexW(dx11ShaderAnnotationValue::kLamp) >= 0)
{
mLightType = eUndefinedLight;
if(objectAnnotation.rindexW(dx11ShaderAnnotationValue::kPoint) >= 0)
{
mLightType = ePointLight;
}
else if(objectAnnotation.rindexW(dx11ShaderAnnotationValue::kSpot) >= 0)
{
mLightType = eSpotLight;
}
else if(objectAnnotation.rindexW(dx11ShaderAnnotationValue::kDirectional) >= 0)
{
mLightType = eDirectionalLight;
}
else if(objectAnnotation.rindexW(dx11ShaderAnnotationValue::kAmbient) >= 0)
{
mLightType = eAmbientLight;
}
}
}
if( mDesc.Semantic)
{
if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightColor))
{
mParamType = eLightColor;
}
if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightEnable))
{
mParamType = eLightEnable;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightIntensity))
{
mParamType = eLightIntensity;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightFalloff) ||
!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kFalloff))
{
mLightType = eSpotLight;
mParamType = eLightFalloff;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightDiffuseColor))
{
mParamType = eLightDiffuseColor;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightAmbientColor))
{
mParamType = eLightAmbientColor;
mLightType = eAmbientLight;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightSpecularColor))
{
mParamType = eLightSpecularColor;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kShadowMap))
{
mParamType = eLightShadowMap;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kShadowMapBias))
{
mParamType = eLightShadowMapBias;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kShadowFlag))
{
mParamType = eLightShadowOn;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kShadowMapMatrix) ||
!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kShadowMapXForm))
{
mParamType = eLightShadowViewProj;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kShadowColor))
{
mParamType = eLightShadowColor;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kHotspot))
{
mParamType = eLightHotspot;
mLightType = eSpotLight;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kLightType))
{
mParamType = eLightType;
}
else if (!_stricmp( mDesc.Semantic, dx11ShaderSemantic::kDecayRate))
{
mParamType = eDecayRate;
}
else
{
bool isLight = (mLightType != eNotLight || findSubstring(name,
MString(dx11ShaderAnnotationValue::kLight)) >= 0);
if(isLight)
{
if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kPosition))
{
mParamType = eLightPosition;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kAreaPosition0))
{
mParamType = eLightAreaPosition0;
mLightType = eAreaLight;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kAreaPosition1))
{
mParamType = eLightAreaPosition1;
mLightType = eAreaLight;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kAreaPosition2))
{
mParamType = eLightAreaPosition2;
mLightType = eAreaLight;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kAreaPosition3))
{
mParamType = eLightAreaPosition3;
mLightType = eAreaLight;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kDirection))
{
mParamType = eLightDirection;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kColor))
{
mParamType = eLightColor;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kAmbient))
{
mParamType = eLightAmbientColor;
mLightType = eAmbientLight;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kDiffuse))
{
mParamType = eLightDiffuseColor;
}
else if( !_stricmp( mDesc.Semantic, dx11ShaderSemantic::kSpecular))
{
mParamType = eLightSpecularColor;
}
}
}
if(mParamType != eUndefined && mLightIndex == -1)
{
if(mLightType == eNotLight)
{
mLightType = eUndefinedLight;
}
const char* objectName = name.asChar();
int truncationPos = -1;
int lightPos = findSubstring(name,
MString(dx11ShaderAnnotationValue::kLight));
if (lightPos >= 0)
truncationPos = lightPos + 5;
if(truncationPos < 0)
{
unsigned int digitPos = 0;
for ( ; digitPos < name.numChars(); ++digitPos)
if ( isdigit(objectName[digitPos]) )
break;
if ( digitPos < name.numChars() )
truncationPos = digitPos;
}
if (truncationPos >= 0)
{
int maxChars = int(name.numChars());
while (truncationPos < maxChars && isdigit(objectName[truncationPos]))
truncationPos++;
mLightIndex = mShader->getIndexForLightName(name.substring(0,truncationPos-1), true);
mUIGroupIndex = mShader->getIndexForUIGroupName(name.substring(0,truncationPos-1), true);
}
}
}
}
MString& CUniformParameterBuilder::getLightParameterSemantic(
int lightParameterType) {
if (lightParameterType < 0 || lightParameterType >= eLastParameterType)
lightParameterType = eUndefined;
if (!semanticNames.
length()) {
semanticNames.
append(dx11ShaderSemantic::kUndefined);
semanticNames.
append(dx11ShaderSemantic::kPosition);
semanticNames.
append(dx11ShaderSemantic::kDirection);
semanticNames.
append(dx11ShaderSemantic::kLightColor);
semanticNames.
append(dx11ShaderSemantic::kLightSpecularColor);
semanticNames.
append(dx11ShaderSemantic::kLightAmbientColor);
semanticNames.
append(dx11ShaderSemantic::kLightDiffuseColor);
semanticNames.
append(dx11ShaderSemantic::kLightRange);
semanticNames.
append(dx11ShaderSemantic::kFalloff);
semanticNames.
append(dx11ShaderSemantic::kLightAttenuation0);
semanticNames.
append(dx11ShaderSemantic::kLightAttenuation1);
semanticNames.
append(dx11ShaderSemantic::kLightAttenuation2);
semanticNames.
append(dx11ShaderSemantic::kLightTheta);
semanticNames.
append(dx11ShaderSemantic::kLightPhi);
semanticNames.
append(dx11ShaderSemantic::kShadowMap);
semanticNames.
append(dx11ShaderSemantic::kShadowMapBias);
semanticNames.
append(dx11ShaderSemantic::kShadowColor);
semanticNames.
append(dx11ShaderSemantic::kShadowMapMatrix);
semanticNames.
append(dx11ShaderSemantic::kShadowFlag);
semanticNames.
append(dx11ShaderSemantic::kLightIntensity);
semanticNames.
append(dx11ShaderSemantic::kHotspot);
semanticNames.
append(dx11ShaderSemantic::kLightEnable);
semanticNames.
append(dx11ShaderSemantic::kLightType);
semanticNames.
append(dx11ShaderSemantic::kDecayRate);
semanticNames.
append(dx11ShaderSemantic::kAreaPosition0);
semanticNames.
append(dx11ShaderSemantic::kAreaPosition1);
semanticNames.
append(dx11ShaderSemantic::kAreaPosition2);
semanticNames.
append(dx11ShaderSemantic::kAreaPosition3);
}
return semanticNames[lightParameterType];
}
ID3DX11EffectVariable* CUniformParameterBuilder::findAnnotationByName(ID3DX11EffectVariable *effectVariable, const char* name)
{
if (mAnnotationIndex.empty())
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
effectVariable->GetDesc(&varDesc);
for (uint32_t idx = 0; idx < varDesc.Annotations; ++idx)
{
ID3DX11EffectVariable* var = effectVariable->GetAnnotationByIndex(idx);
if (var)
{
D3DX11_EFFECT_VARIABLE_DESC varDesc;
var->GetDesc(&varDesc);
mAnnotationIndex.
insert(TAnnotationIndex::value_type(std::string(varDesc.Name), idx));
}
}
mAnnotationIndex.insert(TAnnotationIndex::value_type(std::string("Done!"), 0));
}
TAnnotationIndex::const_iterator index = mAnnotationIndex.find(std::string(name));
if (index != mAnnotationIndex.end())
return effectVariable->GetAnnotationByIndex((*index).second);
else
return 0;
}
bool CUniformParameterBuilder::getAnnotation(const char* name,LPCSTR& value)
{
ID3DX11EffectVariable* annotationVariable= findAnnotationByName(mEffectVariable, name);
if (annotationVariable) {
if (annotationVariable->AsString()->GetString(&value)==S_OK) {
return true;
}
}
return false;
}
bool CUniformParameterBuilder::getAnnotation(const char* name,float& value)
{
ID3DX11EffectVariable* annotationVariable= findAnnotationByName(mEffectVariable, name);
if (annotationVariable) {
if (annotationVariable->AsScalar()->GetFloat(&value)==S_OK) {
return true;
}
}
return false;
}
bool CUniformParameterBuilder::getAnnotation(const char* name,int& value)
{
ID3DX11EffectVariable* annotationVariable= findAnnotationByName(mEffectVariable, name);
if (annotationVariable) {
if (annotationVariable->AsScalar()->GetInt(&value)==S_OK) {
return true;
}
}
return false;
}
bool CUniformParameterBuilder::getBOOLAnnotation(const char* name,BOOL& value)
{
ID3DX11EffectVariable* annotationVariable= findAnnotationByName(mEffectVariable, name);
if (annotationVariable) {
#if defined(USE_BOOL)
if (annotationVariable->AsScalar()->GetBool(&value)==S_OK) {
return true;
}
#else
if (annotationVariable->AsScalar()->GetBool((bool*)&value)==S_OK) {
return true;
}
#endif
}
return false;
}
void CUniformParameterBuilder::logUnsupportedTypeWarning(
const MStringResourceId& typeId)
{
MString typeStr = dx11ShaderStrings::getString( typeId );
mWarnings += dx11ShaderStrings::getString( dx11ShaderStrings::kUnsupportedType, args );
}
void CUniformParameterBuilder::logUnrecognisedSemantic(const char* pSemantic)
{
mWarnings += dx11ShaderStrings::getString( dx11ShaderStrings::kUnknowSemantic, args );
}