MainUnit.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. unit MainUnit;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is Texture Blend Example
  23. *
  24. * The Initial Developer(s) of the Original Code is:
  25. * Michael Hansen <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2010
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. *
  31. * ***** END LICENSE BLOCK ***** *)
  32. interface
  33. {$include GR32.inc}
  34. uses
  35. {$IFNDEF FPC} Windows, {$ELSE} LCLIntf, LResources, LCLType, Buttons, {$ENDIF}
  36. SysUtils, Classes, Graphics, Controls, Forms, Math, StdCtrls, ExtCtrls,
  37. GR32_Image, GR32_RangeBars;
  38. type
  39. TMainForm = class(TForm)
  40. BlendBox: TComboBox;
  41. CombImg: TImage32;
  42. GenerateButton: TButton;
  43. LabelBlendmode: TLabel;
  44. LabelBlendSettings: TLabel;
  45. LabelCombinedTexture: TLabel;
  46. LabelMasterAlpha: TLabel;
  47. LabelTextureA: TLabel;
  48. LabelTextureB: TLabel;
  49. LabelWeightmap: TLabel;
  50. LabelWeightmapSettings: TLabel;
  51. MasterAlphaBar: TGaugeBar;
  52. TexAImg: TImage32;
  53. TexBImg: TImage32;
  54. WeightmapImg: TImage32;
  55. procedure FormCreate(Sender: TObject);
  56. procedure MasterAlphaBarChange(Sender: TObject);
  57. public
  58. procedure GenerateWeightmap(Sender: TObject);
  59. end;
  60. var
  61. MainForm: TMainForm;
  62. implementation
  63. {$R *.dfm}
  64. uses
  65. {$IFDEF Darwin}
  66. MacOSAll,
  67. {$ENDIF}
  68. GR32,
  69. GR32_Resamplers,
  70. GR32_LowLevel,
  71. GR32_Blend,
  72. GR32.ImageFormats.JPG;
  73. var
  74. ColorAlgebraReg: TBlendReg;
  75. function ColorAlgebraEx(F, B: TColor32; M: Cardinal): TColor32;
  76. begin
  77. // Call the coloralgebra routine in action, restore foreground alpha and blend
  78. Result := BlendRegEx(ColorAlgebraReg(F, B) and $FFFFFF or F and $FF000000, B, M);
  79. end;
  80. function SoftMaskedEx(F, B: TColor32; M: Cardinal): TColor32;
  81. var
  82. X: Integer;
  83. begin
  84. // Some sort of masking with MasterAlpha (as threshold) included
  85. X := F shr 24 - (255 - M);
  86. if X > 0 then
  87. Result := F
  88. else
  89. if X = 0 then
  90. Result := ColorAverage(F, B) // Create soft edges
  91. else
  92. Result := B;
  93. end;
  94. { TMainForm }
  95. procedure TMainForm.FormCreate(Sender: TObject);
  96. begin
  97. // Load the textures (note size 256x256 is implicity expected!)
  98. TexAImg.Bitmap.LoadFromResourceName(HInstance, 'TextureA', RT_RCDATA);
  99. TexBImg.Bitmap.LoadFromResourceName(HInstance, 'TextureB', RT_RCDATA);
  100. BlendBox.ItemIndex := 0;
  101. CombImg.Bitmap.SetSizeFrom(TexBImg.Bitmap);
  102. // Set up Weightmap and trigger generate
  103. WeightmapImg.Bitmap.SetSize(256, 256);
  104. GenerateButton.OnClick := GenerateWeightmap;
  105. //we don't want the same series of weightmaps repeat every time the app is run
  106. Randomize;
  107. GenerateWeightmap(Self);
  108. end;
  109. procedure TMainForm.GenerateWeightmap(Sender: TObject);
  110. // Below code is very much based on experimentation, feel free to play around..
  111. var
  112. a, b, c: Single;
  113. function GenerateSomething(x, y : Single): Single;
  114. begin
  115. if a < 0.6 then
  116. Result := Max(Cos(x * PI * a * 2 + b), Sqr(0.1 + c + x*y - y)) *
  117. (Sin(y * b * a) - c + ArcTan2(x + Cos((x - y) * b), y + a))
  118. else
  119. Result := Cos(x * PI * a * 2 + c) * Sin(y * b * a) +
  120. Sin(ArcTan2(x + Cos((x - y) * b), y * c * Sin(x - a)));
  121. end;
  122. const
  123. nS = 1 / 255;
  124. var
  125. I, J: Integer;
  126. W : TColor32;
  127. D, WImg: PColor32;
  128. x, y: Single;
  129. begin
  130. // Setup some random factors:
  131. a := 0.01 + Random;
  132. b := PI * 10 * a * (Random * Random * 2 - 1);
  133. c := Random - Random;
  134. // We use the weightmap as TexB alpha, so we write that on the loop too
  135. D := @TexBImg.Bitmap.Bits[0];
  136. WImg := @WeightmapImg.Bitmap.Bits[0];
  137. for J := 0 to 255 do
  138. for I := 0 to 255 do
  139. begin
  140. x := Cos(I * nS + (PI * a));
  141. y := Sin(J * nS * (PI * c));
  142. W := Round(Constrain(Abs(Min(GenerateSomething(x * c, y),
  143. GenerateSomething(y + c , x * a))) * 200, 0, 255));
  144. if c > 0 then
  145. WImg^ := ColorDifference(WImg^, $FF000000 + W shl 16 + W shl 8 + W)
  146. else
  147. WImg^ := $FF000000 + W shl 16 + W shl 8 + W;
  148. D^ := D^ and $00FFFFFF or W shl 24;
  149. Inc(D);
  150. Inc(WImg);
  151. end;
  152. WeightmapImg.Invalidate;
  153. MasterAlphaBarChange(Self);
  154. end;
  155. procedure TMainForm.MasterAlphaBarChange(Sender: TObject);
  156. var
  157. ABlendRegEx: TBlendRegEx;
  158. begin
  159. // Setup blendmode
  160. case BlendBox.ItemIndex of
  161. 0: ABlendRegEx := BlendRegEx;
  162. 1: ABlendRegEx := SoftMaskedEx;
  163. else
  164. begin
  165. ABlendRegEx := ColorAlgebraEx;
  166. case BlendBox.ItemIndex of
  167. 2: ColorAlgebraReg := ColorAdd;
  168. 3: ColorAlgebraReg := ColorSub;
  169. 4: ColorAlgebraReg := ColorDiv;
  170. 5: ColorAlgebraReg := ColorModulate;
  171. 6: ColorAlgebraReg := ColorMax;
  172. 7: ColorAlgebraReg := ColorMin;
  173. 8: ColorAlgebraReg := ColorDifference;
  174. 9: ColorAlgebraReg := ColorAverage;
  175. 10: ColorAlgebraReg := ColorExclusion;
  176. 11: ColorAlgebraReg := ColorScreen;
  177. 12: ColorAlgebraReg := ColorScreen;
  178. 13: ColorAlgebraReg := ColorDodge;
  179. 14: ColorAlgebraReg := ColorBurn;
  180. end;
  181. end;
  182. end;
  183. // Combine Texture A with B
  184. BlendTransfer(CombImg.Bitmap, 0, 0, CombImg.Bitmap.BoundsRect, TexBImg.Bitmap,
  185. TexBImg.Bitmap.BoundsRect, TexAImg.Bitmap, TexAImg.Bitmap.BoundsRect,
  186. ABlendRegEx, MasterAlphaBar.Position);
  187. // Needed under Mac OS X
  188. CombImg.Invalidate;
  189. end;
  190. end.