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

2D图形编程

开发平台:

Delphi

  1. unit MainFm;
  2. //---------------------------------------------------------------------------
  3. interface
  4. //---------------------------------------------------------------------------
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, AsphyreDevices, AsphyreTorusKnot, BumpMappingFx, Matrices3, Vectors2;
  8. //---------------------------------------------------------------------------
  9. type
  10.   TMainForm = class(TForm)
  11.     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  12.     procedure FormDestroy(Sender: TObject);
  13.     procedure FormCreate(Sender: TObject);
  14.   private
  15.     { Private declarations }
  16.     GameTicks: Integer;
  17.     Shader: TBumpMappingFx;
  18.     Mesh  : TAsphyreTorusKnot;
  19.     ShowWire: Boolean;
  20.     procedure ConfigureDevice(Sender: TAsphyreDevice; Tag: TObject;
  21.      var Config: TScreenConfig);
  22.     procedure OnDeviceCreate(Sender: TObject; EventParam: Pointer;
  23.      var Success: Boolean);
  24.     procedure TimerEvent(Sender: TObject);
  25.     procedure ProcessEvent(Sender: TObject);
  26.     procedure RenderPrimary(Sender: TAsphyreDevice; Tag: TObject);
  27.   public
  28.     { Public declarations }
  29.   end;
  30. //---------------------------------------------------------------------------
  31. var
  32.   MainForm: TMainForm;
  33. //---------------------------------------------------------------------------
  34. implementation
  35. uses
  36.  Direct3D9, Vectors3, Matrices4, AsphyreTimer, AsphyreImages,
  37.  AsphyreSystemFonts, AsphyreEvents, MediaImages, AsphyreColors, AsphyreScene,
  38.  AsphyreMeshes, AsphyreShaderFX;
  39. {$R *.dfm}
  40. //---------------------------------------------------------------------------
  41. var
  42.  ImageSkin: Integer = -1;
  43.  ImageBump: Integer = -1;
  44. //---------------------------------------------------------------------------
  45. procedure TMainForm.FormCreate(Sender: TObject);
  46. begin
  47.  ImageGroups.ParseLink('/images.xml');
  48.  if (not Devices.Initialize(ConfigureDevice, Self)) then
  49.   begin
  50.    MessageDlg('Failed to initialize Asphyre device.', mtError, [mbOk], 0);
  51.    Close();
  52.    Exit;
  53.   end;
  54.  DefDevice.SysFonts.CreateFont('s/tahoma', 'tahoma', 9, False, fwtBold,
  55.   fqtClearType, fctAnsi);
  56.  // Create bump-mapping shader and load it from disk
  57.  Shader:= TBumpMappingFx.Create(DefDevice);
  58.  if (not Shader.LoadFromFile('BumpMapping.fx')) then
  59.   begin
  60.    Devices.Finalize();
  61.    ShowMessage('Failed to load shader effect!');
  62.    Close();
  63.    Exit;
  64.   end;
  65.  // Create 3-4 torus knot
  66.  Mesh:= TAsphyreTorusKnot.Create(DefDevice);
  67.  Mesh.Generate(0.4, 0.1, 3, 4, 256, 24, 16.0, 1.0);
  68.  // -> shader requires tanget and binormal vectors
  69.  Mesh.ComputeTangetBinormal();
  70.  Timer.Enabled  := True;
  71.  Timer.OnTimer  := TimerEvent;
  72.  Timer.OnProcess:= ProcessEvent;
  73.  Timer.MaxFPS   := 200;
  74.  ShowWire:= False;
  75. end;
  76. //---------------------------------------------------------------------------
  77. procedure TMainForm.FormDestroy(Sender: TObject);
  78. begin
  79.  if (Mesh <> nil) then Mesh.Free();
  80.  if (Shader <> nil) then Shader.Free();
  81.  Devices.Finalize();
  82. end;
  83. //---------------------------------------------------------------------------
  84. procedure TMainForm.ConfigureDevice(Sender: TAsphyreDevice; Tag: TObject;
  85.  var Config: TScreenConfig);
  86. begin
  87.  Config.WindowHandle:= Self.Handle;
  88.  Config.HardwareTL  := True;
  89.  Config.DepthStencil:= dsDepthOnly;
  90.  Config.Width   := ClientWidth;
  91.  Config.Height  := ClientHeight;
  92.  Config.Windowed:= False;
  93.  Config.VSync   := False;
  94.  Config.BitDepth:= bd24bit;
  95.  Config.MultiSamples:= 8;
  96.  EventDeviceCreate.Subscribe(OnDeviceCreate, Sender);
  97. end;
  98. //---------------------------------------------------------------------------
  99. procedure TMainForm.OnDeviceCreate(Sender: TObject; EventParam: Pointer;
  100.  var Success: Boolean);
  101. begin
  102.  with Sender as TAsphyreDevice do
  103.   begin
  104.    // Preload skins used with 3D mesh.
  105.    ImageSkin:= Images.ResolveImage('metal');
  106.    ImageBump:= Images.ResolveImage('metal_normal');
  107.   end;
  108. end;
  109. //---------------------------------------------------------------------------
  110. procedure TMainForm.TimerEvent(Sender: TObject);
  111. begin
  112.  DefDevice.Render(RenderPrimary, Self, $4E4438, 1.0, 0);
  113.  Timer.Process();
  114. end;
  115. //---------------------------------------------------------------------------
  116. procedure TMainForm.ProcessEvent(Sender: TObject);
  117. begin
  118.  Inc(GameTicks);
  119. end;
  120. //---------------------------------------------------------------------------
  121. procedure TMainForm.RenderPrimary(Sender: TAsphyreDevice; Tag: TObject);
  122. var
  123.  Shift: TPoint2;
  124. begin
  125.  if (Failed(DefDevice.Dev9.TestCooperativeLevel())) then Exit;
  126.  
  127.  with DefDevice.Dev9 do
  128.   begin
  129.    SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  130.    if (ShowWire) then
  131.     begin
  132.      SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
  133.      SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  134.     end else
  135.     begin
  136.      SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
  137.      SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  138.     end;
  139.   end;
  140.  // -> Viewing Camera
  141.  ViewMtx.LoadIdentity();
  142.  ViewMtx.LookAt(Vector3(5.0, 15.0, -15.0), ZeroVec3, AxisYVec3);
  143.  // -> Projection Matrix
  144.  ProjMtx.LoadIdentity();
  145.  ProjMtx.PerspectiveFovY(Pi / 4.0, ClientWidth / ClientHeight, 0.5, 100.0);
  146.  // -> Object transformation matrix
  147.  WorldMtx.LoadIdentity();
  148.  WorldMtx.Scale(12.0);
  149.  WorldMtx.RotateX(GameTicks * 0.01);
  150.  WorldMtx.RotateY(-GameTicks * 0.0067);
  151.  WorldMtx.RotateZ(GameTicks * 0.0053);
  152.  // -> Shader parameters
  153.  Shader.AmbientColor := cColor(32);
  154.  Shader.DiffuseColor := $FFFFFFFF;
  155.  Shader.SpecularColor:= $808080;
  156.  Shader.LightVector:= Vector3(1.0, -1.0, 1.0);
  157.  // -> Transform texture coordinates to simulate motion
  158.  if (not ShowWire) then
  159.   begin
  160.    Shift.x:= -GameTicks * 0.01;
  161.    Shift.x:= Shift.x - Trunc(Shift.x);
  162.    Shift.y:= GameTicks * 0.002;
  163.    Shift.y:= Shift.y - Trunc(Shift.y);
  164.    Shader.SkinMtx:= TranslateMtx3(Shift);
  165.    Shader.BumpMtx:= Shader.SkinMtx;
  166.   end else
  167.   begin
  168.    Shader.SkinMtx:= IdentityMtx3;
  169.    Shader.BumpMtx:= IdentityMtx3;
  170.   end;
  171.  // Reset vertex and face drawing count.
  172.  ResetDrawInfo();
  173.  // Start rendering 3D scene.
  174.  Shader.BeginAll();
  175.  Shader.Draw(Mesh, WorldMtx.RawMtx^, Sender.Images[ImageSkin],
  176.   Sender.Images[ImageBump]);
  177.  // Finish rendering 3D scene.
  178.  Shader.EndAll();
  179.  // Output some text.
  180.  with Sender.SysFonts.Font['s/tahoma'] do
  181.   begin
  182.    TextOut('Drawing ' + IntToStr(TotalFacesNo) + ' faces and ' +
  183.     IntToStr(TotalVerticesNo) + ' vertices.', 4, 4, $FFEFDEB5);
  184.    TextOut('Hit SPACE to switch between solid/wireframe mode.', 4, 24,
  185.     $FFE1E9B0);
  186.    case Sender.Params.MultiSampleType of
  187.     D3DMULTISAMPLE_NONE,
  188.     D3DMULTISAMPLE_NONMASKABLE:
  189.      TextOut('No multisampling support.', 4, 44, $FFC9A0F1);
  190.     D3DMULTISAMPLE_2_SAMPLES..D3DMULTISAMPLE_16_SAMPLES:
  191.      TextOut(IntToStr(Integer(Sender.Params.MultiSampleType)) +
  192.       'x multisampling used.', 4, 44, $FFC9A0F1);
  193.    end;
  194.    TextOut('Frame rate: ' + IntToStr(Timer.FrameRate), 4, 64, $FFE1E9B0);
  195.   end;
  196. end;
  197. //---------------------------------------------------------------------------
  198. procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
  199.  Shift: TShiftState);
  200. begin
  201.  if (Key = VK_ESCAPE) then Close();
  202.  if (Key = VK_SPACE) then ShowWire:= not ShowWire;
  203. end;
  204. //---------------------------------------------------------------------------
  205. end.