Counter Strike : Global Offensive Source Code
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

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmeshader.h"
  7. #include "datamodel/dmelementfactoryhelper.h"
  8. #include "movieobjects_interfaces.h"
  9. #include "materialsystem/IShader.h"
  10. #include "materialsystem/IMaterialSystem.h"
  11. //-----------------------------------------------------------------------------
  12. // Expose this class to the scene database
  13. //-----------------------------------------------------------------------------
  14. IMPLEMENT_ELEMENT_FACTORY( DmeShader, CDmeShader );
  15. //-----------------------------------------------------------------------------
  16. // Constructor, destructor
  17. //-----------------------------------------------------------------------------
  18. void CDmeShader::OnConstruction()
  19. {
  20. m_ShaderName.Init( this, "shaderName" );
  21. m_ShaderName = "wireframe";
  22. m_pShader = NULL;
  23. }
  24. void CDmeShader::OnDestruction()
  25. {
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Shader name access
  29. //-----------------------------------------------------------------------------
  30. void CDmeShader::SetShaderName( const char *pShaderName )
  31. {
  32. m_ShaderName = pShaderName;
  33. }
  34. const char *CDmeShader::GetShaderName() const
  35. {
  36. return m_ShaderName;
  37. }
  38. //-----------------------------------------------------------------------------
  39. // Finds a shader
  40. //-----------------------------------------------------------------------------
  41. IShader *CDmeShader::FindShader()
  42. {
  43. int nCount = MaterialSystem()->ShaderCount();
  44. IShader **ppShaderList = (IShader**)_alloca( nCount * sizeof(IShader*) );
  45. MaterialSystem()->GetShaders( 0, nCount, ppShaderList );
  46. for ( int i = 0; i < nCount; ++i )
  47. {
  48. if ( !Q_stricmp( m_ShaderName, ppShaderList[i]->GetName() ) )
  49. return ppShaderList[i];
  50. }
  51. return NULL;
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Remove all shader parameters that don't exist in the new shader
  55. //-----------------------------------------------------------------------------
  56. void CDmeShader::RemoveUnusedShaderParams( IShader *pShader )
  57. {
  58. IDmAttribute* pAttribute = FirstAttribute();
  59. IDmAttribute* pNextAttribute = NULL;
  60. for ( ; pAttribute; pAttribute = pNextAttribute )
  61. {
  62. pNextAttribute = pAttribute->NextAttribute();
  63. // Don't remove name, type, or id
  64. if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
  65. continue;
  66. const char *pShaderParam = pAttribute->GetName();
  67. int nCount = pShader->GetNumParams();
  68. int i;
  69. for ( i = 0; i < nCount; ++i )
  70. {
  71. if ( !Q_stricmp( pShaderParam, pShader->GetParamName( i ) ) )
  72. break;
  73. }
  74. // No match? Remove it!
  75. if ( i == nCount )
  76. {
  77. RemoveAttributeByPtr( pAttribute );
  78. }
  79. }
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Add attribute for shader parameter
  83. //-----------------------------------------------------------------------------
  84. IDmAttribute* CDmeShader::AddAttributeForShaderParameter( IShader *pShader, int nIndex )
  85. {
  86. ShaderParamType_t paramType = pShader->GetParamType( nIndex );
  87. const char *pParamName = pShader->GetParamName( nIndex );
  88. IDmAttribute *pAttribute = NULL;
  89. switch ( paramType )
  90. {
  91. case SHADER_PARAM_TYPE_INTEGER:
  92. pAttribute = AddAttributeTyped<int>( pParamName );
  93. break;
  94. case SHADER_PARAM_TYPE_BOOL:
  95. pAttribute = AddAttributeTyped<bool>( pParamName );
  96. break;
  97. case SHADER_PARAM_TYPE_FLOAT:
  98. pAttribute = AddAttributeTyped<float>( pParamName );
  99. break;
  100. case SHADER_PARAM_TYPE_STRING:
  101. pAttribute = AddAttributeTyped<CUtlString>( pParamName );
  102. break;
  103. case SHADER_PARAM_TYPE_COLOR:
  104. pAttribute = AddAttributeTyped<Color>( pParamName );
  105. break;
  106. case SHADER_PARAM_TYPE_VEC2:
  107. pAttribute = AddAttributeTyped<Vector2D>( pParamName );
  108. break;
  109. case SHADER_PARAM_TYPE_VEC3:
  110. pAttribute = AddAttributeTyped<Vector>( pParamName );
  111. break;
  112. case SHADER_PARAM_TYPE_VEC4:
  113. pAttribute = AddAttributeTyped<Vector4D>( pParamName );
  114. break;
  115. case SHADER_PARAM_TYPE_FOURCC:
  116. Assert( 0 );
  117. break;
  118. case SHADER_PARAM_TYPE_MATRIX:
  119. pAttribute = AddAttributeTyped<VMatrix>( pParamName );
  120. break;
  121. case SHADER_PARAM_TYPE_TEXTURE:
  122. pAttribute = AddAttributeTyped<CDmElementRef>( pParamName );
  123. break;
  124. case SHADER_PARAM_TYPE_MATERIAL:
  125. pAttribute = AddAttributeTyped<CDmElementRef>( pParamName );
  126. break;
  127. default:
  128. break;
  129. }
  130. return pAttribute;
  131. }
  132. //-----------------------------------------------------------------------------
  133. // Add all shader parameters that don't currently exist
  134. //-----------------------------------------------------------------------------
  135. void CDmeShader::AddNewShaderParams( IShader *pShader )
  136. {
  137. int nCount = pShader->GetNumParams();
  138. int i;
  139. for ( i = 0; i < nCount; ++i )
  140. {
  141. const char *pParamName = pShader->GetParamName( i );
  142. IDmAttribute* pAttribute = NULL;
  143. for ( pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  144. {
  145. // Don't remove name, type, or id
  146. if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
  147. continue;
  148. const char *pAttributeName = pAttribute->GetName();
  149. if ( !Q_stricmp( pAttributeName, pParamName ) )
  150. break;
  151. }
  152. // No match? Add it!
  153. if ( pAttribute != NULL )
  154. continue;
  155. pAttribute = AddAttributeForShaderParameter( pShader, i );
  156. if ( pAttribute )
  157. {
  158. const char *pDefault = pShader->GetParamDefault( i );
  159. SetAttributeValueFromString( pParamName, pDefault );
  160. }
  161. }
  162. }
  163. //-----------------------------------------------------------------------------
  164. // resolve
  165. //-----------------------------------------------------------------------------
  166. void CDmeShader::Resolve()
  167. {
  168. if ( !m_ShaderName.IsDirty() || !MaterialSystem() )
  169. return;
  170. // First, find the shader
  171. IShader *pShader = FindShader();
  172. // Remove all shader parameters that don't exist in the new shader
  173. RemoveUnusedShaderParams( pShader );
  174. // Add all shader parameters that don't currently exist
  175. AddNewShaderParams( pShader );
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Returns a procedural material to be associated with this shader
  179. //-----------------------------------------------------------------------------
  180. void CDmeShader::CreateMaterial( const char *pMaterialName )
  181. {
  182. KeyValues *pVMTKeyValues = new KeyValues( GetShaderName() );
  183. IDmAttribute* pAttribute = FirstAttribute();
  184. IDmAttribute* pNextAttribute = NULL;
  185. for ( ; pAttribute; pAttribute = pNextAttribute )
  186. {
  187. pNextAttribute = pAttribute->NextAttribute();
  188. // Don't remove name, type, or id
  189. if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
  190. continue;
  191. const char *pShaderParam = pAttribute->GetName();
  192. int nCount = pShader->GetNumParams();
  193. int i;
  194. for ( i = 0; i < nCount; ++i )
  195. {
  196. if ( !Q_stricmp( pShaderParam, pShader->GetParamName( i ) ) )
  197. break;
  198. }
  199. // No match? Remove it!
  200. if ( i == nCount )
  201. {
  202. RemoveAttributeByPtr( pAttribute );
  203. }
  204. }
  205. pVMTKeyValues->SetInt( "$model", 1 );
  206. pVMTKeyValues->SetFloat( "$decalscale", 0.05f );
  207. pVMTKeyValues->SetString( "$basetexture", "error" );
  208. return MaterialSystem()->CreateMaterial( pMaterialName, pVMTKeyValues );
  209. }