unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, direct3d9, d3dx9, dxhelp, ExtCtrls;
type
TForm2 =
class(TForm)
Panel1: TPanel;
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
procedure OnIdle(Sender: TObject;
var done: boolean);
public
{ Public-Deklarationen }
end;
var
Form2: TForm2;
Direct3D9: IDirect3D9;
D3DDev9: IDirect3DDevice9;
Vertexbuffer: IDirect3DVertexBuffer9;
vb_cylinder: IDirect3DVertexBuffer9;
Timegap, Timestart: Cardinal;
type
TD3DLVertex =
record
position: TD3DXVector3;
diffuse: TD3DColor;
end;
const
D3DFVF_TD3DLVertex = D3DFVF_XYZ
or D3DFVF_DIFFUSE;
implementation
{$R *.dfm}
function InitCylinder: HResult;
var
Vertices:
Array[0..99]
of TD3DLVertex;
CX: Integer;
theta: Single;
pVertices: Pointer;
begin
// Dieser Zylinder wird über eine Schleife erstellt
// in der jeweils der obere und untere Vertex definiert wird
for cx := 0
to 49
do
begin
theta := ( 2 * D3DX_PI * CX ) / 49;
Vertices[ 2 * CX ].position := D3DXVector3( cos( theta ), -1.0, sin( theta ) );
Vertices[ 2 * CX ].diffuse := $FF00FF00;
Vertices[ 2 * CX + 1 ].position := D3DXVector3( cos( theta ), 1.0, sin( theta ) );
Vertices[ 2 * CX + 1 ].diffuse := $FFFF0000;
end;
// Erstellen des vb_Zylinders
Result := D3DDev9.CreateVertexBuffer( sizeof( TD3DLVertex ) * 100,
D3DUSAGE_WRITEONLY,
D3DFVF_TD3DLVERTEX,
D3DPOOL_DEFAULT,
vb_cylinder,
nil );
if (Result <> D3D_OK)
then
Exit;
Result := vb_cylinder.Lock( 0, Sizeof( Vertices ), pVertices, 0 );
if (Result <> D3D_OK)
then
Exit;
Move( Vertices, pVertices^, sizeof( Vertices ) );
vb_cylinder.Unlock;
Result := D3D_OK;
end;
procedure SetupTransformation;
var
matRotZ: TD3DXMatrix;
Rotation: Single;
begin
Rotation := Rotation + TimeGap * 0.005;
D3DXMatrixRotationZ( matRotZ, Rotation );
D3DDev9.SetTransform( D3DTS_WORLDMATRIX(0), matRotZ);
end;
procedure SetupViewAndProjection;
var
pos, dir, up: TD3DXVector3;
matView, matProj: TD3DXMatrix;
begin
// Position, Richtung und Ausrichtung festlegen
pos := D3DXVector3( 1, 2, -5 );
dir := D3DXVector3( 0, 0, 0 );
up := D3DXVector3( 0.0, 1.0, 0.0 );
// Viewmatrix festlegen
D3DXMatrixLookAtLH( matView, pos, dir, up );
D3DDev9.SetTransform( D3DTS_VIEW, matView );
// Projektionsmatrix festlegen
D3DXMatrixPerspectiveFovLH( matProj,
D3DX_PI / 4,
Form2.Width / Form2.Height,
1.0, 100 );
D3DDev9.SetTransform( D3DTS_PROJECTION, matProj );
end;
// Dreieck erstellen
function InitGeometry: HResult;
var
Vertices:
Array[0..2]
of TD3DLVertex;
pVertices: Pointer;
begin
// Vertices Eigenschaften
Vertices[ 0 ].position := D3DXVector3( 1, 0, 0 );
Vertices[ 0 ].diffuse := $FFFF0000;
Vertices[ 1 ].position := D3DXVector3( -1, 0, 0 );
Vertices[ 1 ].diffuse := $FF0000FF;
Vertices[ 2 ].position := D3DXVector3( 0, 1, 0 );
Vertices[ 2 ].diffuse := $FFFFFFFF;
// Buffer erstellen
Result := D3DDev9.CreateVertexBuffer( sizeof( TD3DLVertex ) * 3,
D3DUSAGE_WRITEONLY,
D3DFVF_TD3DLVERTEX, D3DPOOL_DEFAULT,
Vertexbuffer,
nil);
// Gelungen?
if (Result <> D3D_OK)
then
Exit;
// Vertexbuffer schließen
Result := VertexBuffer.Lock( 0, Sizeof( Vertices ), pVertices, 0 );
// Gelungen?
if (Result <> D3D_OK)
then
Exit;
// Dann schieben wir die Vertices an die erlaubte Stelle
Move( Vertices, pVertices^, Sizeof( Vertices ) );
// Wieder aufschließen
Result := Vertexbuffer.Unlock;
// Kein Lichteinfall
D3DDev9.SetRenderState( D3DRS_LIGHTING, LongWord( False ) );
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
// Interface erstellen
DHInitDGFX( Panel1.Handle, False, 1280,1024,32, True, Direct3D9, D3DDev9 );
InitGeometry;
InitCylinder;
Application.OnIdle := OnIdle;
end;
procedure TForm2.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
DHCloseDGFX( Direct3D9, D3DDev9);
Vertexbuffer :=
nil;
end;
procedure Render;
begin
// Zeitdifferenz ermitteln
TimeGap := GetTickCount - Timestart;
Timestart := gettickcount;
D3DDev9.BeginScene;
D3DDev9.Clear( 0,
nil, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 10.0, 0);
// Kameraeinstellung wählen
SetupViewAndProjection;
// Transformation einstellen
// SetupTransformation;
// Streamsource setzen
D3DDev9.SetStreamSource(0, vb_cylinder, 0, Sizeof( TD3DLVertex) );
// FVF setzen
D3DDev9.SetFVF( D3DFVF_TD3DLVertex );
// DAS Dreieck rendern
D3DDev9.DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
D3DDev9.EndScene;
D3DDev9.Present(
nil,
nil, 0,
nil );
end;
procedure TForm2.OnIdle(Sender: TObject;
var done: boolean);
begin
done := false;
Render;
end;
end.