261 lines
7.0 KiB
C++
261 lines
7.0 KiB
C++
//====== Copyright © 1996-2004, 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 );
|
|
}
|