Team Fortress 2 Source Code as on 22/4/2020
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.

171 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "pch_materialsystem.h"
  7. #define MATSYS_INTERNAL
  8. #include "cmaterialdict.h"
  9. #include "materialsystem_global.h"
  10. #include "filesystem.h"
  11. #include "imaterialinternal.h"
  12. // NOTE: This must be the last file included!!!
  13. #include "tier0/memdbgon.h"
  14. //-----------------------------------------------------------------------------
  15. // sort function
  16. //-----------------------------------------------------------------------------
  17. bool CMaterialDict::MaterialLessFunc( const MaterialLookup_t& src1,
  18. const MaterialLookup_t& src2 )
  19. {
  20. Assert( ThreadInMainThread() );
  21. // Always sort manually-created materials to the front
  22. if ( src1.m_bManuallyCreated != src2.m_bManuallyCreated )
  23. return src1.m_bManuallyCreated;
  24. return src1.m_Name < src2.m_Name;
  25. }
  26. //-----------------------------------------------------------------------------
  27. // sort function for missing materials
  28. //-----------------------------------------------------------------------------
  29. bool CMaterialDict::MissingMaterialLessFunc( const MissingMaterial_t& src1,
  30. const MissingMaterial_t& src2 )
  31. {
  32. Assert( ThreadInMainThread() );
  33. return src1.m_Name < src2.m_Name;
  34. }
  35. void CMaterialDict::Shutdown( )
  36. {
  37. Assert( ThreadInMainThread() );
  38. // Clean up all materials..
  39. RemoveAllMaterials();
  40. // FIXME: Could dump list here...
  41. if ( m_MissingList.Count() )
  42. DevMsg( "%s m_MissingList count: %d\n", __FUNCTION__, m_MissingList.Count() );
  43. m_MissingList.RemoveAll();
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Adds/removes the material to the list of all materials
  47. //-----------------------------------------------------------------------------
  48. void CMaterialDict::AddMaterialToMaterialList( IMaterialInternal *pMaterial )
  49. {
  50. Assert( ThreadInMainThread() );
  51. MaterialLookup_t lookup;
  52. lookup.m_pMaterial = pMaterial;
  53. lookup.m_Name = pMaterial->GetName();
  54. lookup.m_bManuallyCreated = pMaterial->IsManuallyCreated();
  55. m_MaterialDict.Insert( lookup );
  56. }
  57. void CMaterialDict::RemoveMaterialFromMaterialList( IMaterialInternal *pMaterial )
  58. {
  59. Assert( ThreadInMainThread() );
  60. // Gotta iterate over this manually; name-based lookup is bogus if there are two
  61. // materials with the same name, which can happen for procedural materials
  62. // First remove all the subrect materials, because they'll point at their material pages.
  63. MaterialHandle_t i;
  64. MaterialHandle_t iNext = InvalidMaterial();
  65. for (i = FirstMaterial(); i != InvalidMaterial(); i = iNext )
  66. {
  67. iNext = NextMaterial(i);
  68. if ( m_MaterialDict[i].m_pMaterial == pMaterial )
  69. {
  70. m_MaterialDict.RemoveAt( i );
  71. break;
  72. }
  73. }
  74. Assert( i != InvalidMaterial() );
  75. #ifdef _DEBUG
  76. for ( i = iNext; i != InvalidMaterial(); i = NextMaterial(i) )
  77. {
  78. Assert( m_MaterialDict[i].m_pMaterial != pMaterial );
  79. }
  80. #endif
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Adds, removes materials
  84. //-----------------------------------------------------------------------------
  85. IMaterialInternal* CMaterialDict::AddMaterial( char const* pName, const char *pTextureGroupName )
  86. {
  87. Assert( ThreadInMainThread() );
  88. IMaterialInternal *pMaterial = IMaterialInternal::CreateMaterial( pName, pTextureGroupName );
  89. Assert( pMaterial && pMaterial->IsRealTimeVersion() );
  90. AddMaterialToMaterialList( pMaterial );
  91. return pMaterial;
  92. }
  93. void CMaterialDict::RemoveMaterial( IMaterialInternal* pMaterial )
  94. {
  95. Assert( ThreadInMainThread() );
  96. Assert( (pMaterial == NULL) || pMaterial->IsRealTimeVersion() );
  97. RemoveMaterialFromMaterialList( pMaterial );
  98. }
  99. IMaterialInternal *CMaterialDict::AddMaterialSubRect( const char *pName, const char *pTextureGroupName, KeyValues *pKeyValues, KeyValues *pPatchKeyValues )
  100. {
  101. Assert( ThreadInMainThread() );
  102. IMaterialInternal *pMaterial = IMaterialInternal::CreateMaterialSubRect( pName, pTextureGroupName, pKeyValues, pPatchKeyValues, true );
  103. Assert( pMaterial );
  104. AddMaterialToMaterialList( pMaterial );
  105. return pMaterial;
  106. }
  107. void CMaterialDict::RemoveMaterialSubRect( IMaterialInternal *pMaterial )
  108. {
  109. Assert( ThreadInMainThread() );
  110. RemoveMaterialFromMaterialList( pMaterial );
  111. IMaterialInternal::DestroyMaterialSubRect( pMaterial );
  112. }
  113. void CMaterialDict::RemoveMaterialFromMaterialList( MaterialHandle_t h )
  114. {
  115. Assert( ThreadInMainThread() );
  116. m_MaterialDict.RemoveAt( h );
  117. }
  118. void CMaterialDict::RemoveAllMaterialsFromMaterialList()
  119. {
  120. Assert( ThreadInMainThread() );
  121. m_MaterialDict.RemoveAll();
  122. }
  123. void CMaterialDict::RemoveAllMaterials()
  124. {
  125. Assert( ThreadInMainThread() );
  126. // First remove all the subrect materials, because they'll point at their material pages.
  127. MaterialHandle_t i, iNext;
  128. for (i = FirstMaterial(); i != InvalidMaterial(); i = iNext )
  129. {
  130. iNext = NextMaterial(i);
  131. IMaterialInternal *pMaterial = GetMaterialInternal( i );
  132. if ( pMaterial->InMaterialPage() )
  133. {
  134. IMaterialInternal::DestroyMaterialSubRect( pMaterial );
  135. RemoveMaterialFromMaterialList( i );
  136. }
  137. }
  138. // Now get rid of the rest of the materials, including the pages.
  139. for (i = FirstMaterial(); i != InvalidMaterial(); i = NextMaterial(i) )
  140. {
  141. IMaterialInternal::DestroyMaterial( GetMaterialInternal( i ) );
  142. }
  143. RemoveAllMaterialsFromMaterialList();
  144. }