diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /bitmap/float_bm2.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'bitmap/float_bm2.cpp')
| -rw-r--r-- | bitmap/float_bm2.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/bitmap/float_bm2.cpp b/bitmap/float_bm2.cpp new file mode 100644 index 0000000..2e113c7 --- /dev/null +++ b/bitmap/float_bm2.cpp @@ -0,0 +1,144 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include <tier0/platform.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <stdlib.h> +#include "bitmap/float_bm.h" + + +static float ScaleValue(float f, float overbright) +{ + // map a value between 0..255 to the scale factor + int ival=f; + return ival*(overbright/255.0); +} + +static float IScaleValue(float f, float overbright) +{ + f*=(1.0/overbright); + int ival=min(255,(int)ceil(f*255.0)); + return ival; +} + +void MaybeSetScaleVaue(FloatBitMap_t const &orig, FloatBitMap_t &newbm, int x, int y, + float newscale, float overbright) +{ + // clamp the given scale value to the legal range for that pixel and regnerate the rgb + // components. + float maxc=max(max(orig.Pixel(x,y,0),orig.Pixel(x,y,1)),orig.Pixel(x,y,2)); + if (maxc==0.0) + { + // pixel is black. any scale value is fine. + newbm.Pixel(x,y,3)=newscale; + for(int c=0;c<3;c++) + newbm.Pixel(x,y,c)=0; + } + else + { +// float desired_floatscale=maxc; + float scale_we_will_get=ScaleValue(newscale,overbright); +// if (scale_we_will_get >= desired_floatscale ) + { + newbm.Pixel(x,y,3)=newscale; + for(int c=0;c<3;c++) + newbm.Pixel(x,y,c)=orig.Pixel(x,y,c)/(scale_we_will_get); + } + } +} + + +void FloatBitMap_t::Uncompress(float overbright) +{ + for(int y=0;y<Height;y++) + for(int x=0;x<Width;x++) + { + int iactual_alpha_value=255.0*Pixel(x,y,3); + float actual_alpha_value=iactual_alpha_value*(1.0/255.0); + for(int c=0;c<3;c++) + { + int iactual_color_value=255.0*Pixel(x,y,c); + float actual_color_value=iactual_color_value*(1.0/255.0); + Pixel(x,y,c)=actual_alpha_value*actual_color_value*overbright; + } + } +} + +#define GAUSSIAN_WIDTH 5 +#define SQ(x) ((x)*(x)) + +void FloatBitMap_t::CompressTo8Bits(float overbright) +{ + FloatBitMap_t TmpFBM(Width,Height); + // first, saturate to max overbright + for(int y=0;y<Height;y++) + for(int x=0;x<Width;x++) + for(int c=0;c<3;c++) + Pixel(x,y,c)=min(overbright,Pixel(x,y,c)); + // first pass - choose nominal scale values to convert to rgb,scale + for(int y=0;y<Height;y++) + for(int x=0;x<Width;x++) + { + // determine maximum component + float maxc=max(max(Pixel(x,y,0),Pixel(x,y,1)),Pixel(x,y,2)); + if (maxc==0) + { + for(int c=0;c<4;c++) + TmpFBM.Pixel(x,y,c)=0; + } + else + { + float desired_floatscale=maxc; + float closest_iscale=IScaleValue(desired_floatscale, overbright); + float scale_value_we_got=ScaleValue(closest_iscale, overbright ); + TmpFBM.Pixel(x,y,3)=closest_iscale; + for(int c=0;c<3;c++) + TmpFBM.Pixel(x,y,c)=Pixel(x,y,c)/scale_value_we_got; + } + } + // now, refine scale values +#ifdef FILTER_TO_REDUCE_LERP_ARTIFACTS +// I haven't been able to come up with a filter which eleiminates objectionable artifacts on all +// source textures. So, I've gone to doing the lerping in the shader. + int pass=0; + while(pass<1) + { + FloatBitMap_t temp_filtered(&TmpFBM); + for(int y=0;y<Height;y++) + { + for(int x=0;x<Width;x++) + { + float sum_scales=0.0; + float sum_weights=0.0; + for(int yofs=-GAUSSIAN_WIDTH;yofs<=GAUSSIAN_WIDTH;yofs++) + for(int xofs=-GAUSSIAN_WIDTH;xofs<=GAUSSIAN_WIDTH;xofs++) + { + float r=0.456*GAUSSIAN_WIDTH; + r=0.26*GAUSSIAN_WIDTH; + float x1=xofs/r; + float y1=yofs/r; + float a=(SQ(x1)+SQ(y1))/(2.0*SQ(r)); + float w=exp(-a); + sum_scales+=w*TmpFBM.PixelClamped(x+xofs,y+yofs,3); + sum_weights+=w; + } + int new_trial_scale=sum_scales*(1.0/sum_weights); + MaybeSetScaleVaue(*this,temp_filtered,x,y,new_trial_scale,overbright); + } + } + pass++; + memcpy(TmpFBM.RGBAData,temp_filtered.RGBAData,Width*Height*4*sizeof(float)); + } +#endif + + memcpy(RGBAData,TmpFBM.RGBAData,Width*Height*4*sizeof(float)); + // now, map scale to real value + for(int y=0;y<Height;y++) + for(int x=0;x<Width;x++) + Pixel(x,y,3)*=(1.0/255.0); +} |