mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 06:06:50 +00:00
172 lines
5.3 KiB
C++
172 lines
5.3 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "pch_materialsystem.h"
|
|
|
|
#define MATSYS_INTERNAL
|
|
|
|
#include "cmaterialdict.h"
|
|
|
|
#include "materialsystem_global.h"
|
|
#include "filesystem.h"
|
|
#include "imaterialinternal.h"
|
|
|
|
// NOTE: This must be the last file included!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// sort function
|
|
//-----------------------------------------------------------------------------
|
|
bool CMaterialDict::MaterialLessFunc( const MaterialLookup_t& src1,
|
|
const MaterialLookup_t& src2 )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
// Always sort manually-created materials to the front
|
|
if ( src1.m_bManuallyCreated != src2.m_bManuallyCreated )
|
|
return src1.m_bManuallyCreated;
|
|
|
|
return src1.m_Name < src2.m_Name;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// sort function for missing materials
|
|
//-----------------------------------------------------------------------------
|
|
bool CMaterialDict::MissingMaterialLessFunc( const MissingMaterial_t& src1,
|
|
const MissingMaterial_t& src2 )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
return src1.m_Name < src2.m_Name;
|
|
}
|
|
|
|
void CMaterialDict::Shutdown( )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
// Clean up all materials..
|
|
RemoveAllMaterials();
|
|
|
|
// FIXME: Could dump list here...
|
|
if ( m_MissingList.Count() )
|
|
DevMsg( "%s m_MissingList count: %d\n", __FUNCTION__, m_MissingList.Count() );
|
|
m_MissingList.RemoveAll();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Adds/removes the material to the list of all materials
|
|
//-----------------------------------------------------------------------------
|
|
void CMaterialDict::AddMaterialToMaterialList( IMaterialInternal *pMaterial )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
MaterialLookup_t lookup;
|
|
lookup.m_pMaterial = pMaterial;
|
|
lookup.m_Name = pMaterial->GetName();
|
|
lookup.m_bManuallyCreated = pMaterial->IsManuallyCreated();
|
|
|
|
m_MaterialDict.Insert( lookup );
|
|
}
|
|
|
|
void CMaterialDict::RemoveMaterialFromMaterialList( IMaterialInternal *pMaterial )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
// Gotta iterate over this manually; name-based lookup is bogus if there are two
|
|
// materials with the same name, which can happen for procedural materials
|
|
// First remove all the subrect materials, because they'll point at their material pages.
|
|
MaterialHandle_t i;
|
|
MaterialHandle_t iNext = InvalidMaterial();
|
|
for (i = FirstMaterial(); i != InvalidMaterial(); i = iNext )
|
|
{
|
|
iNext = NextMaterial(i);
|
|
if ( m_MaterialDict[i].m_pMaterial == pMaterial )
|
|
{
|
|
m_MaterialDict.RemoveAt( i );
|
|
break;
|
|
}
|
|
}
|
|
|
|
Assert( i != InvalidMaterial() );
|
|
|
|
#ifdef _DEBUG
|
|
for ( i = iNext; i != InvalidMaterial(); i = NextMaterial(i) )
|
|
{
|
|
Assert( m_MaterialDict[i].m_pMaterial != pMaterial );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Adds, removes materials
|
|
//-----------------------------------------------------------------------------
|
|
IMaterialInternal* CMaterialDict::AddMaterial( char const* pName, const char *pTextureGroupName )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
IMaterialInternal *pMaterial = IMaterialInternal::CreateMaterial( pName, pTextureGroupName );
|
|
Assert( pMaterial && pMaterial->IsRealTimeVersion() );
|
|
AddMaterialToMaterialList( pMaterial );
|
|
return pMaterial;
|
|
}
|
|
|
|
void CMaterialDict::RemoveMaterial( IMaterialInternal* pMaterial )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
Assert( (pMaterial == NULL) || pMaterial->IsRealTimeVersion() );
|
|
RemoveMaterialFromMaterialList( pMaterial );
|
|
}
|
|
|
|
IMaterialInternal *CMaterialDict::AddMaterialSubRect( const char *pName, const char *pTextureGroupName, KeyValues *pKeyValues, KeyValues *pPatchKeyValues )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
IMaterialInternal *pMaterial = IMaterialInternal::CreateMaterialSubRect( pName, pTextureGroupName, pKeyValues, pPatchKeyValues, true );
|
|
Assert( pMaterial );
|
|
AddMaterialToMaterialList( pMaterial );
|
|
return pMaterial;
|
|
}
|
|
|
|
void CMaterialDict::RemoveMaterialSubRect( IMaterialInternal *pMaterial )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
RemoveMaterialFromMaterialList( pMaterial );
|
|
IMaterialInternal::DestroyMaterialSubRect( pMaterial );
|
|
}
|
|
|
|
void CMaterialDict::RemoveMaterialFromMaterialList( MaterialHandle_t h )
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
m_MaterialDict.RemoveAt( h );
|
|
}
|
|
|
|
void CMaterialDict::RemoveAllMaterialsFromMaterialList()
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
m_MaterialDict.RemoveAll();
|
|
}
|
|
|
|
void CMaterialDict::RemoveAllMaterials()
|
|
{
|
|
Assert( ThreadInMainThread() );
|
|
|
|
// First remove all the subrect materials, because they'll point at their material pages.
|
|
MaterialHandle_t i, iNext;
|
|
for (i = FirstMaterial(); i != InvalidMaterial(); i = iNext )
|
|
{
|
|
iNext = NextMaterial(i);
|
|
IMaterialInternal *pMaterial = GetMaterialInternal( i );
|
|
if ( pMaterial->InMaterialPage() )
|
|
{
|
|
IMaterialInternal::DestroyMaterialSubRect( pMaterial );
|
|
RemoveMaterialFromMaterialList( i );
|
|
}
|
|
}
|
|
|
|
// Now get rid of the rest of the materials, including the pages.
|
|
for (i = FirstMaterial(); i != InvalidMaterial(); i = NextMaterial(i) )
|
|
{
|
|
IMaterialInternal::DestroyMaterial( GetMaterialInternal( i ) );
|
|
}
|
|
|
|
RemoveAllMaterialsFromMaterialList();
|
|
}
|
|
|