deargui-vpl/ref/virtools/Samples/Behaviors/Shader/Sources/SetMFX.cpp

210 lines
6.0 KiB
C++

#include "stdafx.h"
#define SETMATERIALSHADERPARAMETERS_GUID CKGUID(0x6cff75c2,0x26b61ecf)
//-----------------------------------------------------------------------------
CKParameterLocal* FindParameterByNameAndType( const XArray<CKParameterLocal*>& params,
char* paramName,
CKGUID paramType )
{
const int shaderParamCount = params.Size();
for( int a=0; a<shaderParamCount ; ++a ){
CKParameterLocal* shaderParam = params[a];
if( !shaderParam ) continue;
if( shaderParam->GetGUID() == paramType ){
if( !strcmp( shaderParam->GetName(), paramName ) ){
return shaderParam;
}
}
}
return NULL;
}
//-----------------------------------------------------------------------------
CKParameterIn* FindBBParamByNameAndType( CKBehavior* beh,
int firstParamIndex,
char* paramName,
CKGUID paramType )
{
const int paramCount = beh->GetInputParameterCount();
for( int a=firstParamIndex ; a<paramCount ; ++a ){
CKParameterIn* pIn = beh->GetInputParameter(a);
if( pIn->GetGUID() == paramType ){
if( !strcmp( pIn->GetName(), paramName ) ){
return pIn;
}
}
}
return NULL;
}
//-----------------------------------------------------------------------------
void FillShaderParameters( CKBehavior* beh, int firstParamIndex,
XArray<CKParameterLocal*>& params )
{
const int paramCount = beh->GetInputParameterCount();
for( int a=firstParamIndex ; a<paramCount ; ++a ){
CKParameterIn* pIn = beh->GetInputParameter(a);
CKParameter* realSource = pIn->GetRealSource();
if( !realSource ) continue;
CKParameterLocal* shaderParam = FindParameterByNameAndType(
params,
pIn->GetName(),
pIn->GetGUID() );
if( shaderParam ) shaderParam->CopyValue( realSource );
}
}
//-----------------------------------------------------------------------------
void BuildShaderExposedParams( CKBehavior* beh, int firstParamIndex,
XArray<CKParameterLocal*>& params )
{
//--- Destroy Invalid Parameters
int a;
int paramCount = beh->GetInputParameterCount()-firstParamIndex;
for( a=0 ; a<paramCount ; ++a ){
CKParameterIn* pIn = beh->GetInputParameter( firstParamIndex+a );
//--- If param exists, then keep it
if( FindParameterByNameAndType(
params,
pIn->GetName(),
pIn->GetGUID()) ){
continue;
}
//--- Otherwise Destroy It
CKDestroyObject( beh->RemoveInputParameter( firstParamIndex+a ) );
--paramCount;
--a;
}
//--- Expose Missing Params
const int shaderParamCount = params.Size();
for( a=0; a<shaderParamCount ; ++a ){
CKParameterLocal* shaderParam = params[a];
char* shaderParamName = shaderParam->GetName();
CKGUID shaderParamGuid = shaderParam->GetGUID();
//--- If Shader Param has already been exposed in BB, then skip...
if( FindBBParamByNameAndType(
beh,
firstParamIndex,
shaderParamName,
shaderParamGuid) ){
continue;
}
//--- Otherwise Create It
//....
beh->CreateInputParameter( shaderParamName, shaderParamGuid );
}
}
/***********************************************/
// MAIN
/***********************************************/
int SetMaterialShaderParameters( const CKBehaviorContext& behcontext )
{
CKBehavior* beh = behcontext.Behavior;
beh->ActivateInput(0, FALSE);
beh->ActivateOutput(0);
CKMaterial* mat = (CKMaterial*)beh->GetTarget();
if( !mat ) return CKBR_PARAMETERERROR;
//--- Gets MaterialShader
CKMaterialShader* mfx = mat->GetMaterialShader();
if( !mfx ) return CKBR_PARAMETERERROR;
//--- Fill Shader Parameters
FillShaderParameters( beh, 0, mfx->m_Params );
return CKBR_OK;
}
/***********************************************/
// CALLBACK
/***********************************************/
CKERROR SetMaterialShaderParametersCallback(const CKBehaviorContext& behcontext)
{
CKBehavior* beh = behcontext.Behavior;
switch( behcontext.CallbackMessage ){
case CKM_BEHAVIORSETTINGSEDITED:
{
//--- Build Exposed Parameters
BOOL buildExposedParams = FALSE;
beh->GetLocalParameterValue( 0, &buildExposedParams );
if( buildExposedParams ){
//--- Reset buildExposedParams Flag
buildExposedParams = FALSE;
beh->SetLocalParameterValue( 0, &buildExposedParams );
//--- Get Material
CKMaterial* mat = (CKMaterial*)beh->GetTarget();
if( !mat ) return CKBR_PARAMETERERROR;
//--- Gets MaterialShader
CKMaterialShader* mfx = mat->GetMaterialShader();
if( !mfx ) return CKBR_PARAMETERERROR;
//--- Create and Destroy pIns
int firstParamIndex = 0;
BuildShaderExposedParams( beh, firstParamIndex, mfx->m_Params );
}
} break;
}
return CKBR_OK;
}
/***********************************************/
// PROTO
/***********************************************/
CKERROR CreateSetMaterialShaderParametersProto(CKBehaviorPrototype **pproto)
{
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Set Shader Parameters");
if(!proto) return CKERR_OUTOFMEMORY;
proto->DeclareInput("In");
proto->DeclareOutput("Out");
proto->DeclareSetting("Build Exposed Params",CKPGUID_BOOL, "FALSE");
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
proto->SetFunction(SetMaterialShaderParameters);
proto->SetBehaviorFlags( (CK_BEHAVIOR_FLAGS)(
CKBEHAVIOR_VARIABLEPARAMETERINPUTS | CKBEHAVIOR_TARGETABLE) );
proto->SetBehaviorCallbackFct( SetMaterialShaderParametersCallback,
CKCB_BEHAVIORSETTINGSEDITED );
*pproto = proto;
return CK_OK;
}
/***********************************************/
// DECLARATION
/***********************************************/
CKObjectDeclaration *FillBehaviorSetMaterialShaderParameters()
{
CKObjectDeclaration *od = CreateCKObjectDeclaration("Set Shader Parameters");
od->SetDescription("Sets one or more parameters of the material's shader.");
od->SetCategory("Shaders/General");
od->SetType(CKDLL_BEHAVIORPROTOTYPE);
od->SetGuid(SETMATERIALSHADERPARAMETERS_GUID);
od->SetAuthorGuid(VIRTOOLS_GUID);
od->SetAuthorName("Virtools");
od->SetVersion(0x00010000);
od->SetCreationFunction(CreateSetMaterialShaderParametersProto);
od->SetCompatibleClassId(CKCID_MATERIAL);
return od;
}