You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
4.4 KiB
212 lines
4.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=====================================================================================// |
|
|
|
#include <math.h> |
|
#include "mathlib/bumpvects.h" |
|
#include "colorspace.h" |
|
#include "materialsystem_global.h" |
|
#include "IHardwareConfigInternal.h" |
|
#include "materialsystem/materialsystem_config.h" |
|
|
|
// NOTE: This has to be the last file included |
|
#include "tier0/memdbgon.h" |
|
|
|
//static float texLightToLinear[256]; // texlight (0..255) to linear (0..4) |
|
static float textureToLinear[256]; // texture (0..255) to linear (0..1) |
|
static int linearToTexture[1024]; // linear (0..1) to texture (0..255) |
|
static int linearToScreen[1024]; // linear (0..1) to gamma corrected vertex light (0..255) |
|
float g_LinearToVertex[4096]; // linear (0..4) to screen corrected vertex space (0..1?) |
|
static int linearToLightmap[4096]; // linear (0..4) to screen corrected texture value (0..255) |
|
|
|
void ColorSpace::SetGamma( float screenGamma, float texGamma, |
|
float overbright, bool allowCheats, bool linearFrameBuffer ) |
|
{ |
|
int i, inf; |
|
float g1, g3; |
|
float g; |
|
float brightness = 0.0f; // This used to be configurable. . hardcode to 0.0 |
|
|
|
if( linearFrameBuffer ) |
|
{ |
|
screenGamma = 1.0f; |
|
} |
|
|
|
g = screenGamma; |
|
|
|
// clamp values to prevent cheating in multiplayer |
|
if( !allowCheats ) |
|
{ |
|
if (brightness > 2.0f) |
|
brightness = 2.0f; |
|
|
|
if (g < 1.8f) |
|
g = 1.8f; |
|
} |
|
|
|
if (g > 3.0) |
|
g = 3.0; |
|
|
|
g = 1.0f / g; |
|
g1 = texGamma * g; |
|
|
|
// pow( textureColor, g1 ) converts from on-disk texture space to framebuffer space |
|
|
|
if (brightness <= 0.0f) |
|
{ |
|
g3 = 0.125; |
|
} |
|
else if (brightness > 1.0f) |
|
{ |
|
g3 = 0.05f; |
|
} |
|
else |
|
{ |
|
g3 = 0.125f - (brightness * brightness) * 0.075f; |
|
} |
|
|
|
for (i=0 ; i<1024 ; i++) |
|
{ |
|
float f; |
|
|
|
f = i / 1023.0f; |
|
|
|
// scale up |
|
if (brightness > 1.0f) |
|
f = f * brightness; |
|
|
|
// shift up |
|
if (f <= g3) |
|
f = (f / g3) * 0.125f; |
|
else |
|
f = 0.125f + ((f - g3) / (1.0f - g3)) * 0.875f; |
|
|
|
// convert linear space to desired gamma space |
|
inf = ( int )( 255 * pow ( f, g ) ); |
|
|
|
if (inf < 0) |
|
inf = 0; |
|
if (inf > 255) |
|
inf = 255; |
|
linearToScreen[i] = inf; |
|
} |
|
|
|
for (i=0 ; i<256 ; i++) |
|
{ |
|
// convert from nonlinear texture space (0..255) to linear space (0..1) |
|
textureToLinear[i] = ( float )pow( i / 255.0f, texGamma ); |
|
} |
|
|
|
for (i=0 ; i<1024 ; i++) |
|
{ |
|
// convert from linear space (0..1) to nonlinear texture space (0..255) |
|
linearToTexture[i] = ( int )( pow( i / 1023.0f, 1.0f / texGamma ) * 255 ); |
|
} |
|
|
|
#if 0 |
|
for (i=0 ; i<256 ; i++) |
|
{ |
|
float f; |
|
|
|
// convert from nonlinear lightmap space (0..255) to linear space (0..4) |
|
f = ( float )( (i / 255.0f) * sqrt( 4 ) ); |
|
f = f * f; |
|
|
|
texLightToLinear[i] = f; |
|
} |
|
#endif |
|
|
|
float f, overbrightFactor; |
|
|
|
// Can't do overbright without texcombine |
|
// UNDONE: Add GAMMA ramp to rectify this |
|
|
|
if ( !HardwareConfig() ) |
|
{ |
|
overbright = 1.0f; |
|
} |
|
if ( overbright == 2.0 ) |
|
{ |
|
overbrightFactor = 0.5; |
|
} |
|
else if ( overbright == 4.0 ) |
|
{ |
|
overbrightFactor = 0.25; |
|
} |
|
else |
|
{ |
|
overbrightFactor = 1.0; |
|
} |
|
|
|
for (i=0 ; i<4096 ; i++) |
|
{ |
|
// convert from linear 0..4 (x1024) to screen corrected vertex space (0..1?) |
|
f = ( float )pow ( i/1024.0f, 1.0f / screenGamma ); |
|
|
|
g_LinearToVertex[i] = f * overbrightFactor; |
|
if (g_LinearToVertex[i] > 1) |
|
g_LinearToVertex[i] = 1; |
|
|
|
linearToLightmap[i] = ( int )( f * 255 * overbrightFactor ); |
|
if (linearToLightmap[i] > 255) |
|
linearToLightmap[i] = 255; |
|
} |
|
} |
|
|
|
// convert texture to linear 0..1 value |
|
float ColorSpace::TextureToLinear( int c ) |
|
{ |
|
if (c < 0) |
|
return 0; |
|
if (c > 255) |
|
return 1.0f; |
|
|
|
return textureToLinear[c]; |
|
} |
|
|
|
// convert texture to linear 0..1 value |
|
int ColorSpace::LinearToTexture( float f ) |
|
{ |
|
int i; |
|
i = ( int )( f * 1023.0f ); // assume 0..1 range |
|
if (i < 0) |
|
i = 0; |
|
if (i > 1023) |
|
i = 1023; |
|
|
|
return linearToTexture[i]; |
|
} |
|
|
|
float ColorSpace::TexLightToLinear( int c, int exponent ) |
|
{ |
|
// return texLightToLinear[ c ]; |
|
// optimize me |
|
return ( float )c * ( float )pow( 2.0f, exponent ) * ( 1.0f / 255.0f ); |
|
} |
|
|
|
// converts 0..1 linear value to screen gamma (0..255) |
|
int ColorSpace::LinearToScreenGamma( float f ) |
|
{ |
|
int i; |
|
i = ( int )( f * 1023.0f ); // assume 0..1 range |
|
if (i < 0) |
|
i = 0; |
|
if (i > 1023) |
|
i = 1023; |
|
|
|
return linearToScreen[i]; |
|
} |
|
|
|
|
|
uint16 ColorSpace::LinearFloatToCorrectedShort( float in ) |
|
{ |
|
uint16 out; |
|
in = min( in * 4096.0, 65535.0 ); |
|
out = max( in, 0.0f ); |
|
|
|
return out; |
|
} |
|
|
|
|
|
|