summaryrefslogtreecommitdiff
path: root/movieobjects/dmeshader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'movieobjects/dmeshader.cpp')
-rw-r--r--movieobjects/dmeshader.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/movieobjects/dmeshader.cpp b/movieobjects/dmeshader.cpp
new file mode 100644
index 0000000..8408124
--- /dev/null
+++ b/movieobjects/dmeshader.cpp
@@ -0,0 +1,260 @@
+//========= 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 );
+}