Counter Strike : Global Offensive Source Code
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.

151 lines
4.6 KiB

  1. //===== Copyright � 1996-2006, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include <tier0/platform.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <stdlib.h>
  11. #include "bitmap/floatbitmap.h"
  12. // NOTE: This has to be the last file included!
  13. #include "tier0/memdbgon.h"
  14. static float ScaleValue( float f, float overbright )
  15. {
  16. // map a value between 0..255 to the scale factor
  17. int ival = ( int )f;
  18. return ival * ( overbright / 255.0 );
  19. }
  20. static float IScaleValue( float f, float overbright )
  21. {
  22. f *= ( 1.0 / overbright );
  23. int ival = ( int )MIN( 255, ceil( f * 255.0 ));
  24. return ival;
  25. }
  26. void MaybeSetScaleVaue( FloatBitMap_t const & orig, FloatBitMap_t & newbm, int x, int y,
  27. float newscale, float overbright )
  28. {
  29. // clamp the given scale value to the legal range for that pixel and regnerate the rgb
  30. // components.
  31. float maxc = MAX( MAX( orig.Pixel( x, y, 0, 0 ), orig.Pixel( x, y, 0, 1 )), orig.Pixel( x, y, 0, 2 ));
  32. if ( maxc == 0.0 )
  33. {
  34. // pixel is black. any scale value is fine.
  35. newbm.Pixel( x, y, 0, 3 ) = newscale;
  36. for( int c = 0;c < 3;c++ )
  37. newbm.Pixel( x, y, 0, c ) = 0;
  38. }
  39. else
  40. {
  41. // float desired_floatscale=maxc;
  42. float scale_we_will_get = ScaleValue( newscale, overbright );
  43. // if (scale_we_will_get >= desired_floatscale )
  44. {
  45. newbm.Pixel( x, y, 0, 3 ) = newscale;
  46. for( int c = 0;c < 3;c++ )
  47. newbm.Pixel( x, y, 0, c ) = orig.Pixel( x, y, 0, c ) / ( scale_we_will_get );
  48. }
  49. }
  50. }
  51. void FloatBitMap_t::Uncompress( float overbright )
  52. {
  53. for( int y = 0;y < NumRows();y++ )
  54. for( int x = 0;x < NumCols();x++ )
  55. {
  56. int iactual_alpha_value = ( int )( 255.0 * Pixel( x, y, 0, 3 ) );
  57. float actual_alpha_value = iactual_alpha_value * ( 1.0 / 255.0 );
  58. for( int c = 0;c < 3;c++ )
  59. {
  60. int iactual_color_value = ( int )( 255.0 * Pixel( x, y, 0, c ) );
  61. float actual_color_value = iactual_color_value * ( 1.0 / 255.0 );
  62. Pixel( x, y, 0, c ) = actual_alpha_value * actual_color_value * overbright;
  63. }
  64. }
  65. }
  66. #define GAUSSIAN_WIDTH 5
  67. #define SQ(x) ((x)*(x))
  68. void FloatBitMap_t::CompressTo8Bits( float overbright )
  69. {
  70. FloatBitMap_t TmpFBM( NumCols(), NumRows() );
  71. // first, saturate to max overbright
  72. for( int y = 0;y < NumRows();y++ )
  73. for( int x = 0;x < NumCols();x++ )
  74. for( int c = 0;c < 3;c++ )
  75. Pixel( x, y, 0, c ) = MIN( overbright, Pixel( x, y, 0, c ));
  76. // first pass - choose nominal scale values to convert to rgb,scale
  77. for( int y = 0;y < NumRows();y++ )
  78. for( int x = 0;x < NumCols();x++ )
  79. {
  80. // determine maximum component
  81. float maxc = MAX( MAX( Pixel( x, y, 0, 0 ), Pixel( x, y, 0, 1 )), Pixel( x, y, 0, 2 ));
  82. if ( maxc == 0 )
  83. {
  84. for( int c = 0;c < 4;c++ )
  85. TmpFBM.Pixel( x, y, 0, c ) = 0;
  86. }
  87. else
  88. {
  89. float desired_floatscale = maxc;
  90. float closest_iscale = IScaleValue( desired_floatscale, overbright );
  91. float scale_value_we_got = ScaleValue( closest_iscale, overbright );
  92. TmpFBM.Pixel( x, y, 0, 3 ) = closest_iscale;
  93. for( int c = 0;c < 3;c++ )
  94. TmpFBM.Pixel( x, y, 0, c ) = Pixel( x, y, 0, c ) / scale_value_we_got;
  95. }
  96. }
  97. // now, refine scale values
  98. #ifdef FILTER_TO_REDUCE_LERP_ARTIFACTS
  99. // I haven't been able to come up with a filter which eleiminates objectionable artifacts on all
  100. // source textures. So, I've gone to doing the lerping in the shader.
  101. int pass = 0;
  102. while( pass < 1 )
  103. {
  104. FloatBitMap_t temp_filtered( & TmpFBM );
  105. for( int y = 0;y < NumRows();y++ )
  106. {
  107. for( int x = 0;x < NumCols();x++ )
  108. {
  109. float sum_scales = 0.0;
  110. float sum_weights = 0.0;
  111. for( int yofs =- GAUSSIAN_WIDTH;yofs <= GAUSSIAN_WIDTH;yofs++ )
  112. for( int xofs =- GAUSSIAN_WIDTH;xofs <= GAUSSIAN_WIDTH;xofs++ )
  113. {
  114. float r = 0.456 * GAUSSIAN_WIDTH;
  115. r = 0.26 * GAUSSIAN_WIDTH;
  116. float x1 = xofs / r;
  117. float y1 = yofs / r;
  118. float a = ( SQ( x1 ) + SQ( y1 )) / ( 2.0 * SQ( r ));
  119. float w = exp( - a );
  120. sum_scales += w * TmpFBM.PixelClamped( x + xofs, y + yofs, 3 );
  121. sum_weights += w;
  122. }
  123. int new_trial_scale = sum_scales * ( 1.0 / sum_weights );
  124. MaybeSetScaleVaue( * this, temp_filtered, x, y, new_trial_scale, overbright );
  125. }
  126. }
  127. pass++;
  128. memcpy( TmpFBM.RGBAData, temp_filtered.RGBAData, NumCols() * NumRows() * 4 * sizeof( float ));
  129. }
  130. #endif
  131. CopyAttrFrom( TmpFBM, FBM_ATTR_RED );
  132. CopyAttrFrom( TmpFBM, FBM_ATTR_GREEN );
  133. CopyAttrFrom( TmpFBM, FBM_ATTR_BLUE );
  134. CopyAttrFrom( TmpFBM, FBM_ATTR_ALPHA );
  135. // now, map scale to real value
  136. for( int y = 0; y < NumRows(); y++ )
  137. for( int x = 0; x < NumCols(); x++ )
  138. Pixel( x, y, 0, 3 ) *= ( 1.0 / 255.0 );
  139. }