//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Color correction system // //============================================================================== #if defined (WIN32) && !defined( _X360 ) #include #elif POSIX #define _cdecl #endif #include "materialsystem/IColorCorrection.h" #include "materialsystem_global.h" #include "shaderapi/ishaderapi.h" #include "texturemanager.h" #include "utlvector.h" #include "generichash.h" #include "filesystem.h" #include "filesystem/IQueuedLoader.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" class ITextureInternal; //----------------------------------------------------------------------------- // Holds all the necessary information for a single color correction lookup // function //----------------------------------------------------------------------------- struct ColorCorrectionLookup_t { ColorCorrectionHandle_t m_Handle; ITextureInternal *m_pColorCorrectionTexture; color24 m_pColorCorrection[COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE]; bool m_bLocked; float m_flWeight; bool m_bResetable; ColorCorrectionLookup_t( ColorCorrectionHandle_t handle ); ~ColorCorrectionLookup_t( ); void ReleaseTexture(); void RestoreTexture(); void AllocTexture(); }; ColorCorrectionLookup_t::ColorCorrectionLookup_t( ColorCorrectionHandle_t handle ) { m_Handle = handle; m_bLocked = false; m_flWeight = 1.0f; m_bResetable = true; AllocTexture(); } ColorCorrectionLookup_t::~ColorCorrectionLookup_t( ) { // We must remove the texture from the active color correction // textures, otherwise we may leak a reference if ( m_pColorCorrectionTexture ) { for ( int i=0; iColorCorrectionTexture( i ) ) { TextureManager()->SetColorCorrectionTexture( i, NULL ); } } m_pColorCorrectionTexture->DecrementReferenceCount(); ITextureInternal::Destroy( m_pColorCorrectionTexture ); m_pColorCorrectionTexture = NULL; } } void ColorCorrectionLookup_t::AllocTexture() { char name[64]; sprintf( name, "ColorCorrection - %d", m_Handle ); m_pColorCorrectionTexture = ITextureInternal::CreateProceduralTexture( name, TEXTURE_GROUP_OTHER, COLOR_CORRECTION_TEXTURE_SIZE, COLOR_CORRECTION_TEXTURE_SIZE, COLOR_CORRECTION_TEXTURE_SIZE, IMAGE_FORMAT_BGRX8888, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_SINGLECOPY | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_CLAMPU | TEXTUREFLAGS_NODEBUGOVERRIDE ); extern void CreateColorCorrectionTexture( ITextureInternal *pTexture, ColorCorrectionHandle_t handle ); CreateColorCorrectionTexture( m_pColorCorrectionTexture, m_Handle ); m_pColorCorrectionTexture->Download(); } void ColorCorrectionLookup_t::ReleaseTexture() { m_pColorCorrectionTexture->ReleaseMemory(); } void ColorCorrectionLookup_t::RestoreTexture() { // Put the texture back onto the board m_pColorCorrectionTexture->OnRestore(); // Give render targets a chance to reinitialize themselves if necessary (due to AA changes). m_pColorCorrectionTexture->Download(); } //----------------------------------------------------------------------------- // IColorCorrectionSystem interface implementation //----------------------------------------------------------------------------- class CColorCorrectionSystem : public IColorCorrectionSystem { public: virtual void Init(); virtual void Shutdown(); virtual void LockLookup(); virtual void SetLookup( RGBX5551_t inColor, color24 outColor ); virtual void UnlockLookup(); virtual color24 GetLookup( RGBX5551_t inColor ); virtual void LoadLookup( const char *pLookupName ); virtual void CopyLookup( const color24 *pSrcColorCorrection ); virtual void ResetLookup( ); virtual ColorCorrectionHandle_t AddLookup( const char *pName ); virtual bool RemoveLookup( ColorCorrectionHandle_t handle ); virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ); virtual float GetLookupWeight( ColorCorrectionHandle_t handle ); virtual float GetLookupWeight( int i ); virtual void LockLookup( ColorCorrectionHandle_t handle ); virtual void SetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor, color24 outColor ); virtual color24 GetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor ); virtual void UnlockLookup( ColorCorrectionHandle_t handle ); virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ); virtual void CopyLookup( ColorCorrectionHandle_t handle, const color24 *pSrcColorCorrection ); virtual void ResetLookup( ColorCorrectionHandle_t handle ); virtual void ResetLookupWeights( ); virtual void ReleaseTextures( ); virtual void RestoreTextures( ); virtual color24 ConvertToColor24( RGBX5551_t inColor ); virtual int GetNumLookups( ); virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ); virtual void GetCurrentColorCorrection( ShaderColorCorrectionInfo_t* pInfo ); virtual void EnableColorCorrection( bool bEnable ); protected: CUtlVector< ColorCorrectionLookup_t * > m_ColorCorrectionList; ColorCorrectionHandle_t m_DefaultColorCorrectionHandle; ColorCorrectionHandle_t m_UnnamedColorCorrectionHandle; float m_DefaultColorCorrectionWeight; bool m_bEnabled; void SortLookups( ); ColorCorrectionLookup_t *FindLookup( ColorCorrectionHandle_t handle ); ColorCorrectionHandle_t GetLookupHandle( const char *pName ); void SetLookupPtr( ColorCorrectionLookup_t *lookup, RGBX5551_t inColor, color24 outColor ); void GetNormalizedWeights( float *pDefaultWeight, float *pLookupWeights ); }; CColorCorrectionSystem g_ColorCorrectionSystem; IColorCorrectionSystem *g_pColorCorrectionSystem = &g_ColorCorrectionSystem; #ifndef _X360 // Don't allow this on the 360.. it doesn't work in mat_queued_mode EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CColorCorrectionSystem, IColorCorrectionSystem, COLORCORRECTION_INTERFACE_VERSION, g_ColorCorrectionSystem ); #endif //----------------------------------------------------------------------------- // Wrappers for release/restore functionality //----------------------------------------------------------------------------- void ReleaseColorCorrection() { g_pColorCorrectionSystem->ReleaseTextures(); } void RestoreColorCorrection( int changeFlags ) { g_pColorCorrectionSystem->RestoreTextures(); } //----------------------------------------------------------------------------- // Init function //----------------------------------------------------------------------------- void CColorCorrectionSystem::Init() { m_DefaultColorCorrectionHandle = (ColorCorrectionHandle_t)-1; m_UnnamedColorCorrectionHandle = GetLookupHandle( "unnamed" ); m_DefaultColorCorrectionWeight = 0.0f; m_bEnabled = true; MaterialSystem()->AddReleaseFunc( ReleaseColorCorrection ); MaterialSystem()->AddRestoreFunc( RestoreColorCorrection ); } //----------------------------------------------------------------------------- // Shutdown function //----------------------------------------------------------------------------- void CColorCorrectionSystem::Shutdown() { for ( int i=0;iRemoveReleaseFunc( ReleaseColorCorrection ); MaterialSystem()->RemoveRestoreFunc( RestoreColorCorrection ); } //----------------------------------------------------------------------------- // Global enable/disable of color correction //----------------------------------------------------------------------------- void CColorCorrectionSystem::EnableColorCorrection( bool bEnable ) { m_bEnabled = bEnable; } //----------------------------------------------------------------------------- // Lock the "unnamed" color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::LockLookup() { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) { AddLookup( "unnamed" ); } LockLookup( m_UnnamedColorCorrectionHandle ); } //----------------------------------------------------------------------------- // Set the specified mapping for the "unnamed" color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::SetLookup( RGBX5551_t inColor, color24 outColor ) { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) return; SetLookup( m_UnnamedColorCorrectionHandle, inColor, outColor ); } //----------------------------------------------------------------------------- // Unlock the "unnamed" color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::UnlockLookup() { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) return; UnlockLookup( m_UnnamedColorCorrectionHandle ); } //----------------------------------------------------------------------------- // Get the specified mapping from the "unnamed" color correction lookup //----------------------------------------------------------------------------- color24 CColorCorrectionSystem::GetLookup( RGBX5551_t inColor ) { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) AddLookup( "unnamed" ); return GetLookup( m_UnnamedColorCorrectionHandle, inColor ); } //----------------------------------------------------------------------------- // Load the specified file into the "unnamed" color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::LoadLookup( const char *pLookupName ) { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) return; return LoadLookup( m_UnnamedColorCorrectionHandle, pLookupName ); } //----------------------------------------------------------------------------- // Copy the specified data into the "unnamed" color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::CopyLookup( const color24 *pSrcColorCorrection ) { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) return; CopyLookup( m_UnnamedColorCorrectionHandle, pSrcColorCorrection ); } //----------------------------------------------------------------------------- // Reset the "unnamed" color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::ResetLookup( ) { ColorCorrectionLookup_t *lookup = FindLookup( m_UnnamedColorCorrectionHandle ); if ( !lookup ) return; return ResetLookup( m_UnnamedColorCorrectionHandle ); } //----------------------------------------------------------------------------- // ColorCorrectionLookup_t sorting function //----------------------------------------------------------------------------- typedef ColorCorrectionLookup_t * CCLPtr; int _cdecl CompareLookups( const CCLPtr *lookup_a, const CCLPtr *lookup_b ) { if ( (*lookup_a)->m_flWeight < (*lookup_b)->m_flWeight ) return 1; else if ( (*lookup_a)->m_flWeight > (*lookup_b)->m_flWeight ) return -1; return 0; } //----------------------------------------------------------------------------- // Sort ColorCorrectionLookup_t vector based on decreasing weight //----------------------------------------------------------------------------- void CColorCorrectionSystem::SortLookups( ) { m_ColorCorrectionList.Sort( CompareLookups ); for ( int i=0;iSetColorCorrectionTexture( i, m_ColorCorrectionList[i]->m_pColorCorrectionTexture ); } for ( int i=m_ColorCorrectionList.Count();iSetColorCorrectionTexture( i, NULL ); } } //----------------------------------------------------------------------------- // Find the ColorCorrectionLookup_t corresponding to the specified handle //----------------------------------------------------------------------------- ColorCorrectionLookup_t *CColorCorrectionSystem::FindLookup( ColorCorrectionHandle_t handle ) { for ( int i=0; im_Handle == handle ) { return m_ColorCorrectionList[i]; } } return NULL; } //----------------------------------------------------------------------------- // Find the handle associated with a specified name //----------------------------------------------------------------------------- ColorCorrectionHandle_t CColorCorrectionSystem::GetLookupHandle( const char *pName ) { // case and slash insensitive FileNameHandle_t hName = g_pFullFileSystem->FindOrAddFileName( pName ); COMPILE_TIME_ASSERT( sizeof( FileNameHandle_t ) == sizeof( ColorCorrectionHandle_t ) ); return (ColorCorrectionHandle_t)hName; } //----------------------------------------------------------------------------- // Add a color correction lookup with the specified name //----------------------------------------------------------------------------- ColorCorrectionHandle_t CColorCorrectionSystem::AddLookup( const char *pName ) { ColorCorrectionHandle_t handle = GetLookupHandle( pName ); if ( handle == m_DefaultColorCorrectionHandle ) return handle; ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( lookup ) { // Warning( "Cannot have 2 lookups referencing the same name %s\n", pName ); // NOTE: Cannot use 0xFFFFFFFF because that's the default handle return (ColorCorrectionHandle_t)0xFFFFFFFE; } lookup = new ColorCorrectionLookup_t( handle ); m_ColorCorrectionList.AddToTail( lookup ); LockLookup( handle ); ResetLookup( handle ); UnlockLookup( handle ); SetLookupWeight( handle, 1.0f ); return handle; } //----------------------------------------------------------------------------- // Remove the specified color correction lookup //----------------------------------------------------------------------------- bool CColorCorrectionSystem::RemoveLookup( ColorCorrectionHandle_t handle ) { if ( handle == m_DefaultColorCorrectionHandle ) return false; for ( int i=0;im_Handle == handle ) { m_ColorCorrectionList.Remove( i ); delete lookup; return true; } } return false; } //----------------------------------------------------------------------------- // Sets the weight for the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) { if ( handle == m_DefaultColorCorrectionHandle ) { m_DefaultColorCorrectionWeight = flWeight; return; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( lookup && flWeight>lookup->m_flWeight ) { lookup->m_flWeight = flWeight; } SortLookups( ); } //----------------------------------------------------------------------------- // Gets the weight for the specified color correction lookup //----------------------------------------------------------------------------- float CColorCorrectionSystem::GetLookupWeight( ColorCorrectionHandle_t handle ) { if ( handle == m_DefaultColorCorrectionHandle ) { return m_DefaultColorCorrectionWeight; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return 0.0f; return lookup->m_flWeight; } //----------------------------------------------------------------------------- // Gets the weight for the color correction lookup specified by index //----------------------------------------------------------------------------- float CColorCorrectionSystem::GetLookupWeight( int i ) { if ( im_flWeight; } return 0.0f; } //----------------------------------------------------------------------------- // Lock the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::LockLookup( ColorCorrectionHandle_t handle ) { if ( handle == m_DefaultColorCorrectionHandle ) { return; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return; lookup->m_bLocked = true; } //----------------------------------------------------------------------------- // Set the mapping for the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::SetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor, color24 outColor ) { if ( handle == m_DefaultColorCorrectionHandle ) return; ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return; SetLookupPtr( lookup, inColor, outColor ); } //----------------------------------------------------------------------------- // Set the mapping for the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::SetLookupPtr( ColorCorrectionLookup_t *lookup, RGBX5551_t inColor, color24 outColor ) { Assert( lookup->m_bLocked ); lookup->m_pColorCorrection[inColor.r + inColor.g*COLOR_CORRECTION_TEXTURE_SIZE + inColor.b*COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE] = outColor; } //----------------------------------------------------------------------------- // Get the mapping for the specified color correction lookup //----------------------------------------------------------------------------- color24 CColorCorrectionSystem::GetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor ) { if ( handle == m_DefaultColorCorrectionHandle ) { color24 col = ConvertToColor24( inColor ); return col; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) { color24 col; col.r = 0; col.g = 0; col.b = 0; return col; } return lookup->m_pColorCorrection[inColor.r + inColor.g*COLOR_CORRECTION_TEXTURE_SIZE + inColor.b*COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE]; } //----------------------------------------------------------------------------- // Unlock the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::UnlockLookup( ColorCorrectionHandle_t handle ) { if ( handle == m_DefaultColorCorrectionHandle ) { return; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return; lookup->m_bLocked = false; lookup->m_pColorCorrectionTexture->Download(); } //----------------------------------------------------------------------------- // Load the specified file into the color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) { if ( handle == m_DefaultColorCorrectionHandle ) { return; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return; Assert( lookup->m_bLocked ); Assert( pLookupName ); CUtlBuffer colorBuff; if ( !g_pFullFileSystem->ReadFile( pLookupName, "GAME", colorBuff ) ) { return; } int res = (int)powf( (float)( colorBuff.TellMaxPut()/sizeof( color24 ) ), 1.0f/3.0f ); if ( res != COLOR_CORRECTION_TEXTURE_SIZE || res*res*res*(int)sizeof( color24 ) != colorBuff.TellMaxPut() ) { Warning( "CColorCorrectionSystem: Raw file '%s' has bad size (%d)\n", pLookupName, colorBuff.TellMaxPut() ); return; } color24 *pColors = (color24 *)colorBuff.Base(); int colorIndex = 0; RGBX5551_t inColor; inColor.b = 0; for ( int b = 0; b < COLOR_CORRECTION_TEXTURE_SIZE; ++b, ++inColor.b ) { inColor.g = 0; for ( int g = 0; g < COLOR_CORRECTION_TEXTURE_SIZE; ++g, ++inColor.g ) { inColor.r = 0; for ( int r = 0; r < COLOR_CORRECTION_TEXTURE_SIZE; ++r, ++inColor.r ) { color24 vOutColor24 = pColors[colorIndex]; /* // Still experimenting with this...it looks banded right now so leaving it off. // I think we need to generate better raw data for the 360 instead of hacking it here. if ( IsX360() ) { // We need to adjust the outcolor for the 360's piecewise linear gamma space // So apply SrgbLinearToGamma( X360GammaToLinear( inColor.rgb ) ) to fetch the desired // srgb outColor assuming a 360 gamma input color and then put that into 360 gamma space as the new outColor // Our input is in 360 gamma space color24 inColor24 = ConvertToColor24( inColor ); float flInColor360[3] = { float( inColor24.r ) / float( 255 ), float( inColor24.g ) / float( 255 ), float( inColor24.b ) / float( 255 ) }; // Find the srgb gamma color this maps to float flInColorSrgb[3]; for ( int i = 0; i < 3; i++ ) { flInColorSrgb[i] = SrgbLinearToGamma( X360GammaToLinear( flInColor360[i] ) ); } int nInColor[3]; for ( int i = 0; i < 3; i++ ) { nInColor[i] = ( int )( flInColorSrgb[i] * float( COLOR_CORRECTION_TEXTURE_SIZE - 1 ) ); } // Now convert the sRGB out color into 360 gamma space color24 vOutColor24Srgb = pColors[nInColor[0] + nInColor[1]*COLOR_CORRECTION_TEXTURE_SIZE + nInColor[2]*COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE]; color24 vOutColor24X360; vOutColor24X360.r = ( unsigned char )( X360LinearToGamma( SrgbGammaToLinear( float( vOutColor24Srgb.r ) / float( 255 ) ) ) * float( 255 ) ); vOutColor24X360.g = ( unsigned char )( X360LinearToGamma( SrgbGammaToLinear( float( vOutColor24Srgb.g ) / float( 255 ) ) ) * float( 255 ) ); vOutColor24X360.b = ( unsigned char )( X360LinearToGamma( SrgbGammaToLinear( float( vOutColor24Srgb.b ) / float( 255 ) ) ) * float( 255 ) ); // Copy the outColor and pass that to SetLookupPtr() below vOutColor24 = vOutColor24X360; } //*/ SetLookupPtr( lookup, inColor, vOutColor24 ); colorIndex++; } } } } //----------------------------------------------------------------------------- // Copy the data to the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::CopyLookup( ColorCorrectionHandle_t handle, const color24 *pSrcColorCorrection ) { if ( handle == m_DefaultColorCorrectionHandle ) { return; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return; Assert( lookup->m_bLocked ); Assert( pSrcColorCorrection ); Q_memcpy( lookup->m_pColorCorrection, pSrcColorCorrection, sizeof(color24)*COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE*COLOR_CORRECTION_TEXTURE_SIZE ); } //----------------------------------------------------------------------------- // Reset the mapping for the specified color correction lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::ResetLookup( ColorCorrectionHandle_t handle ) { if ( handle == m_DefaultColorCorrectionHandle ) { return; } ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( !lookup ) return; Assert( lookup->m_bLocked ); RGBX5551_t inColor; inColor.b = 0; for ( int b = 0; b < COLOR_CORRECTION_TEXTURE_SIZE; ++b, ++inColor.b ) { inColor.g = 0; for ( int g = 0; g < COLOR_CORRECTION_TEXTURE_SIZE; ++g, ++inColor.g ) { inColor.r = 0; for ( int r = 0; r < COLOR_CORRECTION_TEXTURE_SIZE; ++r, ++inColor.r ) { color24 outColor = ConvertToColor24( inColor ); SetLookupPtr( lookup, inColor, outColor ); } } } } //----------------------------------------------------------------------------- // Reset the weight to zero for all lookups //----------------------------------------------------------------------------- void CColorCorrectionSystem::ResetLookupWeights( ) { m_DefaultColorCorrectionWeight = 0.0f; for ( int i=0;im_bResetable ) { lookup->m_flWeight = 0.0f; } else { lookup->m_flWeight = 1.0f; } } } //----------------------------------------------------------------------------- // Convert a color from RGBX5551_t to color24 //----------------------------------------------------------------------------- color24 CColorCorrectionSystem::ConvertToColor24( RGBX5551_t inColor ) { color24 out; out.r = (inColor.r << 3) | (inColor.r >> 2); out.g = (inColor.g << 3) | (inColor.g >> 2); out.b = (inColor.b << 3) | (inColor.b >> 2); return out; } //----------------------------------------------------------------------------- // Call ReleaseTexture for all ColorCorrectionLookup_t //----------------------------------------------------------------------------- void CColorCorrectionSystem::ReleaseTextures( ) { for ( int i=0;iReleaseTexture(); } } //----------------------------------------------------------------------------- // Call RestoreTexture for all ColorCorrectionLookup_t //----------------------------------------------------------------------------- void CColorCorrectionSystem::RestoreTextures( ) { for ( int i=0;iRestoreTexture(); } } //----------------------------------------------------------------------------- // Normalize the active set of color correction weights //----------------------------------------------------------------------------- void CColorCorrectionSystem::GetNormalizedWeights( float *pDefaultWeight, float *pLookupWeights ) { float total_weight = 0.0f; int nLoopCount = min( m_ColorCorrectionList.Count(), (int)COLOR_CORRECTION_MAX_TEXTURES ); for ( int i=0; im_flWeight; pLookupWeights[i] = m_ColorCorrectionList[i]->m_flWeight; } for ( int i = nLoopCount; i < COLOR_CORRECTION_MAX_TEXTURES; ++i ) { pLookupWeights[i] = 0.0f; } if ( total_weight <= ( 1.0f - 1e-3 ) ) { *pDefaultWeight = 1.0f - total_weight; } else { *pDefaultWeight = 0.0f; float inv_total_weight = 1.0f / total_weight; for ( int i=0; i< nLoopCount; i++ ) { pLookupWeights[i] *= inv_total_weight; } } } //----------------------------------------------------------------------------- // Returns the number of active lookup //----------------------------------------------------------------------------- int CColorCorrectionSystem::GetNumLookups( ) { int i; for ( i=0;im_flWeight<=0.0f ) break; } return i; } //----------------------------------------------------------------------------- // Enables/disables resetting of this lookup //----------------------------------------------------------------------------- void CColorCorrectionSystem::SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) { ColorCorrectionLookup_t *lookup = FindLookup( handle ); if ( lookup ) { lookup->m_bResetable = bResetable; } } //----------------------------------------------------------------------------- // Returns info for the shaders to control color correction //----------------------------------------------------------------------------- void CColorCorrectionSystem::GetCurrentColorCorrection( ShaderColorCorrectionInfo_t* pInfo ) { COMPILE_TIME_ASSERT( COLOR_CORRECTION_MAX_TEXTURES == ARRAYSIZE( pInfo->m_pLookupWeights ) ); pInfo->m_bIsEnabled = m_bEnabled && ( GetNumLookups() > 0 || m_DefaultColorCorrectionWeight != 0.0f ); pInfo->m_nLookupCount = GetNumLookups(); GetNormalizedWeights( &pInfo->m_flDefaultWeight, pInfo->m_pLookupWeights ); }