unit U1Main;
interface
uses Direct3D9, D3DX9,
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ComCtrls, AppEvnts;
type
TfmMain = class(TForm)
btnExit: TButton;
StatusBar1: TStatusBar;
Panel1: TPanel;
ApplicationEvents1: TApplicationEvents;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
procedure btnExitClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
FPS: Int64;
FD3D: IDirect3D9;
Fd3dDevice: IDirect3DDevice9;
FVB: IDirect3DVertexBuffer9;
function InitD3D(HWin: HWND): HResult;
function InitGeometry: HResult;
procedure SetupMatrices;
procedure Transform;
procedure Render;
procedure Cleanup;
public
{ Public declarations }
end;
var
fmMain: TfmMain;
implementation
uses MMSystem;
{$R *.dfm}
procedure TfmMain.FormCreate(Sender: TObject);
begin
InitD3D(Panel1.Handle);
InitGeometry;
SetupMatrices;
end;
procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Cleanup;
end;
procedure TfmMain.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
Render;
Done:= false;
end;
procedure TfmMain.btnExitClick(Sender: TObject);
begin
Close;
end;
procedure TfmMain.Timer1Timer(Sender: TObject);
begin
StatusBar1.SimpleText:= Format('%u fps', [FPS]);
FPS:= 0;
end;
/////////////////////////////////////////
type
TCustomVertex = packed record
x, y, z: Single;
color: TD3DColor;
tu, tv: Single;
end;
const
D3DFVF_CustomVertex = D3DFVF_XYZ or D3DFVF_Diffuse or D3DFVF_TEX1;
function TfmMain.InitD3D(HWin: HWND): HResult; // FormCreate
var
d3dpp: TD3DPresentParameters;
begin
Result:= E_Fail;
FD3D:= Direct3DCreate9(D3D_SDK_Version);
If not Assigned(FD3D) then Exit;
ZeroMemory(@d3dpp, SizeOf(d3dpp)); // windows.pas
// FillChar(d3dpp, SizeOf(d3dpp), 0); // system.pas
d3dpp.Windowed:= true;
d3dpp.SwapEffect:= D3DSwapEffect_Discard;
d3dpp.BackBufferFormat:= D3DFmt_Unknown;
d3dpp.PresentationInterval:= D3DPRESENT_INTERVAL_IMMEDIATE;
Result:= FD3D.CreateDevice(D3DAdapter_Default,
D3DDevType_HAL,
HWin,
D3DCreate_Software_VertexProcessing,
@d3dpp,
Fd3dDevice);
if Failed(Result) then
begin
Result:= E_Fail;
Exit;
end;
Fd3dDevice.SetRenderState(D3DRS_CullMode, D3DCull_None);
Fd3dDevice.SetRenderState(D3DRS_Lighting, iFalse);
Result:= S_OK;
end; // InitD3D
function TfmMain.InitGeometry: HResult; // FormCreate
const
vertices: array[0..3] of TCustomVertex = (
(x: -1.0; y: -1.0; z:0.0; color: $FFFF0000), // A R G B
(x: -1.0; y: 1.0; z:0.0; color: $FF00FF00),
(x: 1.0; y: -1.0; z:0.0; color: $FFFFFFFF),
(x: 1.0; y: 1.0; z:0.0; color: $FF0000FF)
);
var
pVertices: Pointer;
begin
Result:= E_Fail;
if Failed(Fd3dDevice.CreateVertexBuffer(4*SizeOf(TCustomVertex),
0, D3DFVF_CustomVertex, D3DPool_Default, FVB, nil))
then Exit;
if Failed(FVB.Lock(0, SizeOf(vertices), pVertices, 0))
then Exit;
CopyMemory(pVertices, @vertices, SizeOf(vertices));
FVB.Unlock;
Result:= S_OK;
end; // InitGeometry
procedure TfmMain.SetupMatrices; // FormCreate
var
vEyePt, vLookatPt, vUpVec: TD3DVector;
matView: Td3DMatrix;
matProj: Td3DMatrix;
begin
vEyePt:= D3DXVector3(0.0, 2.7, -5.0);
vLookatPt:= D3DXVector3(0.0, 0.0, 0.0);
vUpVec:= D3DXVector3(0.0, 1.0, 0.0);
D3DXMatrixLookAtLH(matView, vEyePt, vLookatPt, vUpVec);
Fd3dDevice.SetTransform(D3DTS_View, matView);
D3DXMatrixPerspectiveFovLH(matProj, D3DX_pi/6.0, 1.0, 1.0, 100.0);
Fd3dDevice.SetTransform(D3DTS_Projection, matProj);
end; // SetupMatrices
procedure TfmMain.Transform; // Render
var
matWorld: TD3DMatrix;
iTime: LongWord;
fAngle: Single;
begin
iTime:= Round(1000 * 2.0 * D3DX_pi);
fAngle:= (-timeGetTime mod iTime) / 1000.0;
D3DXMatrixRotationY(matWorld, fAngle);
//matWorld._44:= 0.5;
Fd3dDevice.SetTransform(D3DTS_World, matWorld);
end; // Transform
procedure TfmMain.Render; // OnIdle
begin
if not (Assigned(Fd3dDevice) and Assigned(FVB)) then Exit;
Fd3dDevice.Clear(0, nil, D3DClear_Target, D3DColor_XRGB(0,0,0), 1.0, 0);
if Succeeded(Fd3dDevice.BeginScene) then
begin
Transform;
Fd3dDevice.SetStreamSource(0, FVB, 0, SizeOf(TCustomVertex));
Fd3dDevice.SetFVF(D3DFVF_CustomVertex);
Fd3dDevice.DrawPrimitive(D3DPT_TriangleStrip, 0, 2);
Fd3dDevice.EndScene;
end;
Fd3dDevice.Present(nil, nil, 0, nil);
Inc(FPS);
end; // Render
procedure TfmMain.Cleanup; // FormClose
begin
if Assigned(FVB) then FVB:= nil;
if Assigned(Fd3dDevice) then Fd3dDevice:= nil;
if Assigned(FD3D) then FD3D:= nil;
end; // Cleanup
end.