You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.0 KiB
260 lines
7.0 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
#include "movieobjects/dmeshader.h" |
|
#include "datamodel/dmelementfactoryhelper.h" |
|
#include "movieobjects_interfaces.h" |
|
|
|
#include "materialsystem/IShader.h" |
|
#include "materialsystem/imaterialsystem.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Expose this class to the scene database |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY( DmeShader, CDmeShader ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
void CDmeShader::OnConstruction() |
|
{ |
|
m_ShaderName.Init( this, "shaderName" ); |
|
|
|
m_ShaderName = "wireframe"; |
|
m_pShader = NULL; |
|
} |
|
|
|
void CDmeShader::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Shader name access |
|
//----------------------------------------------------------------------------- |
|
void CDmeShader::SetShaderName( const char *pShaderName ) |
|
{ |
|
m_ShaderName = pShaderName; |
|
} |
|
|
|
const char *CDmeShader::GetShaderName() const |
|
{ |
|
return m_ShaderName; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Finds a shader |
|
//----------------------------------------------------------------------------- |
|
IShader *CDmeShader::FindShader() |
|
{ |
|
int nCount = MaterialSystem()->ShaderCount(); |
|
IShader **ppShaderList = (IShader**)_alloca( nCount * sizeof(IShader*) ); |
|
MaterialSystem()->GetShaders( 0, nCount, ppShaderList ); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
if ( !Q_stricmp( m_ShaderName, ppShaderList[i]->GetName() ) ) |
|
return ppShaderList[i]; |
|
} |
|
return NULL; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Remove all shader parameters that don't exist in the new shader |
|
//----------------------------------------------------------------------------- |
|
void CDmeShader::RemoveUnusedShaderParams( IShader *pShader ) |
|
{ |
|
IDmAttribute* pAttribute = FirstAttribute(); |
|
IDmAttribute* pNextAttribute = NULL; |
|
for ( ; pAttribute; pAttribute = pNextAttribute ) |
|
{ |
|
pNextAttribute = pAttribute->NextAttribute(); |
|
|
|
// Don't remove name, type, or id |
|
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) ) |
|
continue; |
|
|
|
const char *pShaderParam = pAttribute->GetName(); |
|
int nCount = pShader->GetNumParams(); |
|
int i; |
|
for ( i = 0; i < nCount; ++i ) |
|
{ |
|
if ( !Q_stricmp( pShaderParam, pShader->GetParamName( i ) ) ) |
|
break; |
|
} |
|
|
|
// No match? Remove it! |
|
if ( i == nCount ) |
|
{ |
|
RemoveAttributeByPtr( pAttribute ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Add attribute for shader parameter |
|
//----------------------------------------------------------------------------- |
|
IDmAttribute* CDmeShader::AddAttributeForShaderParameter( IShader *pShader, int nIndex ) |
|
{ |
|
ShaderParamType_t paramType = pShader->GetParamType( nIndex ); |
|
const char *pParamName = pShader->GetParamName( nIndex ); |
|
|
|
IDmAttribute *pAttribute = NULL; |
|
switch ( paramType ) |
|
{ |
|
case SHADER_PARAM_TYPE_INTEGER: |
|
pAttribute = AddAttributeTyped<int>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_BOOL: |
|
pAttribute = AddAttributeTyped<bool>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_FLOAT: |
|
pAttribute = AddAttributeTyped<float>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_STRING: |
|
pAttribute = AddAttributeTyped<CUtlString>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_COLOR: |
|
pAttribute = AddAttributeTyped<Color>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_VEC2: |
|
pAttribute = AddAttributeTyped<Vector2D>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_VEC3: |
|
pAttribute = AddAttributeTyped<Vector>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_VEC4: |
|
pAttribute = AddAttributeTyped<Vector4D>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_FOURCC: |
|
Assert( 0 ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_MATRIX: |
|
pAttribute = AddAttributeTyped<VMatrix>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_TEXTURE: |
|
pAttribute = AddAttributeTyped<CDmElementRef>( pParamName ); |
|
break; |
|
|
|
case SHADER_PARAM_TYPE_MATERIAL: |
|
pAttribute = AddAttributeTyped<CDmElementRef>( pParamName ); |
|
break; |
|
|
|
default: |
|
break; |
|
} |
|
return pAttribute; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Add all shader parameters that don't currently exist |
|
//----------------------------------------------------------------------------- |
|
void CDmeShader::AddNewShaderParams( IShader *pShader ) |
|
{ |
|
int nCount = pShader->GetNumParams(); |
|
int i; |
|
for ( i = 0; i < nCount; ++i ) |
|
{ |
|
const char *pParamName = pShader->GetParamName( i ); |
|
|
|
IDmAttribute* pAttribute = NULL; |
|
for ( pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() ) |
|
{ |
|
// Don't remove name, type, or id |
|
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) ) |
|
continue; |
|
|
|
const char *pAttributeName = pAttribute->GetName(); |
|
if ( !Q_stricmp( pAttributeName, pParamName ) ) |
|
break; |
|
} |
|
|
|
// No match? Add it! |
|
if ( pAttribute != NULL ) |
|
continue; |
|
|
|
pAttribute = AddAttributeForShaderParameter( pShader, i ); |
|
if ( pAttribute ) |
|
{ |
|
const char *pDefault = pShader->GetParamDefault( i ); |
|
|
|
SetAttributeValueFromString( pParamName, pDefault ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// resolve |
|
//----------------------------------------------------------------------------- |
|
void CDmeShader::Resolve() |
|
{ |
|
if ( !m_ShaderName.IsDirty() || !MaterialSystem() ) |
|
return; |
|
|
|
// First, find the shader |
|
IShader *pShader = FindShader(); |
|
|
|
// Remove all shader parameters that don't exist in the new shader |
|
RemoveUnusedShaderParams( pShader ); |
|
|
|
// Add all shader parameters that don't currently exist |
|
AddNewShaderParams( pShader ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns a procedural material to be associated with this shader |
|
//----------------------------------------------------------------------------- |
|
void CDmeShader::CreateMaterial( const char *pMaterialName ) |
|
{ |
|
KeyValues *pVMTKeyValues = new KeyValues( GetShaderName() ); |
|
|
|
IDmAttribute* pAttribute = FirstAttribute(); |
|
IDmAttribute* pNextAttribute = NULL; |
|
for ( ; pAttribute; pAttribute = pNextAttribute ) |
|
{ |
|
pNextAttribute = pAttribute->NextAttribute(); |
|
|
|
// Don't remove name, type, or id |
|
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) ) |
|
continue; |
|
|
|
const char *pShaderParam = pAttribute->GetName(); |
|
int nCount = pShader->GetNumParams(); |
|
int i; |
|
for ( i = 0; i < nCount; ++i ) |
|
{ |
|
if ( !Q_stricmp( pShaderParam, pShader->GetParamName( i ) ) ) |
|
break; |
|
} |
|
|
|
// No match? Remove it! |
|
if ( i == nCount ) |
|
{ |
|
RemoveAttributeByPtr( pAttribute ); |
|
} |
|
} |
|
|
|
pVMTKeyValues->SetInt( "$model", 1 ); |
|
pVMTKeyValues->SetFloat( "$decalscale", 0.05f ); |
|
pVMTKeyValues->SetString( "$basetexture", "error" ); |
|
return MaterialSystem()->CreateMaterial( pMaterialName, pVMTKeyValues ); |
|
}
|
|
|