csgo-2018-source/engine/MaterialBuckets.h

154 lines
3.7 KiB
C
Raw Permalink Normal View History

2021-07-25 12:11:47 +08:00
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This is a helper class for the situation where you want to build lists of
// things that fall into buckets, and effeciently keep up with which buckets have
// been used since flush.
//
//=============================================================================//
#ifndef MATERIALBUCKETS_H
#define MATERIALBUCKETS_H
#ifdef _WIN32
#pragma once
#endif
// FLASHLIGHTFIXME: Make all of the buckets share the same m_Elements (ie. make m_Elements static)
template <class Element_t>
class CMaterialsBuckets
{
public:
typedef unsigned short SortIDHandle_t;
typedef unsigned short ElementHandle_t;
CMaterialsBuckets()
{
m_FlushCount = -1;
}
// Set the number of buckets that are needed. This should get called every time
// a level is loaded.
void SetNumMaterialSortIDs( int n )
{
m_MaterialSortInfoArray.Purge();
m_MaterialSortInfoArray.SetCount( n );
m_Elements.Purge();
m_UsedSortIDs.Purge();
}
// Clear out all buckets. This should get called once a frame.
void Flush( void )
{
m_FlushCount++;
m_Elements.RemoveAll();
m_UsedSortIDs.RemoveAll();
}
//
// These functions are used to get at the list of used buckets.
//
SortIDHandle_t GetFirstUsedSortID()
{
return m_UsedSortIDs.Head();
}
SortIDHandle_t GetNextUsedSortID( SortIDHandle_t prevSortID )
{
return m_UsedSortIDs.Next( prevSortID );
}
int GetSortID( SortIDHandle_t handle )
{
return m_UsedSortIDs[handle];
}
SortIDHandle_t InvalidSortIDHandle()
{
return m_UsedSortIDs.InvalidIndex();
}
//
// These functions are used to get at the list of elements for each sortID.
//
ElementHandle_t GetElementListHead( int sortID )
{
return m_MaterialSortInfoArray[sortID].m_Head;
}
ElementHandle_t GetElementListNext( ElementHandle_t h )
{
return m_Elements.Next( h );
}
Element_t GetElement( ElementHandle_t h )
{
return m_Elements[h];
}
ElementHandle_t InvalidElementHandle()
{
return m_Elements.InvalidIndex();
}
// Add an element to the the bucket specified by sortID
void AddElement( int sortID, Element_t elem )
{
// Allocate an element to stick this in.
unsigned short elemID = m_Elements.Alloc( true );
m_Elements[elemID] = elem;
if( m_MaterialSortInfoArray[sortID].m_FlushCount != m_FlushCount )
{
// This is the first element that has used this sort id since flush.
// FLASHLIGHTFIXME: need to sort these by vertex format when shoving
// them into this list!
// Mark this sortID as having been used since the last flush.
m_MaterialSortInfoArray[sortID].m_FlushCount = m_FlushCount;
// Add this sortID to the list of sortIDs used since flush.
m_UsedSortIDs.AddToTail( sortID );
// Set the head pointer for this sort id to this element.
m_MaterialSortInfoArray[sortID].m_Head = elemID;
}
else
{
// We already have an element in this sort id since flush, so chain
// into thelist of elements for this sort id.
m_Elements.LinkBefore( m_MaterialSortInfoArray[sortID].m_Head, elemID );
m_MaterialSortInfoArray[sortID].m_Head = elemID;
}
}
private:
struct MaterialSortInfo_t
{
MaterialSortInfo_t() :
m_FlushCount( -1 ),
m_Head( (unsigned short)-1 ) // i.e., InvalidIndex()
{
}
int m_FlushCount;
unsigned short m_Head;
};
// This is a list of material sort info ids that have been used since flush.
CUtlLinkedList<unsigned short> m_UsedSortIDs;
// This is m_NumMaterialSortIDs big.
CUtlVector<MaterialSortInfo_t> m_MaterialSortInfoArray;
// This is used in multilist mode to make elements that belong in the multiple lists of
CUtlLinkedList<Element_t, unsigned short, true> m_Elements;
int m_FlushCount;
};
#endif // MATERIALBUCKETS_H