hl2_src-leak-2017/src/materialsystem/CColorCorrection.cpp

838 lines
28 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Color correction system
//
//==============================================================================
#if defined (WIN32) && !defined( _X360 )
#include <windows.h>
#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; i<COLOR_CORRECTION_MAX_TEXTURES; i++ )
{
if ( m_pColorCorrectionTexture == TextureManager()->ColorCorrectionTexture( 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;i<m_ColorCorrectionList.Count();i++ )
{
delete m_ColorCorrectionList[i];
}
MaterialSystem()->RemoveReleaseFunc( 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;i<COLOR_CORRECTION_MAX_TEXTURES && i<m_ColorCorrectionList.Count();i++ )
{
TextureManager()->SetColorCorrectionTexture( i, m_ColorCorrectionList[i]->m_pColorCorrectionTexture );
}
for ( int i=m_ColorCorrectionList.Count();i<COLOR_CORRECTION_MAX_TEXTURES;i++ )
{
TextureManager()->SetColorCorrectionTexture( i, NULL );
}
}
//-----------------------------------------------------------------------------
// Find the ColorCorrectionLookup_t corresponding to the specified handle
//-----------------------------------------------------------------------------
ColorCorrectionLookup_t *CColorCorrectionSystem::FindLookup( ColorCorrectionHandle_t handle )
{
for ( int i=0; i<m_ColorCorrectionList.Count(); i++ )
{
if ( m_ColorCorrectionList[i]->m_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;i<m_ColorCorrectionList.Count();i++ )
{
ColorCorrectionLookup_t *lookup = m_ColorCorrectionList[i];
if ( lookup->m_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 ( i<m_ColorCorrectionList.Count() )
{
if ( i==-1 )
return m_DefaultColorCorrectionWeight;
ColorCorrectionLookup_t *lookup = m_ColorCorrectionList[ i ];
return lookup->m_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;i<m_ColorCorrectionList.Count();i++ )
{
ColorCorrectionLookup_t *lookup = m_ColorCorrectionList[i];
if ( lookup->m_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;i<m_ColorCorrectionList.Count();i++ )
{
m_ColorCorrectionList[i]->ReleaseTexture();
}
}
//-----------------------------------------------------------------------------
// Call RestoreTexture for all ColorCorrectionLookup_t
//-----------------------------------------------------------------------------
void CColorCorrectionSystem::RestoreTextures( )
{
for ( int i=0;i<m_ColorCorrectionList.Count();i++ )
{
m_ColorCorrectionList[i]->RestoreTexture();
}
}
//-----------------------------------------------------------------------------
// 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; i<nLoopCount; i++ )
{
total_weight += m_ColorCorrectionList[i]->m_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;i<m_ColorCorrectionList.Count()&&i<COLOR_CORRECTION_MAX_TEXTURES;i++ )
{
if ( m_ColorCorrectionList[i]->m_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 );
}