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

195 lines
5.4 KiB
C++

#include "stdafx.h"
#define GETMATERIALSHADERPARAMETERS_GUID CKGUID(0x512a6b7c,0xc12f6ab6)
//-----------------------------------------------------------------------------
extern CKParameterLocal* FindParameterByNameAndType( const XArray<CKParameterLocal*>& params,
char* paramName,
CKGUID paramType );
//-----------------------------------------------------------------------------
int FindParameterIndexByNameAndType(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 a;
}
}
}
return -1;
}
//-----------------------------------------------------------------------------
void BuildParameters(CKBehavior* beh,const XArray<CKParameterLocal*>& params)
{
XArray<CKParameterOut*> poutToBuild;
BOOL rebuild = FALSE;
int ocount = beh->GetOutputParameterCount();
int scount = params.Size();
poutToBuild.Resize(scount);
poutToBuild.Memset(0);
if (ocount!=scount)
rebuild=TRUE;
for (int i=ocount-1;i>=0;--i)
{
CKParameterOut* pout = beh->GetOutputParameter(i);
int index = FindParameterIndexByNameAndType(params,pout->GetName(),pout->GetGUID());
if (index>=0)
{
if (index!=i) //pout not rightly placed
{
beh->RemoveOutputParameter( i );
poutToBuild[index]=pout;
rebuild=TRUE;
}
else
poutToBuild[index]=(CKParameterOut*)-1;//already rightly placed
}
else
{
CKDestroyObject( beh->RemoveOutputParameter( i ) );
}
}
if (rebuild)
{
for (int i=0;i<scount;i++)
{
CKParameterOut* pout = poutToBuild[i];
if (pout)
beh->InsertOutputParameter(i,pout);
else if (pout!=(CKParameterOut*)-1)
{
CKParameterLocal* plocal = params[i];
pout = beh->GetCKContext()->CreateCKParameterOut(plocal->GetName(),plocal->GetGUID());
beh->InsertOutputParameter(i,pout);
}
}
}
}
//-----------------------------------------------------------------------------
void FillShaderParameters(CKBehavior* beh,XArray<CKParameterLocal*>& params)
{
const int paramCount = beh->GetOutputParameterCount();
for( int a=0 ; a<paramCount ; ++a ){
CKParameterOut* pout = beh->GetOutputParameter(a);
CKParameterLocal* shaderParam = FindParameterByNameAndType(
params,
pout->GetName(),
pout->GetGUID() );
if( shaderParam )
pout->CopyValue( shaderParam );
}
}
/***********************************************/
// MAIN
/***********************************************/
int GetMaterialShaderParameters( 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, mfx->m_Params );
return CKBR_OK;
}
/***********************************************/
// CALLBACK
/***********************************************/
CKERROR GetMaterialShaderParametersCallback(const CKBehaviorContext& behcontext)
{
CKBehavior* beh = behcontext.Behavior;
switch( behcontext.CallbackMessage ){
case CKM_BEHAVIORSETTINGSEDITED:
{
BOOL buildExposedParams = FALSE;
beh->GetLocalParameterValue( 0, &buildExposedParams );
if( buildExposedParams )
{
//--- Reset buildExposedParams Flag
buildExposedParams = FALSE;
beh->SetLocalParameterValue( 0, &buildExposedParams );
CKMaterial* mat = (CKMaterial*)beh->GetTarget();
if( !mat ) return CKBR_PARAMETERERROR;
//--- Gets MaterialShader
CKMaterialShader* mfx = mat->GetMaterialShader();
if( !mfx ) return CKBR_PARAMETERERROR;
BuildParameters(beh,mfx->m_Params);
}
}
break;
}
return CKBR_OK;
}
/***********************************************/
// PROTO
/***********************************************/
CKERROR CreateGetMaterialShaderParametersProto(CKBehaviorPrototype **pproto)
{
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Get 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(GetMaterialShaderParameters);
proto->SetBehaviorFlags( (CK_BEHAVIOR_FLAGS)(
CKBEHAVIOR_VARIABLEPARAMETEROUTPUTS | CKBEHAVIOR_TARGETABLE) );
proto->SetBehaviorCallbackFct( GetMaterialShaderParametersCallback,CKCB_BEHAVIORSETTINGSEDITED );
*pproto = proto;
return CK_OK;
}
/***********************************************/
// DECLARATION
/***********************************************/
CKObjectDeclaration *FillBehaviorGetMaterialShaderParameters()
{
CKObjectDeclaration *od = CreateCKObjectDeclaration("Get Shader Parameters");
od->SetDescription("Gets parameters of the material's shader.");
od->SetCategory("Shaders/General");
od->SetType(CKDLL_BEHAVIORPROTOTYPE);
od->SetGuid(GETMATERIALSHADERPARAMETERS_GUID);
od->SetAuthorGuid(VIRTOOLS_GUID);
od->SetAuthorName("Virtools");
od->SetVersion(0x00010000);
od->SetCreationFunction(CreateGetMaterialShaderParametersProto);
od->SetCompatibleClassId(CKCID_MATERIAL);
return od;
}