MainUnit.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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. * Christian-W. Budde <[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. {$IFDEF FPC}LCLIntf, LResources, Buttons, {$ENDIF}
  36. SysUtils, Classes, Graphics, Controls, Forms, Math, StdCtrls, ExtCtrls,
  37. GR32, GR32_Blend, GR32_Image;
  38. type
  39. TMainForm = class(TForm)
  40. CheckBoxBackground: TCheckBox;
  41. CheckBoxForeground: TCheckBox;
  42. CheckBoxTransparent: TCheckBox;
  43. DstImg: TImage32;
  44. LabelBlendHint: TLabel;
  45. LabelBlendSettings: TLabel;
  46. LabelMergeHint: TLabel;
  47. LabelOverlay: TLabel;
  48. LabelVisible: TLabel;
  49. RadioButtonBlend: TRadioButton;
  50. RadioButtonMerge: TRadioButton;
  51. procedure FormCreate(Sender: TObject);
  52. procedure CheckBoxImageClick(Sender: TObject);
  53. procedure DstImgPaintStage(Sender: TObject; Buffer: TBitmap32;
  54. StageNum: Cardinal);
  55. procedure RadioButtonBlendClick(Sender: TObject);
  56. procedure RadioButtonMergeClick(Sender: TObject);
  57. procedure RadioButtonNoneClick(Sender: TObject);
  58. private
  59. FForeground: TBitmap32;
  60. FBackground: TBitmap32;
  61. FBackgroundOpaque: TBitmap32;
  62. FBlendFunc: TBlendReg;
  63. procedure ModifyAlphaValues;
  64. procedure UpdateBlendModeEnabled;
  65. procedure DrawBitmap;
  66. end;
  67. var
  68. MainForm: TMainForm;
  69. implementation
  70. {$R *.dfm}
  71. uses
  72. {$IFDEF Darwin}
  73. MacOSAll,
  74. {$ENDIF}
  75. GR32.ImageFormats.JPG,
  76. GR32_Resamplers,
  77. GR32_LowLevel;
  78. { TMainForm }
  79. procedure TMainForm.FormCreate(Sender: TObject);
  80. begin
  81. // setup custom checker board paint stage
  82. with DstImg do
  83. begin
  84. with PaintStages[0]^ do //Set up custom paintstage to draw checkerboard
  85. begin
  86. Stage := PST_CUSTOM;
  87. Parameter := 1; // use parameter to tag the stage, we inspect this in OnPaintStage
  88. end;
  89. end;
  90. // Load the textures (note size 256x256 is implicity expected!)
  91. FForeground := TBitmap32.Create;
  92. FForeground.LoadFromResourceName(HInstance, 'TextureA', 'JPG');
  93. FBackground := TBitmap32.Create;
  94. FBackground.LoadFromResourceName(HInstance, 'TextureB', 'JPG');
  95. // clone background (= store original background without transparency)
  96. FBackgroundOpaque := TBitmap32.Create;
  97. FBackgroundOpaque.Assign(FBackground);
  98. // apply transparency to both background and foreground
  99. ModifyAlphaValues;
  100. DstImg.Bitmap.SetSize(FForeground.Width, FForeground.Height);
  101. FBlendFunc := MergeReg;
  102. DrawBitmap;
  103. end;
  104. procedure TMainForm.ModifyAlphaValues;
  105. var
  106. X, Y: Integer;
  107. Line: PColor32EntryArray;
  108. begin
  109. // apply a linear alpha gradient from left (transparent) to right (opaque)
  110. for Y := 0 to FForeground.Height - 1 do
  111. begin
  112. Line := PColor32EntryArray(FForeground.ScanLine[Y]);
  113. for X := 0 to FForeground.Width - 1 do
  114. Line^[X].A := X;
  115. end;
  116. // apply a linear alpha gradient from top (transparent) to bottom (opaque)
  117. for Y := 0 to FBackground.Height - 1 do
  118. begin
  119. Line := PColor32EntryArray(FBackground.ScanLine[Y]);
  120. for X := 0 to FBackground.Width - 1 do
  121. Line^[X].A := Y;
  122. end;
  123. end;
  124. procedure TMainForm.DstImgPaintStage(Sender: TObject; Buffer: TBitmap32;
  125. StageNum: Cardinal);
  126. const
  127. Colors: array [Boolean] of TColor32 = ($FFFFFFFF, $FFB0B0B0);
  128. var
  129. R: TRect;
  130. I, J: Integer;
  131. OddY: Integer;
  132. TilesHorz, TilesVert: Integer;
  133. TileX, TileY: Integer;
  134. TileHeight, TileWidth: Integer;
  135. begin
  136. // draw checker board
  137. with TImgView32(Sender) do
  138. begin
  139. BeginUpdate;
  140. R := GetViewportRect;
  141. TileHeight := 8;
  142. TileWidth := 8;
  143. TilesHorz := (R.Right - R.Left) div TileWidth;
  144. TilesVert := (R.Bottom - R.Top) div TileHeight;
  145. TileY := 0;
  146. for J := 0 to TilesVert do
  147. begin
  148. TileX := 0;
  149. OddY := J and $1;
  150. for I := 0 to TilesHorz do
  151. begin
  152. Buffer.FillRectS(TileX, TileY, TileX + TileWidth, TileY +
  153. TileHeight, Colors[I and $1 = OddY]);
  154. Inc(TileX, TileWidth);
  155. end;
  156. Inc(TileY, TileHeight);
  157. end;
  158. EndUpdate;
  159. end;
  160. end;
  161. procedure TMainForm.RadioButtonNoneClick(Sender: TObject);
  162. begin
  163. DstImg.Bitmap.Clear(0);
  164. // Needed under Mac OS X
  165. DstImg.Invalidate;
  166. end;
  167. procedure TMainForm.RadioButtonBlendClick(Sender: TObject);
  168. begin
  169. FBlendFunc := BlendReg;
  170. DrawBitmap;
  171. end;
  172. procedure TMainForm.RadioButtonMergeClick(Sender: TObject);
  173. begin
  174. FBlendFunc := MergeReg;
  175. DrawBitmap;
  176. end;
  177. procedure TMainForm.CheckBoxImageClick(Sender: TObject);
  178. begin
  179. DrawBitmap;
  180. UpdateBlendModeEnabled;
  181. end;
  182. procedure TMainForm.UpdateBlendModeEnabled;
  183. var
  184. Value: Boolean;
  185. begin
  186. Value := CheckBoxForeground.Checked and CheckBoxBackground.Checked;
  187. RadioButtonBlend.Enabled := Value;
  188. RadioButtonMerge.Enabled := Value;
  189. end;
  190. procedure TMainForm.DrawBitmap;
  191. var
  192. X, Y: Integer;
  193. PSrcF, PSrcB, PDst: PColor32Array;
  194. Background: TBitmap32;
  195. begin
  196. // select whether the opaque or transparent image shall be used
  197. if CheckBoxTransparent.Checked then
  198. Background := FBackground
  199. else
  200. Background := FBackgroundOpaque;
  201. if CheckBoxForeground.Checked then
  202. begin
  203. if CheckBoxBackground.Checked then
  204. for Y := 0 to FForeground.Height - 1 do
  205. begin
  206. // blend lines according to the blend function (blend or merge)
  207. PSrcF := PColor32Array(FForeground.ScanLine[Y]);
  208. PSrcB := PColor32Array(Background.ScanLine[Y]);
  209. PDst := PColor32Array(DstImg.Bitmap.ScanLine[Y]);
  210. for X := 0 to FForeground.Width - 1 do
  211. PDst[X] := FBlendFunc(PSrcF[X], PSrcB[X]);
  212. end
  213. else
  214. for Y := 0 to FForeground.Height - 1 do
  215. begin
  216. // copy lines from the foreground image
  217. PSrcF := PColor32Array(FForeground.ScanLine[Y]);
  218. PDst := PColor32Array(DstImg.Bitmap.ScanLine[Y]);
  219. MoveLongword(PSrcF^, PDst^, FForeground.Width);
  220. end
  221. end
  222. else
  223. begin
  224. if CheckBoxBackground.Checked then
  225. for Y := 0 to FForeground.Height - 1 do
  226. begin
  227. // copy lines from the background image
  228. PSrcB := PColor32Array(Background.ScanLine[Y]);
  229. PDst := PColor32Array(DstImg.Bitmap.ScanLine[Y]);
  230. MoveLongword(PSrcB^, PDst^, FForeground.Width);
  231. end
  232. else
  233. DstImg.Bitmap.Clear(0);
  234. end;
  235. // Needed under Mac OS X
  236. DstImg.Invalidate;
  237. end;
  238. end.