MainFm.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:8k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit MainFm;
  2. //---------------------------------------------------------------------------
  3. // Asphyre example application                          Modified: 21-Feb-2007
  4. // Copyright (c) 2000 - 2007  Afterwarp Interactive
  5. //---------------------------------------------------------------------------
  6. // This demo illustrates how to render isometric terrain with variable
  7. // height using Asphyre.
  8. //---------------------------------------------------------------------------
  9. // The contents of this file are subject to the Mozilla Public License
  10. // Version 1.1 (the "License"); you may not use this file except in
  11. // compliance with the License. You may obtain a copy of the License at
  12. // http://www.mozilla.org/MPL/
  13. //
  14. // Software distributed under the License is distributed on an "AS IS"
  15. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  16. // License for the specific language governing rights and limitations
  17. // under the License.
  18. //---------------------------------------------------------------------------
  19. interface
  20. //---------------------------------------------------------------------------
  21. uses
  22.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  23.   Dialogs, ComCtrls, AsphyreDevices, AsphyrePalettes, AsphyreTypes;
  24. //---------------------------------------------------------------------------
  25. type
  26.   TMainForm = class(TForm)
  27.     StatusBar1: TStatusBar;
  28.     procedure FormResize(Sender: TObject);
  29.     procedure FormCreate(Sender: TObject);
  30.     procedure FormDestroy(Sender: TObject);
  31.   private
  32.     { Private declarations }
  33.     SinTab, CosTab: array[0..1023] of Word;
  34.     PaletteTab: array[0..1023] of Cardinal;
  35.     iShift, jShift: Integer;
  36.     PalIndex: Integer;
  37.     procedure InitPlasma();
  38.     procedure InitPalette();
  39.     procedure SetupDevice(Sender: TAsphyreDevice; Tag: TObject;
  40.      var Config: TScreenConfig);
  41.     procedure OnResolveFailed(Sender: TObject; EventParam: Pointer;
  42.      var Success: Boolean);
  43.     procedure TimerEvent(Sender: TObject);
  44.     procedure ProcessEvent(Sender: TObject);
  45.     procedure RenderPrimary(Sender: TAsphyreDevice; Tag: TObject);
  46.     procedure DoPlasma(iShift, jShift: Integer);
  47.   public
  48.     { Public declarations }
  49.   end;
  50. //---------------------------------------------------------------------------
  51. var
  52.   MainForm: TMainForm;
  53. //---------------------------------------------------------------------------
  54. implementation
  55. uses
  56.  MediaImages, MediaFonts, AsphyreTimer, AsphyreImages, AsphyreFonts,
  57.  AsphyreEffects, AsphyreEvents;
  58. {$R *.dfm}
  59. //---------------------------------------------------------------------------
  60. procedure TMainForm.FormCreate(Sender: TObject);
  61. begin
  62.  InitPlasma();
  63.  InitPalette();
  64.  // retreive image and font descriptions
  65.  ImageGroups.ParseLink('/media.xml');
  66.  FontGroups.ParseLink('/media.xml');
  67.  if (not Devices.Initialize(SetupDevice, Self)) then
  68.   begin
  69.    MessageDlg('Failed to initialize Asphyre device.', mtError, [mbOk], 0);
  70.    Close();
  71.    Exit;
  72.   end;
  73.  // configure Asphyre timer
  74.  Timer.Enabled  := True;
  75.  Timer.OnTimer  := TimerEvent;
  76.  Timer.OnProcess:= ProcessEvent;
  77.  Timer.MaxFPS   := 4000;
  78. end;
  79. //---------------------------------------------------------------------------
  80. procedure TMainForm.FormDestroy(Sender: TObject);
  81. begin
  82.  Devices.Finalize();
  83. end;
  84. //---------------------------------------------------------------------------
  85. procedure TMainForm.InitPlasma();
  86. var
  87.  i: Integer;
  88. begin
  89.  // make lookup tables
  90.  for i:= 0 to 1023 do
  91.   begin
  92.    SinTab[i]:= (Trunc(Sin(2.0 * Pi * i / 1024.0) * 512) + 512) and $3FF;
  93.    CosTab[i]:= (Trunc(Cos(2.0 * Pi * i / 1024.0) * 512) + 512) and $3FF;
  94.   end;
  95.  // sine / cosine displacers
  96.  iShift:= 0;
  97.  jShift:= 0;
  98. end;
  99. //---------------------------------------------------------------------------
  100. procedure TMainForm.InitPalette();
  101. var
  102.  Palette: TAsphyrePalette;
  103.  i: Integer;
  104. begin
  105.  Palette:= TAsphyrePalette.Create();
  106.  Palette.Add($FF000000, ntSine, 0.0);
  107.  Palette.Add($FF7E00FF, ntSine, 0.1);
  108.  Palette.Add($FFE87AFF, ntSine, 0.2);
  109.  Palette.Add($FF7E00FF, ntSine, 0.3);
  110.  Palette.Add($FFFFFFFF, ntSine, 0.4);
  111.  Palette.Add($FF000000, ntPlain, 0.5);
  112.  Palette.Add($FF0500A8, ntBrake, 0.6);
  113.  Palette.Add($FFBEFF39, ntAccel, 0.7);
  114.  Palette.Add($FFFFC939, ntBrake, 0.8);
  115.  Palette.Add($FFFFF58D, ntSine,  0.9);
  116.  Palette.Add($FF000000, ntPlain, 1.0);
  117.  for i:= 0 to 1023 do
  118.   PaletteTab[i]:= Palette.Color[i / 1023.0];
  119.  Palette.Free();
  120. end;
  121. //---------------------------------------------------------------------------
  122. procedure TMainForm.SetupDevice(Sender: TAsphyreDevice; Tag: TObject;
  123.   var Config: TScreenConfig);
  124. begin
  125.  Config.Width   := ClientWidth;
  126.  Config.Height  := ClientHeight;
  127.  Config.Windowed:= True;
  128.  Config.WindowHandle:= Self.Handle;
  129.  Config.HardwareTL  := False;
  130.  EventResolveFailed.Subscribe(OnResolveFailed, Sender);
  131. end;
  132. //---------------------------------------------------------------------------
  133. procedure TMainForm.FormResize(Sender: TObject);
  134. begin
  135.  Devices[0].ChangeParams(ClientWidth, ClientHeight, True);
  136. end;
  137. //---------------------------------------------------------------------------
  138. procedure TMainForm.OnResolveFailed(Sender: TObject; EventParam: Pointer;
  139.  var Success: Boolean);
  140. begin
  141.  Timer.Enabled:= False;
  142.  MessageDlg('Failed to resolve symbol ' + PChar(EventParam), mtError, [mbOk],
  143.   0);
  144.  Close();
  145. end;
  146. //---------------------------------------------------------------------------
  147. procedure TMainForm.TimerEvent(Sender: TObject);
  148. begin
  149.  // place plasma on dynamic texture
  150.  DoPlasma(iShift, jShift);
  151.  Devices[0].Render(RenderPrimary, Self, 0);
  152.  Timer.Process();
  153. end;
  154. //---------------------------------------------------------------------------
  155. procedure TMainForm.RenderPrimary(Sender: TAsphyreDevice; Tag: TObject);
  156. var
  157.  i, j: Integer;
  158.  DraftIndex, ScanIndex: Integer;
  159. begin
  160.  // retreive indexes to speed up the rendering
  161.  DraftIndex:= Devices[0].Images.Image['pixelcanvas'].ImageIndex;
  162.  ScanIndex := Devices[0].Images.Image['scanline'].ImageIndex;
  163.  // draw plasma (tiled)
  164.  for j:= 0 to (ClientHeight div 256) do
  165.   for i:= 0 to (ClientWidth div 256) do
  166.    begin
  167.     Sender.Canvas.UseImage(Sender.Images[DraftIndex], TexFull4);
  168.     Sender.Canvas.TexMap(pBounds4(i * 256, j * 256, 256, 256),
  169.      clWhite4, fxuNoBlend);
  170.    end;
  171.  // apply scanline effect
  172.  for j:= 0 to (ClientHeight div 64) do
  173.   for i:= 0 to (ClientWidth div 64) do
  174.    begin
  175.     Sender.Canvas.UseImage(Sender.Images[ScanIndex], TexFull4);
  176.     Sender.Canvas.TexMap(pBounds4(i * 64, j * 64, 64, 64),
  177.     clWhite4, fxuMultiply);
  178.    end;
  179.  with Sender.Fonts.Font['x/tranceform'] do
  180.   begin
  181.    Options.Kerning:= -2;
  182.    Options.ShowShadow:= True;
  183.    TextOut('Frame Rate: ' + IntToStr(Timer.FrameRate), 4, 4, cColor2($FF9500FF,
  184.     $FFFFFFFF));
  185.   end;
  186. end;
  187. //---------------------------------------------------------------------------
  188. procedure TMainForm.ProcessEvent(Sender: TObject);
  189. begin
  190.  Inc(iShift);
  191.  Dec(jShift);
  192.  Inc(PalIndex);
  193. end;
  194. //---------------------------------------------------------------------------
  195. procedure TMainForm.DoPlasma(iShift, jShift: Integer);
  196. var
  197.  Image: TAsphyreDraft;
  198.  Bits : Pointer;
  199.  Pitch: Integer;
  200.  DestPtr: Pointer;
  201.  i, j, Xadd, Cadd: Integer;
  202.  pl: PLongword;
  203.  Index: Integer;
  204. begin
  205.  // Gain direct access to our draft surface.
  206.  Image:= TAsphyreDraft(Devices[0].Images.Image['pixelcanvas']);
  207.  if (Image = nil)or(not Image.Draft.Lock(Bits, Pitch)) then Exit;
  208.  // plasma rendering
  209.  DestPtr:= Bits;
  210.  for j:= 0 to 255 do
  211.   begin
  212.    pl:= DestPtr;
  213.    // plasma shifts
  214.    Xadd:= SinTab[((j shl 2) + iShift) and $3FF];
  215.    Cadd:= CosTab[((j shl 2) + jShift) and $3FF];
  216.    // render scanline
  217.    for i:= 0 to 255 do
  218.     begin
  219.      Index:= (SinTab[((i shl 2) + Xadd) and $3FF] + Cadd + (PalIndex * 4)) and $3FF;
  220.      if (Index > 511) then Index:= 1023 - Index;
  221.      pl^:= PaletteTab[((Index div 4) + PalIndex) and $3FF];
  222.      Inc(pl);
  223.     end;
  224.    // select the next scanline
  225.    Inc(Integer(DestPtr), Pitch);
  226.   end;
  227.  // release the surface
  228.  Image.Draft.Unlock();
  229. end;
  230. //---------------------------------------------------------------------------
  231. end.