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.

102 lines
3.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "tier0/platform.h"
  7. #include "bitmap/float_bm.h"
  8. #include "mathlib/mathlib.h"
  9. #include "tier2/tier2.h"
  10. #include "bitmap/tgaloader.h"
  11. #define NEIGHBORHOOD_SIZE 5
  12. void SynthesizeTexture(FloatBitMap_t & output, FloatBitMap_t const & input)
  13. {
  14. // init output with histogram-equalized random pixels
  15. output.InitializeWithRandomPixelsFromAnotherFloatBM(input);
  16. // build image pyramids
  17. FloatImagePyramid_t input_pyramid(input,PYRAMID_MODE_GAUSSIAN);
  18. FloatImagePyramid_t output_pyramid(output,PYRAMID_MODE_GAUSSIAN);
  19. // now, synthesize texture from lowest res to highest
  20. for(int level=min(input_pyramid.m_nLevels,output_pyramid.m_nLevels)-2;level>=0;level--)
  21. {
  22. FloatBitMap_t & output=*(output_pyramid.Level(level));
  23. FloatBitMap_t & output0=*(output_pyramid.Level(level+1));
  24. FloatBitMap_t & input=*(input_pyramid.Level(level));
  25. FloatBitMap_t & input0=*(input_pyramid.Level(level+1));
  26. if (
  27. (input.Width < NEIGHBORHOOD_SIZE*3) ||
  28. (input.Height < NEIGHBORHOOD_SIZE*3)
  29. )
  30. {
  31. printf("skip level %d\n",level);
  32. continue;
  33. }
  34. // now, synthesize each pixel
  35. for(int yloop=0;yloop<output.Height;yloop++)
  36. {
  37. int yo=((yloop+NEIGHBORHOOD_SIZE) % output.Height);
  38. printf("level %d line %d\n",level,yo);
  39. for(int xo=0;xo<output.Width;xo++)
  40. {
  41. int best_pixel_x=-1, best_pixel_y=-1;
  42. float best_error=1.0e22;
  43. // traverse all neighborhoods of src
  44. for(int nblk_y=NEIGHBORHOOD_SIZE;nblk_y<input.Height;nblk_y++)
  45. for(int nblk_x=NEIGHBORHOOD_SIZE;nblk_x<input.Width-NEIGHBORHOOD_SIZE;nblk_x++)
  46. {
  47. float our_error=0;
  48. // now, compare this block to the neighborhood around our output pixel
  49. for(int oy=-NEIGHBORHOOD_SIZE;oy<=0;oy++)
  50. {
  51. int xlimit=NEIGHBORHOOD_SIZE/2;
  52. if (oy==0)
  53. xlimit=-1; // on last line, don't step past our output pixel
  54. for(int ox=-NEIGHBORHOOD_SIZE/2;ox<=xlimit;ox++)
  55. for(int c=0;c<3;c++)
  56. {
  57. float pix_diff=
  58. output.PixelWrapped(xo+ox,yo+oy,c)-
  59. input.Pixel(nblk_x+ox,nblk_y+oy,c);
  60. our_error+=pix_diff*pix_diff;
  61. float pix_diff0=
  62. output0.PixelWrapped(xo+ox,yo+oy,c)-
  63. input0.PixelClamped(nblk_x+ox,nblk_y+oy,c);
  64. our_error+=pix_diff0*pix_diff0;
  65. }
  66. }
  67. if (our_error < best_error)
  68. {
  69. best_pixel_x=nblk_x;
  70. best_pixel_y=nblk_y;
  71. best_error=our_error;
  72. }
  73. }
  74. for(int c=0;c<3;c++)
  75. output.Pixel(xo,yo,c)=input.Pixel(best_pixel_x,best_pixel_y,c);
  76. }
  77. }
  78. }
  79. output_pyramid.WriteTGAs("synth_out");
  80. }
  81. void main(int argc,char **argv)
  82. {
  83. InitCommandLineProgram( argc, argv );
  84. FloatBitMap_t src_texture(argv[1]);
  85. int out_width = atoi( argv[2] );
  86. int out_height = atoi( argv[3] );
  87. FloatBitMap_t output_map(out_width,out_height);
  88. SynthesizeTexture(output_map,src_texture);
  89. }