fMainD.pas 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. unit fMainD;
  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. {$I 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. {$IFDEF FPC}
  71. {$R *.lfm}
  72. {$ELSE}
  73. {$R *.dfm}
  74. {$ENDIF}
  75. uses
  76. {$IFDEF Darwin}
  77. MacOSAll,
  78. {$ENDIF}
  79. {$IFNDEF FPC}
  80. JPEG,
  81. {$ELSE}
  82. LazJPG,
  83. {$ENDIF}
  84. GR32_Resamplers, GR32_LowLevel;
  85. // TMainForm
  86. procedure TMainForm.FormCreate(Sender: TObject);
  87. var
  88. ResStream: TResourceStream;
  89. JPEG: TJPEGImage;
  90. begin
  91. // setup custom checker board paint stage
  92. // Set up custom paintstage to draw checkerboard
  93. DstImg.PaintStages[0]^.Stage := PST_CUSTOM;
  94. DstImg.PaintStages[0]^.Parameter := 1; // use parameter to tag the stage, we inspect this in OnPaintStage
  95. // Load the textures (note size 256x256 is implicity expected!)
  96. JPEG := TJPEGImage.Create;
  97. try
  98. ResStream := TResourceStream.Create(HInstance, 'TextureA', 'JPG');
  99. try
  100. JPEG.LoadFromStream(ResStream);
  101. finally
  102. ResStream.Free;
  103. end;
  104. FForeground := TBitmap32.Create;
  105. FForeground.Assign(JPEG);
  106. ResStream := TResourceStream.Create(HInstance, 'TextureB', 'JPG');
  107. try
  108. JPEG.LoadFromStream(ResStream);
  109. finally
  110. ResStream.Free;
  111. end;
  112. FBackground := TBitmap32.Create;
  113. FBackground.Assign(JPEG);
  114. finally
  115. JPEG.Free;
  116. end;
  117. // clone background (= store original background without transparency)
  118. FBackgroundOpaque := TBitmap32.Create;
  119. FBackgroundOpaque.Assign(FBackground);
  120. // apply transparency to both background and foreground
  121. ModifyAlphaValues;
  122. DstImg.Bitmap.SetSize(FForeground.Width, FForeground.Height);
  123. FBlendFunc := MergeReg;
  124. DrawBitmap;
  125. end;
  126. procedure TMainForm.ModifyAlphaValues;
  127. var
  128. X, Y: Integer;
  129. Line: PColor32EntryArray;
  130. begin
  131. // apply a linear alpha gradient from left (transparent) to right (opaque)
  132. for Y := 0 to FForeground.Height - 1 do
  133. begin
  134. Line := PColor32EntryArray(FForeground.ScanLine[Y]);
  135. for X := 0 to FForeground.Width - 1 do
  136. Line^[X].A := X;
  137. end;
  138. // apply a linear alpha gradient from top (transparent) to bottom (opaque)
  139. for Y := 0 to FBackground.Height - 1 do
  140. begin
  141. Line := PColor32EntryArray(FBackground.ScanLine[Y]);
  142. for X := 0 to FBackground.Width - 1 do
  143. Line^[X].A := Y;
  144. end;
  145. end;
  146. procedure TMainForm.DstImgPaintStage(Sender: TObject; Buffer: TBitmap32;
  147. StageNum: Cardinal);
  148. const
  149. Colors: array [Boolean] of TColor32 = ($FFFFFFFF, $FFB0B0B0);
  150. var
  151. R: TRect;
  152. I, J: Integer;
  153. OddY: Integer;
  154. TilesHorz, TilesVert: Integer;
  155. TileX, TileY: Integer;
  156. TileHeight, TileWidth: Integer;
  157. begin
  158. // draw checker board
  159. TImgView32(Sender).BeginUpdate;
  160. R := TImgView32(Sender).GetViewportRect;
  161. TileHeight := 8;
  162. TileWidth := 8;
  163. TilesHorz := (R.Right - R.Left) div TileWidth;
  164. TilesVert := (R.Bottom - R.Top) div TileHeight;
  165. TileY := 0;
  166. for J := 0 to TilesVert do
  167. begin
  168. TileX := 0;
  169. OddY := J and $1;
  170. for I := 0 to TilesHorz do
  171. begin
  172. Buffer.FillRectS(TileX, TileY, TileX + TileWidth, TileY +
  173. TileHeight, Colors[I and $1 = OddY]);
  174. Inc(TileX, TileWidth);
  175. end;
  176. Inc(TileY, TileHeight);
  177. end;
  178. TImgView32(Sender).EndUpdate;
  179. end;
  180. procedure TMainForm.RadioButtonNoneClick(Sender: TObject);
  181. begin
  182. DstImg.Bitmap.Clear(0);
  183. // Needed under Mac OS X
  184. DstImg.Invalidate;
  185. end;
  186. procedure TMainForm.RadioButtonBlendClick(Sender: TObject);
  187. begin
  188. FBlendFunc := BlendReg;
  189. DrawBitmap;
  190. end;
  191. procedure TMainForm.RadioButtonMergeClick(Sender: TObject);
  192. begin
  193. FBlendFunc := MergeReg;
  194. DrawBitmap;
  195. end;
  196. procedure TMainForm.CheckBoxImageClick(Sender: TObject);
  197. begin
  198. DrawBitmap;
  199. UpdateBlendModeEnabled;
  200. end;
  201. procedure TMainForm.UpdateBlendModeEnabled;
  202. var
  203. Value: Boolean;
  204. begin
  205. Value := CheckBoxForeground.Checked and CheckBoxBackground.Checked;
  206. RadioButtonBlend.Enabled := Value;
  207. RadioButtonMerge.Enabled := Value;
  208. end;
  209. procedure TMainForm.DrawBitmap;
  210. var
  211. X, Y: Integer;
  212. PSrcF, PSrcB, PDst: PColor32Array;
  213. Background: TBitmap32;
  214. begin
  215. // select whether the opaque or transparent image shall be used
  216. if CheckBoxTransparent.Checked then
  217. Background := FBackground
  218. else
  219. Background := FBackgroundOpaque;
  220. if CheckBoxForeground.Checked then
  221. begin
  222. if CheckBoxBackground.Checked then
  223. for Y := 0 to FForeground.Height - 1 do
  224. begin
  225. // blend lines according to the blend function (blend or merge)
  226. PSrcF := PColor32Array(FForeground.ScanLine[Y]);
  227. PSrcB := PColor32Array(Background.ScanLine[Y]);
  228. PDst := PColor32Array(DstImg.Bitmap.ScanLine[Y]);
  229. for X := 0 to FForeground.Width - 1 do
  230. PDst[X] := FBlendFunc(PSrcF[X], PSrcB[X]);
  231. end
  232. else
  233. for Y := 0 to FForeground.Height - 1 do
  234. begin
  235. // copy lines from the foreground image
  236. PSrcF := PColor32Array(FForeground.ScanLine[Y]);
  237. PDst := PColor32Array(DstImg.Bitmap.ScanLine[Y]);
  238. MoveLongword(PSrcF^, PDst^, FForeground.Width);
  239. end
  240. end
  241. else
  242. begin
  243. if CheckBoxBackground.Checked then
  244. for Y := 0 to FForeground.Height - 1 do
  245. begin
  246. // copy lines from the background image
  247. PSrcB := PColor32Array(Background.ScanLine[Y]);
  248. PDst := PColor32Array(DstImg.Bitmap.ScanLine[Y]);
  249. MoveLongword(PSrcB^, PDst^, FForeground.Width);
  250. end
  251. else
  252. DstImg.Bitmap.Clear(0);
  253. end;
  254. //This is needed because we may use MMX
  255. EMMS;
  256. // Needed under Mac OS X
  257. DstImg.Invalidate;
  258. end;
  259. end.