//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef R_DECAL_H #define R_DECAL_H #ifdef _WIN32 #pragma once #endif #include "decal_private.h" #include "decal_clip.h" #include "utllinkedlist.h" #include "utlrbtree.h" #include "tier0/platform.h" #include "tier0/memdbgon.h" // Initialize and shutdown the decal stuff. // R_DecalTerm unlinks all the active decals (which frees their counterparts in displacements). void R_DecalInit(); void R_DecalTerm( worldbrushdata_t *pBrushData, bool term_permanent_decals, bool term_player_decals ); void R_DecalTermNew( worldbrushdata_t *pBrushData, int nTick ); void R_DecalTermAll(); float ComputeDecalLightmapOffset( SurfaceHandle_t surfID ); // --------------------------------------------------------------- // // Decal functions used for displacements. // --------------------------------------------------------------- // // Figure out where the decal maps onto the surface. void R_SetupDecalClip( CDecalVert* &pOutVerts, decal_t *pDecal, Vector &vSurfNormal, IMaterial *pMaterial, Vector textureSpaceBasis[3], float decalWorldScale[2] ); //----------------------------------------------------------------------------- // Gets the decal material and radius based on the decal index //----------------------------------------------------------------------------- void R_DecalGetMaterialAndSize( int decalIndex, IMaterial*& pDecalMaterial, float& w, float& h ); //============================================================================= // // Decal Sort Structures. // #define DECALSORT_RBTREE_SIZE 16 enum { PERMANENT_LIGHTMAP = 0, LIGHTMAP, NONLIGHTMAP, DECALSORT_TYPE_COUNT, }; struct DecalSortVertexFormat_t { VertexFormat_t m_VertexFormat; int m_iSortTree; // Sort tree index. }; struct DecalMaterialSortData_t { IMaterial *m_pMaterial; int m_iLightmapPage; int m_iBucket; // Index into the s_aDecalMaterialHead list. }; struct DecalMaterialBucket_t { intp m_iHead; intp m_iTail; int m_nCheckCount; }; inline bool DecalSortTreeSortLessFunc( const DecalMaterialSortData_t &decal1, const DecalMaterialSortData_t &decal2 ) { if ( ( decal1.m_iLightmapPage == -1 ) || ( decal2.m_iLightmapPage == -1 ) ) { return ( ( intp )decal1.m_pMaterial < ( intp )decal2.m_pMaterial ); } if ( ( intp )decal1.m_pMaterial == ( intp )decal2.m_pMaterial ) { return ( decal1.m_iLightmapPage < decal2.m_iLightmapPage ); } else { return ( ( intp )decal1.m_pMaterial < ( intp )decal2.m_pMaterial ); } } struct DecalSortTrees_t { CUtlRBTree *m_pTrees[DECALSORT_TYPE_COUNT]; CUtlVector m_aDecalSortBuckets[MAX_MAT_SORT_GROUPS+1][DECALSORT_TYPE_COUNT]; DecalSortTrees_t() { for ( int iSort = 0; iSort < DECALSORT_TYPE_COUNT; ++iSort ) { m_pTrees[iSort] = new CUtlRBTree( DECALSORT_RBTREE_SIZE, DECALSORT_RBTREE_SIZE, DecalSortTreeSortLessFunc ); } } ~DecalSortTrees_t() { for ( int iSort = 0; iSort < DECALSORT_TYPE_COUNT; ++iSort ) { if ( m_pTrees[iSort] ) { m_pTrees[iSort]->RemoveAll(); delete m_pTrees[iSort]; m_pTrees[iSort] = NULL; } } for ( int iGroup = 0; iGroup < ( MAX_MAT_SORT_GROUPS + 1 ); ++iGroup ) { for ( int iSort = 0; iSort < DECALSORT_TYPE_COUNT; ++iSort ) { m_aDecalSortBuckets[iGroup][iSort].Purge(); } } } }; extern CUtlVector g_aDecalFormats; // Surface decals. extern CUtlFixedLinkedList g_aDecalSortPool; extern CUtlVector g_aDecalSortTrees; extern int g_nDecalSortCheckCount; extern int g_nBrushModelDecalSortCheckCount; // Displacement decals. extern CUtlFixedLinkedList g_aDispDecalSortPool; extern CUtlVector g_aDispDecalSortTrees; extern int g_nDispDecalSortCheckCount; struct DecalBatchList_t { IMaterial *m_pMaterial; void *m_pProxy; int m_iLightmapPage; unsigned short m_iStartIndex; unsigned short m_nIndexCount; }; struct DecalMeshList_t { IMesh *m_pMesh; CUtlVectorFixed m_aBatches; }; void DecalSurfacesInit( bool bBrushModel ); void DecalSurfaceAdd( SurfaceHandle_t surfID, int renderGroup ); void DecalSurfaceDraw( IMatRenderContext *pRenderContext, int renderGroup, float flFade = 1.0f ); void DrawDecalsOnSingleSurface( IMatRenderContext *pRenderContext, SurfaceHandle_t surfID ); void R_DecalReSortMaterials( void ); void R_DecalFlushDestroyList( bool bImmediateCleanup = false ); extern VMatrix g_BrushToWorldMatrix; #include "tier0/memdbgoff.h" #endif // R_DECAL_H