Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #include <math.h>
  7. #include "mathlib/bumpvects.h"
  8. #include "colorspace.h"
  9. #include "materialsystem_global.h"
  10. #include "IHardwareConfigInternal.h"
  11. #include "materialsystem/materialsystem_config.h"
  12. // NOTE: This has to be the last file included
  13. #include "tier0/memdbgon.h"
  14. //static float texLightToLinear[256]; // texlight (0..255) to linear (0..4)
  15. static float textureToLinear[256]; // texture (0..255) to linear (0..1)
  16. static int linearToTexture[1024]; // linear (0..1) to texture (0..255)
  17. static int linearToScreen[1024]; // linear (0..1) to gamma corrected vertex light (0..255)
  18. float g_LinearToVertex[4096]; // linear (0..4) to screen corrected vertex space (0..1?)
  19. static int linearToLightmap[4096]; // linear (0..4) to screen corrected texture value (0..255)
  20. void ColorSpace::SetGamma( float screenGamma, float texGamma,
  21. float overbright, bool allowCheats, bool linearFrameBuffer )
  22. {
  23. int i, inf;
  24. float g1, g3;
  25. float g;
  26. float brightness = 0.0f; // This used to be configurable. . hardcode to 0.0
  27. if( linearFrameBuffer )
  28. {
  29. screenGamma = 1.0f;
  30. }
  31. g = screenGamma;
  32. // clamp values to prevent cheating in multiplayer
  33. if( !allowCheats )
  34. {
  35. if (brightness > 2.0f)
  36. brightness = 2.0f;
  37. if (g < 1.8f)
  38. g = 1.8f;
  39. }
  40. if (g > 3.0)
  41. g = 3.0;
  42. g = 1.0f / g;
  43. g1 = texGamma * g;
  44. // pow( textureColor, g1 ) converts from on-disk texture space to framebuffer space
  45. if (brightness <= 0.0f)
  46. {
  47. g3 = 0.125;
  48. }
  49. else if (brightness > 1.0f)
  50. {
  51. g3 = 0.05f;
  52. }
  53. else
  54. {
  55. g3 = 0.125f - (brightness * brightness) * 0.075f;
  56. }
  57. for (i=0 ; i<1024 ; i++)
  58. {
  59. float f;
  60. f = i / 1023.0f;
  61. // scale up
  62. if (brightness > 1.0f)
  63. f = f * brightness;
  64. // shift up
  65. if (f <= g3)
  66. f = (f / g3) * 0.125f;
  67. else
  68. f = 0.125f + ((f - g3) / (1.0f - g3)) * 0.875f;
  69. // convert linear space to desired gamma space
  70. inf = ( int )( 255 * pow ( f, g ) );
  71. if (inf < 0)
  72. inf = 0;
  73. if (inf > 255)
  74. inf = 255;
  75. linearToScreen[i] = inf;
  76. }
  77. for (i=0 ; i<256 ; i++)
  78. {
  79. // convert from nonlinear texture space (0..255) to linear space (0..1)
  80. textureToLinear[i] = ( float )pow( i / 255.0f, texGamma );
  81. }
  82. for (i=0 ; i<1024 ; i++)
  83. {
  84. // convert from linear space (0..1) to nonlinear texture space (0..255)
  85. linearToTexture[i] = ( int )( pow( i / 1023.0f, 1.0f / texGamma ) * 255 );
  86. }
  87. #if 0
  88. for (i=0 ; i<256 ; i++)
  89. {
  90. float f;
  91. // convert from nonlinear lightmap space (0..255) to linear space (0..4)
  92. f = ( float )( (i / 255.0f) * sqrt( 4 ) );
  93. f = f * f;
  94. texLightToLinear[i] = f;
  95. }
  96. #endif
  97. float f, overbrightFactor;
  98. // Can't do overbright without texcombine
  99. // UNDONE: Add GAMMA ramp to rectify this
  100. if ( !HardwareConfig() )
  101. {
  102. overbright = 1.0f;
  103. }
  104. if ( overbright == 2.0 )
  105. {
  106. overbrightFactor = 0.5;
  107. }
  108. else if ( overbright == 4.0 )
  109. {
  110. overbrightFactor = 0.25;
  111. }
  112. else
  113. {
  114. overbrightFactor = 1.0;
  115. }
  116. for (i=0 ; i<4096 ; i++)
  117. {
  118. // convert from linear 0..4 (x1024) to screen corrected vertex space (0..1?)
  119. f = ( float )pow ( i/1024.0f, 1.0f / screenGamma );
  120. g_LinearToVertex[i] = f * overbrightFactor;
  121. if (g_LinearToVertex[i] > 1)
  122. g_LinearToVertex[i] = 1;
  123. linearToLightmap[i] = ( int )( f * 255 * overbrightFactor );
  124. if (linearToLightmap[i] > 255)
  125. linearToLightmap[i] = 255;
  126. }
  127. }
  128. // convert texture to linear 0..1 value
  129. float ColorSpace::TextureToLinear( int c )
  130. {
  131. if (c < 0)
  132. return 0;
  133. if (c > 255)
  134. return 1.0f;
  135. return textureToLinear[c];
  136. }
  137. // convert texture to linear 0..1 value
  138. int ColorSpace::LinearToTexture( float f )
  139. {
  140. int i;
  141. i = ( int )( f * 1023.0f ); // assume 0..1 range
  142. if (i < 0)
  143. i = 0;
  144. if (i > 1023)
  145. i = 1023;
  146. return linearToTexture[i];
  147. }
  148. float ColorSpace::TexLightToLinear( int c, int exponent )
  149. {
  150. // return texLightToLinear[ c ];
  151. // optimize me
  152. return ( float )c * ( float )pow( 2.0f, exponent ) * ( 1.0f / 255.0f );
  153. }
  154. // converts 0..1 linear value to screen gamma (0..255)
  155. int ColorSpace::LinearToScreenGamma( float f )
  156. {
  157. int i;
  158. i = ( int )( f * 1023.0f ); // assume 0..1 range
  159. if (i < 0)
  160. i = 0;
  161. if (i > 1023)
  162. i = 1023;
  163. return linearToScreen[i];
  164. }
  165. uint16 ColorSpace::LinearFloatToCorrectedShort( float in )
  166. {
  167. uint16 out;
  168. in = min( in * 4096.0, 65535.0 );
  169. out = max( in, 0.0f );
  170. return out;
  171. }