MainUnit.pas 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. {$I GR32.inc}
  34. uses
  35. {$IFNDEF FPC} Windows, {$ELSE} LCLIntf, LResources, 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. A, B, C: Single;
  63. implementation
  64. {$IFDEF FPC}
  65. {$R *.lfm}
  66. {$ELSE}
  67. {$R *.dfm}
  68. {$ENDIF}
  69. uses
  70. {$IFDEF Darwin}
  71. MacOSAll,
  72. {$ENDIF}
  73. {$IFNDEF FPC}
  74. JPEG,
  75. {$ELSE}
  76. LazJPG,
  77. {$ENDIF}
  78. GR32, GR32_Resamplers, GR32_LowLevel, GR32_Blend;
  79. var
  80. ColorAlgebraReg: TBlendReg;
  81. function ColorAlgebraEx(F, B, M: TColor32): TColor32;
  82. begin
  83. // Call the coloralgebra routine in action, restore foreground alpha and blend
  84. Result := BlendRegEx(ColorAlgebraReg(F, B) and $FFFFFF or F and
  85. $FF000000, B, M);
  86. end;
  87. function SoftMaskedEx(F, B, M: TColor32): TColor32;
  88. var
  89. X: Integer;
  90. begin
  91. // Some sort of masking with MasterAlpha (as threshold) included
  92. X := F shr 24 - (255 - M);
  93. if X > 0 then
  94. Result := F
  95. else if X = 0 then
  96. Result := ColorAverage(F, B) // Create soft edges
  97. else
  98. Result := B;
  99. end;
  100. { TMainForm }
  101. procedure TMainForm.FormCreate(Sender: TObject);
  102. var
  103. ResStream: TResourceStream;
  104. JPEG: TJPEGImage;
  105. begin
  106. // Load the textures (note size 256x256 is implicity expected!)
  107. JPEG := TJPEGImage.Create;
  108. try
  109. ResStream := TResourceStream.Create(HInstance, 'TextureA', RT_RCDATA);
  110. try
  111. JPEG.LoadFromStream(ResStream);
  112. finally
  113. ResStream.Free;
  114. end;
  115. TexAImg.Bitmap.Assign(JPEG);
  116. ResStream := TResourceStream.Create(HInstance, 'TextureB', RT_RCDATA);
  117. try
  118. JPEG.LoadFromStream(ResStream);
  119. finally
  120. ResStream.Free;
  121. end;
  122. TexBImg.Bitmap.Assign(JPEG);
  123. finally
  124. JPEG.Free;
  125. end;
  126. BlendBox.ItemIndex := 0;
  127. CombImg.Bitmap.SetSizeFrom(TexBImg.Bitmap);
  128. // Set up Weightmap and trigger generate
  129. WeightmapImg.Bitmap.SetSize(256, 256);
  130. GenerateButton.OnClick := GenerateWeightmap;
  131. // we don't want the same series of weightmaps repeat every time the app is run
  132. Randomize;
  133. GenerateWeightmap(Self);
  134. end;
  135. function GenerateSomething(X, Y: Single): Single;
  136. begin
  137. if A < 0.6 then
  138. Result := Max(Cos(X * PI * A * 2 + B), Sqr(0.1 + C + X * Y - Y)) *
  139. (Sin(Y * B * A) - C + ArcTan2(X + Cos((X - Y) * B), Y + A))
  140. else
  141. Result := Cos(X * PI * A * 2 + C) * Sin(Y * B * A) +
  142. Sin(ArcTan2(X + Cos((X - Y) * B), Y * c * Sin(X - A)));
  143. end;
  144. procedure TMainForm.GenerateWeightmap(Sender: TObject);
  145. // Below code is very much based on experimentation, feel free to play around..
  146. const
  147. nS = 1 / 255;
  148. var
  149. I, J: Integer;
  150. W: TColor32;
  151. D, WImg: PColor32;
  152. X, y: Single;
  153. begin
  154. // Setup some random factors:
  155. a := 0.01 + Random;
  156. B := PI * 10 * a * (Random * Random * 2 - 1);
  157. c := Random - Random;
  158. // We use the weightmap as TexB alpha, so we write that on the loop too
  159. D := @TexBImg.Bitmap.Bits[0];
  160. WImg := @WeightmapImg.Bitmap.Bits[0];
  161. for J := 0 to 255 do
  162. for I := 0 to 255 do
  163. begin
  164. X := Cos(I * nS + (PI * a));
  165. y := Sin(J * nS * (PI * c));
  166. W := Round(Constrain(Abs(Min(GenerateSomething(X * c, y),
  167. GenerateSomething(y + c, X * a))) * 200, 0, 255));
  168. if c > 0 then
  169. WImg^ := ColorDifference(WImg^, $FF000000 + W shl 16 + W shl 8 + W)
  170. else
  171. WImg^ := $FF000000 + W shl 16 + W shl 8 + W;
  172. EMMS;
  173. D^ := D^ and $00FFFFFF or W shl 24;
  174. Inc(D);
  175. Inc(WImg);
  176. end;
  177. WeightmapImg.Invalidate;
  178. MasterAlphaBarChange(Self);
  179. end;
  180. procedure TMainForm.MasterAlphaBarChange(Sender: TObject);
  181. var
  182. ABlendRegEx: TBlendRegEx;
  183. begin
  184. // Setup blendmode
  185. case BlendBox.ItemIndex of
  186. 0:
  187. ABlendRegEx := BlendRegEx;
  188. 1:
  189. ABlendRegEx := SoftMaskedEx;
  190. else
  191. begin
  192. ABlendRegEx := ColorAlgebraEx;
  193. case BlendBox.ItemIndex of
  194. 2:
  195. ColorAlgebraReg := ColorAdd;
  196. 3:
  197. ColorAlgebraReg := ColorSub;
  198. 4:
  199. ColorAlgebraReg := ColorDiv;
  200. 5:
  201. ColorAlgebraReg := ColorModulate;
  202. 6:
  203. ColorAlgebraReg := ColorMax;
  204. 7:
  205. ColorAlgebraReg := ColorMin;
  206. 8:
  207. ColorAlgebraReg := ColorDifference;
  208. 9:
  209. ColorAlgebraReg := ColorAverage;
  210. 10:
  211. ColorAlgebraReg := ColorExclusion;
  212. 11:
  213. ColorAlgebraReg := ColorScreen;
  214. 12:
  215. ColorAlgebraReg := ColorScreen;
  216. 13:
  217. ColorAlgebraReg := ColorDodge;
  218. 14:
  219. ColorAlgebraReg := ColorBurn;
  220. end;
  221. end;
  222. end;
  223. // Combine Texture A with B
  224. BlendTransfer(CombImg.Bitmap, 0, 0, CombImg.Bitmap.BoundsRect, TexBImg.Bitmap,
  225. TexBImg.Bitmap.BoundsRect, TexAImg.Bitmap, TexAImg.Bitmap.BoundsRect,
  226. ABlendRegEx, MasterAlphaBar.Position);
  227. // This is needed because we may use MMX in the custom pixelcombiners
  228. EMMS;
  229. // Needed under Mac OS X
  230. CombImg.Invalidate;
  231. end;
  232. end.