fTexCombineD.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. unit fTexCombineD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. System.SysUtils,
  6. System.UITypes,
  7. System.Classes,
  8. System.Actions,
  9. System.ImageList,
  10. Vcl.Graphics,
  11. Vcl.Controls,
  12. Vcl.Forms,
  13. Vcl.Dialogs,
  14. Vcl.ExtCtrls,
  15. Vcl.ExtDlgs,
  16. Vcl.StdCtrls,
  17. Vcl.ComCtrls,
  18. Vcl.ActnList,
  19. Vcl.ToolWin,
  20. Vcl.Menus,
  21. Vcl.ImgList,
  22. Vcl.Imaging.Jpeg,
  23. GLS.Objects,
  24. GLS.HUDObjects,
  25. GLS.Scene,
  26. GLS.SceneViewer,
  27. GLS.FileTGA,
  28. GLS.Coordinates,
  29. GLS.BaseClasses,
  30. GLS.Texture,
  31. GLS.Graphics,
  32. GLScene.VectorGeometry,
  33. GLS.State,
  34. GLScene.Utils;
  35. type
  36. TTTBMain = class(TForm)
  37. MainMenu: TMainMenu;
  38. ImageList: TImageList;
  39. ActionList: TActionList;
  40. File1: TMenuItem;
  41. ACExit: TAction;
  42. Exit1: TMenuItem;
  43. PAImages: TPanel;
  44. PAPreview: TPanel;
  45. Splitter1: TSplitter;
  46. PageControl: TPageControl;
  47. TSRGB: TTabSheet;
  48. TSAlpha: TTabSheet;
  49. GLSceneViewer: TGLSceneViewer;
  50. GLScene: TGLScene;
  51. GLCamera: TGLCamera;
  52. GLDummyCube: TGLDummyCube;
  53. GLCube: TGLCube;
  54. GLLightSource: TGLLightSource;
  55. HSBkgnd: TGLHUDSprite;
  56. ToolBar: TToolBar;
  57. ACImport: TAction;
  58. ACOpenTexture: TAction;
  59. tbImport: TToolButton;
  60. ScrollBox1: TScrollBox;
  61. IMRGB: TImage;
  62. ScrollBox2: TScrollBox;
  63. IMAlpha: TImage;
  64. OpenPictureDialog: TOpenPictureDialog;
  65. Panel1: TPanel;
  66. Label1: TLabel;
  67. CBWidth: TComboBox;
  68. Label2: TLabel;
  69. CBHeight: TComboBox;
  70. N1: TMenuItem;
  71. Exit2: TMenuItem;
  72. ACSaveTexture: TAction;
  73. SaveDialog: TSaveDialog;
  74. SaveTexture1: TMenuItem;
  75. Panel2: TPanel;
  76. CBTextureFiltering: TCheckBox;
  77. CBBackground: TComboBox;
  78. ools1: TMenuItem;
  79. ACColorDilatation: TAction;
  80. Colormapdilatation1: TMenuItem;
  81. ACAlphaErosion: TAction;
  82. Alphamaperosion1: TMenuItem;
  83. ACExport: TAction;
  84. tbExport: TToolButton;
  85. N2: TMenuItem;
  86. ACAlphaDilatation: TAction;
  87. AlphamapDilatation1: TMenuItem;
  88. GenerateAlpha1: TMenuItem;
  89. ACAlphaSuperBlack: TAction;
  90. Alpha1: TMenuItem;
  91. SuperBlackTransparent1: TMenuItem;
  92. ACOpaque: TAction;
  93. ACFromRGBIntensity: TAction;
  94. ACFromRGBSqrtIntensity: TAction;
  95. Opaque1: TMenuItem;
  96. FromRGBIntensity1: TMenuItem;
  97. FromRGBSqrtIntensity1: TMenuItem;
  98. ACAlphaOffset: TAction;
  99. Offset1: TMenuItem;
  100. ACAlphaSaturate: TAction;
  101. Saturate1: TMenuItem;
  102. ACAlphaNegate: TAction;
  103. Negate1: TMenuItem;
  104. N3: TMenuItem;
  105. procedure PAPreviewResize(Sender: TObject);
  106. procedure FormShow(Sender: TObject);
  107. procedure ACImportExecute(Sender: TObject);
  108. procedure CBWidthChange(Sender: TObject);
  109. procedure CBTextureFilteringClick(Sender: TObject);
  110. procedure FormCreate(Sender: TObject);
  111. procedure ACOpenTextureExecute(Sender: TObject);
  112. procedure ACSaveTextureExecute(Sender: TObject);
  113. procedure GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton;
  114. Shift: TShiftState; X, Y: Integer);
  115. procedure GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState;
  116. X, Y: Integer);
  117. procedure CBBackgroundChange(Sender: TObject);
  118. procedure ACColorDilatationExecute(Sender: TObject);
  119. procedure ACAlphaErosionExecute(Sender: TObject);
  120. procedure ACExportExecute(Sender: TObject);
  121. procedure ACAlphaDilatationExecute(Sender: TObject);
  122. procedure ACAlphaSuperBlackExecute(Sender: TObject);
  123. procedure ACOpaqueExecute(Sender: TObject);
  124. procedure ACFromRGBIntensityExecute(Sender: TObject);
  125. procedure ACFromRGBSqrtIntensityExecute(Sender: TObject);
  126. procedure ACAlphaOffsetExecute(Sender: TObject);
  127. procedure ACAlphaSaturateExecute(Sender: TObject);
  128. procedure ACAlphaNegateExecute(Sender: TObject);
  129. private
  130. mx, my: Integer;
  131. AssetPath: TFileName;
  132. procedure ResetAlpha;
  133. procedure GenerateAlpha(transparentColor: TColor; fromIntensity: Boolean;
  134. doSqrt: Boolean);
  135. function SpawnBitmap: TBitmap;
  136. procedure ResizeImage(im: TImage);
  137. procedure NormalizeAlpha;
  138. procedure TextureChanged;
  139. procedure BreakupTexture(bmp: TBitmap);
  140. public
  141. end;
  142. var
  143. TTBMain: TTTBMain;
  144. //===========================================================================
  145. implementation
  146. {$R *.dfm}
  147. procedure TTTBMain.FormCreate(Sender: TObject);
  148. begin
  149. AssetPath := GetCurrentAssetPath();
  150. SetCurrentDir(AssetPath + '\texture');
  151. CBWidth.ItemIndex := 8;
  152. CBHeight.ItemIndex := 8;
  153. CBBackground.ItemIndex := 1;
  154. ResetAlpha;
  155. end;
  156. procedure TTTBMain.FormShow(Sender: TObject);
  157. begin
  158. PAPreviewResize(Self);
  159. CBBackgroundChange(Self);
  160. end;
  161. procedure TTTBMain.PAPreviewResize(Sender: TObject);
  162. const
  163. cTileSize = 32;
  164. var
  165. w, h: Integer;
  166. begin
  167. // adjust background, we could just have made huge one,
  168. // but that would have been too simple for a demo ;)
  169. w := (GLSceneViewer.Width div cTileSize);
  170. h := (GLSceneViewer.Height div cTileSize);
  171. HSBkgnd.XTiles := w;
  172. HSBkgnd.YTiles := h;
  173. w := w * cTileSize + cTileSize;
  174. h := h * cTileSize + cTileSize;
  175. HSBkgnd.Width := w;
  176. HSBkgnd.Height := h;
  177. HSBkgnd.Position.SetPoint(w div 2, h div 2, 0);
  178. // zoom scene with viewer's width
  179. GLCamera.SceneScale := GLSceneViewer.Width / 120;
  180. end;
  181. procedure TTTBMain.ACImportExecute(Sender: TObject);
  182. begin
  183. GLCube.Material.Texture.Disabled := False;
  184. if OpenPictureDialog.Execute then
  185. begin
  186. if PageControl.ActivePage = TSRGB then
  187. begin
  188. IMRGB.Picture.LoadFromFile(OpenPictureDialog.FileName);
  189. ResizeImage(IMRGB);
  190. end
  191. else
  192. begin
  193. IMAlpha.Picture.LoadFromFile(OpenPictureDialog.FileName);
  194. ResizeImage(IMAlpha);
  195. NormalizeAlpha;
  196. end;
  197. TextureChanged;
  198. end;
  199. end;
  200. procedure TTTBMain.ACExportExecute(Sender: TObject);
  201. begin
  202. if SaveDialog.Execute then
  203. begin
  204. if PageControl.ActivePage = TSRGB then
  205. IMRGB.Picture.SaveToFile(SaveDialog.FileName)
  206. else
  207. IMAlpha.Picture.SaveToFile(SaveDialog.FileName);
  208. end;
  209. end;
  210. function TTTBMain.SpawnBitmap: TBitmap;
  211. begin
  212. Result := TBitmap.Create;
  213. Result.PixelFormat := pf32bit;
  214. Result.Width := StrToInt(CBWidth.Text);
  215. Result.Height := StrToInt(CBHeight.Text);
  216. end;
  217. procedure TTTBMain.ResetAlpha;
  218. var
  219. bmp: TBitmap;
  220. begin
  221. // Opaque alpha channel
  222. bmp := SpawnBitmap;
  223. try
  224. with bmp.Canvas do
  225. begin
  226. Brush.Color := clWhite;
  227. FillRect(Rect(0, 0, bmp.Width, bmp.Height));
  228. end;
  229. IMAlpha.Picture.Bitmap := bmp;
  230. finally
  231. bmp.Free;
  232. end;
  233. end;
  234. procedure TTTBMain.GenerateAlpha(transparentColor: TColor;
  235. fromIntensity: Boolean; doSqrt: Boolean);
  236. var
  237. bmp: TBitmap;
  238. bmp32: TGLBitmap32;
  239. X, Y: Integer;
  240. pSrc: PGLPixel32Array;
  241. pDest: PIntegerArray;
  242. c: Integer;
  243. begin
  244. // Opaque alpha channel
  245. bmp := SpawnBitmap;
  246. bmp32 := TGLBitmap32.Create;
  247. GLSceneViewer.Buffer.RenderingContext.Activate;
  248. try
  249. bmp.Canvas.StretchDraw(Rect(0, 0, bmp.Width, bmp.Height),
  250. IMRGB.Picture.Graphic);
  251. bmp32.Assign(bmp);
  252. if transparentColor <> -1 then
  253. bmp32.SetAlphaTransparentForColor(transparentColor);
  254. if fromIntensity then
  255. bmp32.SetAlphaFromIntensity;
  256. if doSqrt then
  257. bmp32.SqrtAlpha;
  258. for Y := 0 to bmp.Height - 1 do
  259. begin
  260. pSrc := bmp32.ScanLine[Y];
  261. pDest := bmp.ScanLine[bmp.Height - 1 - Y];
  262. for X := 0 to bmp.Width - 1 do
  263. begin
  264. c := pSrc[X].a;
  265. c := c + (c shl 8) + (c shl 16);
  266. pDest[X] := c;
  267. end;
  268. end;
  269. IMAlpha.Picture.Graphic := bmp;
  270. finally
  271. bmp32.Free;
  272. bmp.Free;
  273. GLSceneViewer.Buffer.RenderingContext.Deactivate;
  274. end;
  275. TextureChanged;
  276. end;
  277. procedure TTTBMain.NormalizeAlpha;
  278. var
  279. col: Byte;
  280. X, Y, c: Integer;
  281. bmp: TBitmap;
  282. pSrc, pDest: PIntegerArray;
  283. begin
  284. GLSceneViewer.Buffer.RenderingContext.Activate;
  285. bmp := SpawnBitmap;
  286. try
  287. for Y := 0 to bmp.Height - 1 do
  288. begin
  289. pSrc := IMAlpha.Picture.Bitmap.ScanLine[Y];
  290. pDest := bmp.ScanLine[Y];
  291. for X := 0 to bmp.Width - 1 do
  292. begin
  293. c := pSrc[X];
  294. col := Round(0.3 * (c and $FF) + 0.59 * ((c shr 8) and $FF) + 0.11 *
  295. ((c shr 16) and $FF));
  296. pDest[X] := col + (col shl 8) + (col shl 16);
  297. end;
  298. end;
  299. IMAlpha.Picture.Bitmap := bmp;
  300. finally
  301. bmp.Free;
  302. GLSceneViewer.Buffer.RenderingContext.Deactivate;
  303. end;
  304. end;
  305. procedure TTTBMain.ResizeImage(im: TImage);
  306. var
  307. bmp: TBitmap;
  308. begin
  309. if im.Height = 0 then
  310. Exit;
  311. bmp := SpawnBitmap;
  312. try
  313. bmp.Canvas.StretchDraw(Rect(0, 0, bmp.Width, bmp.Height),
  314. im.Picture.Graphic);
  315. im.Picture.Bitmap := bmp;
  316. finally
  317. bmp.Free;
  318. end;
  319. end;
  320. procedure TTTBMain.BreakupTexture(bmp: TBitmap);
  321. var
  322. bmpAlpha, bmpRGB: TBitmap;
  323. Y, X, c: Integer;
  324. pRGB, pAlpha, pSrc: PIntegerArray;
  325. begin
  326. bmpAlpha := SpawnBitmap;
  327. bmpRGB := SpawnBitmap;
  328. try
  329. bmpAlpha.Width := bmp.Width;
  330. bmpAlpha.Height := bmp.Height;
  331. bmpRGB.Width := bmp.Width;
  332. bmpRGB.Height := bmp.Height;
  333. for Y := 0 to bmp.Height - 1 do
  334. begin
  335. pRGB := bmpRGB.ScanLine[Y];
  336. pAlpha := bmpAlpha.ScanLine[Y];
  337. pSrc := bmp.ScanLine[Y];
  338. for X := 0 to bmp.Width - 1 do
  339. begin
  340. c := pSrc[X];
  341. pRGB[X] := (c and $FFFFFF);
  342. c := (c shr 24) and $FF;
  343. pAlpha[X] := c + (c shl 8) + (c shl 16);
  344. end;
  345. end;
  346. IMRGB.Picture.Bitmap := bmpRGB;
  347. IMAlpha.Picture.Bitmap := bmpAlpha;
  348. finally
  349. bmpAlpha.Free;
  350. bmpRGB.Free;
  351. end;
  352. end;
  353. procedure TTTBMain.TextureChanged;
  354. var
  355. bmp: TBitmap;
  356. Y, X: Integer;
  357. pRGB, pAlpha, pDest: PIntegerArray;
  358. begin
  359. if IMRGB.Picture.Graphic.Empty then
  360. Exit;
  361. if IMAlpha.Picture.Height = 0 then
  362. begin
  363. GLCube.Material.Texture.Assign(IMRGB.Picture);
  364. end
  365. else
  366. begin
  367. bmp := SpawnBitmap;
  368. try
  369. for Y := 0 to bmp.Height - 1 do
  370. begin
  371. pRGB := IMRGB.Picture.Bitmap.ScanLine[Y];
  372. pAlpha := IMAlpha.Picture.Bitmap.ScanLine[Y];
  373. pDest := bmp.ScanLine[Y];
  374. for X := 0 to bmp.Width - 1 do
  375. pDest[X] := pRGB[X] or ((pAlpha[X] and $FF) shl 24);
  376. end;
  377. GLCube.Material.Texture.Assign(bmp);
  378. finally
  379. bmp.Free;
  380. end;
  381. end;
  382. end;
  383. procedure TTTBMain.CBWidthChange(Sender: TObject);
  384. begin
  385. ResizeImage(IMRGB);
  386. ResizeImage(IMAlpha);
  387. end;
  388. procedure TTTBMain.CBTextureFilteringClick(Sender: TObject);
  389. begin
  390. with GLCube.Material.Texture do
  391. begin
  392. if CBTextureFiltering.Checked then
  393. begin
  394. MagFilter := maLinear;
  395. MinFilter := miLinearMipmapLinear;
  396. end
  397. else
  398. begin
  399. MagFilter := maNearest;
  400. MinFilter := miNearest;
  401. end;
  402. end;
  403. end;
  404. procedure TTTBMain.ACOpenTextureExecute(Sender: TObject);
  405. var
  406. pic: TPicture;
  407. begin
  408. if OpenPictureDialog.Execute then
  409. begin
  410. pic := TPicture.Create;
  411. try
  412. GLCube.Material.Texture.Disabled := False;
  413. pic.LoadFromFile(OpenPictureDialog.FileName);
  414. if (pic.Graphic is TBitmap) and (pic.Bitmap.PixelFormat = pf32bit) then
  415. begin
  416. BreakupTexture(pic.Bitmap);
  417. ResizeImage(IMAlpha);
  418. end
  419. else
  420. begin
  421. IMRGB.Picture := pic;
  422. ResetAlpha;
  423. end;
  424. ResizeImage(IMRGB);
  425. TextureChanged;
  426. finally
  427. pic.Free;
  428. end;
  429. end;
  430. end;
  431. procedure TTTBMain.ACSaveTextureExecute(Sender: TObject);
  432. var
  433. pic: TPicture;
  434. fName: String;
  435. tga: TTGAImage;
  436. begin
  437. if (pic.Height > 0) and SaveDialog.Execute then
  438. begin
  439. pic := (GLCube.Material.Texture.Image as TGLPictureImage).Picture;
  440. fName := SaveDialog.FileName;
  441. if ExtractFileExt(fName) = '' then
  442. if SaveDialog.FilterIndex = 1 then
  443. fName := fName + '.bmp'
  444. else
  445. fName := fName + '.tga';
  446. if LowerCase(ExtractFileExt(fName)) = '.tga' then
  447. begin
  448. tga := TTGAImage.Create;
  449. try
  450. tga.Assign(pic.Bitmap);
  451. tga.SaveToFile(fName)
  452. finally
  453. tga.Free;
  454. end;
  455. end
  456. else
  457. pic.SaveToFile(fName);
  458. end;
  459. end;
  460. procedure TTTBMain.GLSceneViewerMouseDown(Sender: TObject; Button: TMouseButton;
  461. Shift: TShiftState; X, Y: Integer);
  462. begin
  463. mx := X;
  464. my := Y;
  465. end;
  466. procedure TTTBMain.GLSceneViewerMouseMove(Sender: TObject; Shift: TShiftState;
  467. X, Y: Integer);
  468. begin
  469. if Shift = [ssLeft] then
  470. begin
  471. GLCamera.MoveAroundTarget(my - Y, mx - X);
  472. mx := X;
  473. my := Y;
  474. end;
  475. end;
  476. procedure TTTBMain.CBBackgroundChange(Sender: TObject);
  477. begin
  478. HSBkgnd.Visible := (CBBackground.ItemIndex = 0);
  479. case CBBackground.ItemIndex of
  480. 1:
  481. GLSceneViewer.Buffer.BackgroundColor := clBlack;
  482. 2:
  483. GLSceneViewer.Buffer.BackgroundColor := clSilver;
  484. 3:
  485. GLSceneViewer.Buffer.BackgroundColor := clWhite;
  486. end;
  487. end;
  488. procedure TTTBMain.ACColorDilatationExecute(Sender: TObject);
  489. var
  490. X, Y, sx, sy: Integer;
  491. bmRGB, bmAlpha: TBitmap;
  492. r, g, b: Single;
  493. weightSum, iw: Single;
  494. procedure WeightIn(X, Y: Integer; wBase: Single);
  495. var
  496. w: Single;
  497. rgb, alpha: Integer;
  498. begin
  499. if (Cardinal(X) < Cardinal(sx)) and (Cardinal(Y) < Cardinal(sy)) then
  500. begin
  501. alpha := bmAlpha.Canvas.Pixels[X, Y];
  502. if alpha > 0 then
  503. begin
  504. w := ((alpha shr 8) and $FF) * (1 / 255) * wBase;
  505. weightSum := weightSum + w;
  506. rgb := bmRGB.Canvas.Pixels[X, Y];
  507. r := r + GetRValue(rgb) * w;
  508. g := g + GetGValue(rgb) * w;
  509. b := b + GetBValue(rgb) * w;
  510. end;
  511. end;
  512. end;
  513. begin
  514. Screen.Cursor := crHourGlass;
  515. // for all pixels in the color map that are fully transparent,
  516. // change their color to the average of the weighted average of their
  517. // opaque neighbours
  518. bmRGB := IMRGB.Picture.Bitmap;
  519. bmAlpha := IMAlpha.Picture.Bitmap;
  520. sx := StrToInt(CBWidth.Text);
  521. sy := StrToInt(CBHeight.Text);
  522. for Y := 0 to sy - 1 do
  523. begin
  524. for X := 0 to sx - 1 do
  525. begin
  526. // if pixel fully opaque
  527. if bmAlpha.Canvas.Pixels[X, Y] = 0 then
  528. begin
  529. // weight-in all neighbours
  530. r := 0;
  531. g := 0;
  532. b := 0;
  533. weightSum := 0;
  534. WeightIn(X - 1, Y - 1, 0.7);
  535. WeightIn(X, Y - 1, 1.0);
  536. WeightIn(X + 1, Y - 1, 0.7);
  537. WeightIn(X - 1, Y, 1.0);
  538. WeightIn(X, Y, 4.0);
  539. WeightIn(X + 1, Y, 1.0);
  540. WeightIn(X - 1, Y + 1, 0.7);
  541. WeightIn(X, Y + 1, 1.0);
  542. WeightIn(X + 1, Y + 1, 0.7);
  543. if weightSum > 0 then
  544. begin
  545. iw := 1 / weightSum;
  546. bmRGB.Canvas.Pixels[X, Y] := rgb(Round(r * iw), Round(g * iw),
  547. Round(b * iw));
  548. end;
  549. end;
  550. end;
  551. end;
  552. TextureChanged;
  553. Screen.Cursor := crDefault;
  554. end;
  555. procedure TTTBMain.ACAlphaErosionExecute(Sender: TObject);
  556. var
  557. X, Y, sx, sy: Integer;
  558. bmp, bmAlpha: TBitmap;
  559. minNeighbour: Integer;
  560. begin
  561. // make fully transparent all pixels in the color for all pixels in the alpha map
  562. // that are adjacent to a fully transparent one
  563. bmAlpha := IMAlpha.Picture.Bitmap;
  564. sx := StrToInt(CBWidth.Text);
  565. sy := StrToInt(CBHeight.Text);
  566. bmp := SpawnBitmap;
  567. for Y := 0 to sy - 1 do
  568. begin
  569. for X := 0 to sx - 1 do
  570. with bmAlpha.Canvas do
  571. begin
  572. if Pixels[X, Y] > 0 then
  573. begin
  574. minNeighbour := MinInteger(MinInteger(Pixels[X, Y - 1],
  575. Pixels[X, Y + 1]), MinInteger(Pixels[X - 1, Y], Pixels[X + 1, Y]));
  576. bmp.Canvas.Pixels[X, Y] := MinInteger(minNeighbour, Pixels[X, Y]);
  577. end
  578. else
  579. bmp.Canvas.Pixels[X, Y] := 0;
  580. end;
  581. end;
  582. IMAlpha.Picture.Bitmap := bmp;
  583. bmp.Free;
  584. TextureChanged;
  585. end;
  586. procedure TTTBMain.ACAlphaDilatationExecute(Sender: TObject);
  587. var
  588. X, Y, sx, sy: Integer;
  589. bmp, bmAlpha: TBitmap;
  590. maxNeighbour: Integer;
  591. begin
  592. // make fully transparent all pixels in the color for all pixels in the alpha map
  593. // that are adjacent to a fully transparent one
  594. bmAlpha := IMAlpha.Picture.Bitmap;
  595. sx := StrToInt(CBWidth.Text);
  596. sy := StrToInt(CBHeight.Text);
  597. bmp := SpawnBitmap;
  598. for Y := 0 to sy - 1 do
  599. begin
  600. for X := 0 to sx - 1 do
  601. with bmAlpha.Canvas do
  602. begin
  603. if Pixels[X, Y] < clWhite then
  604. begin
  605. maxNeighbour := MaxInteger(MaxInteger(Pixels[X, Y - 1],
  606. Pixels[X, Y + 1]), MaxInteger(Pixels[X - 1, Y], Pixels[X + 1, Y]));
  607. bmp.Canvas.Pixels[X, Y] := MaxInteger(maxNeighbour, Pixels[X, Y]);
  608. end
  609. else
  610. bmp.Canvas.Pixels[X, Y] := clWhite;
  611. end;
  612. end;
  613. IMAlpha.Picture.Bitmap := bmp;
  614. bmp.Free;
  615. TextureChanged;
  616. end;
  617. procedure TTTBMain.ACOpaqueExecute(Sender: TObject);
  618. begin
  619. ResetAlpha;
  620. end;
  621. procedure TTTBMain.ACAlphaSuperBlackExecute(Sender: TObject);
  622. begin
  623. GenerateAlpha(clBlack, False, False);
  624. end;
  625. procedure TTTBMain.ACFromRGBIntensityExecute(Sender: TObject);
  626. begin
  627. GenerateAlpha(-1, True, False);
  628. end;
  629. procedure TTTBMain.ACFromRGBSqrtIntensityExecute(Sender: TObject);
  630. begin
  631. GenerateAlpha(-1, True, True);
  632. end;
  633. procedure TTTBMain.ACAlphaOffsetExecute(Sender: TObject);
  634. var
  635. X, Y, c, offset: Integer;
  636. bmp: TBitmap;
  637. pSrc, pDest: PIntegerArray;
  638. offsetStr: String;
  639. begin
  640. offsetStr := '0';
  641. if not InputQuery('Alpha Offset', 'Enter Offset Value (-255..255)', offsetStr)
  642. then
  643. Exit;
  644. offset := StrToIntDef(offsetStr, MaxInt);
  645. if (offset < -255) or (offset > 255) then
  646. begin
  647. ShowMessage('Invalid Alpha Offset');
  648. Exit;
  649. end;
  650. bmp := SpawnBitmap;
  651. try
  652. for Y := 0 to bmp.Height - 1 do
  653. begin
  654. pSrc := IMAlpha.Picture.Bitmap.ScanLine[Y];
  655. pDest := bmp.ScanLine[Y];
  656. for X := 0 to bmp.Width - 1 do
  657. begin
  658. c := pSrc[X] and $FF;
  659. c := c + offset;
  660. if c <= 0 then
  661. pDest[X] := 0
  662. else if c >= 255 then
  663. pDest[X] := $FFFFFF
  664. else
  665. pDest[X] := c + (c shl 8) + (c shl 16);
  666. end;
  667. end;
  668. IMAlpha.Picture.Bitmap := bmp;
  669. finally
  670. bmp.Free;
  671. end;
  672. TextureChanged;
  673. end;
  674. procedure TTTBMain.ACAlphaSaturateExecute(Sender: TObject);
  675. var
  676. X, Y: Integer;
  677. bmp: TBitmap;
  678. pSrc, pDest: PIntegerArray;
  679. begin
  680. bmp := SpawnBitmap;
  681. try
  682. for Y := 0 to bmp.Height - 1 do
  683. begin
  684. pSrc := IMAlpha.Picture.Bitmap.ScanLine[Y];
  685. pDest := bmp.ScanLine[Y];
  686. for X := 0 to bmp.Width - 1 do
  687. begin
  688. if (pSrc[X] and $FF) > 0 then
  689. pDest[X] := $FFFFFF
  690. else
  691. pDest[X] := 0;
  692. end;
  693. end;
  694. IMAlpha.Picture.Bitmap := bmp;
  695. finally
  696. bmp.Free;
  697. end;
  698. TextureChanged;
  699. end;
  700. procedure TTTBMain.ACAlphaNegateExecute(Sender: TObject);
  701. var
  702. X, Y, c: Integer;
  703. bmp: TBitmap;
  704. pSrc, pDest: PIntegerArray;
  705. begin
  706. bmp := SpawnBitmap;
  707. try
  708. for Y := 0 to bmp.Height - 1 do
  709. begin
  710. pSrc := IMAlpha.Picture.Bitmap.ScanLine[Y];
  711. pDest := bmp.ScanLine[Y];
  712. for X := 0 to bmp.Width - 1 do
  713. begin
  714. c := $FF - (pSrc[X] and $FF);
  715. pDest[X] := c + (c shl 8) + (c shl 16);
  716. end;
  717. end;
  718. IMAlpha.Picture.Bitmap := bmp;
  719. finally
  720. bmp.Free;
  721. end;
  722. TextureChanged;
  723. end;
  724. end.