unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Direct3D9, d3dx9, Direct3D;
type
CUSTOMVERTEX =
record
x, y, z : Single;
// Positionskoordinaten
color : TD3DColor;
// Farbe
end;
TForm1 =
class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
function GetCustomVertex(_x, _y, _z: single; _color: TD3DColor): CUSTOMVERTEX;
function InitGeometry:HRESULT;
private
procedure OnIdle (Sender: TObject;
var done: Boolean);
public
{ Public declarations }
end;
const // Format von CUSTOMVERTEX
D3DFVF_CUSTOMVERTEX = ( D3DFVF_XYZ
or D3DFVF_DIFFUSE );
var
Form1: TForm1;
d3d9: IDirect3D9;
d3ddev9: IDirect3DDevice9;
vbuffer: IDirect3DVertexBuffer9;
implementation
{$R *.DFM}
function TForm1.InitGeometry: HRESULT;
var
Vertices:
Array[0..2]
of CUSTOMVERTEX;
pVertices : PByte;
begin
// Wenn die Funktion vorzeitig abgebrochen wird, wird E_FAIL zurückgegeben
Result := E_FAIL;
// In das Vertex-Array werden die Koordinaten und Farben geschrieben
Vertices[0] := GetCustomVertex(1, -1, 0, $FFFF0000);
Vertices[1] := GetCustomVertex(-1, -1, 0, $FF0000FF);
Vertices[2] := GetCustomVertex(0, 1, 0, $FFFFFF00);
// Erstellen des Vertexbuffers
if ( d3ddev9.CreateVertexBuffer( sizeof( CUSTOMVERTEX ) * 3, 0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, vbuffer,
nil ) <> D3D_OK )
then Exit;
if ( vbuffer.Lock( 0, sizeof( Vertices ), Pointer(pVertices), 0 ) <> D3D_OK )
then Exit;
Move( Vertices, pVertices^, sizeof( Vertices ) );
vbuffer.Unlock;
result:= D3D_OK;
end;
function TForm1.GetCustomVertex(_x, _y, _z: single; _color: TD3DColor) : CUSTOMVERTEX;
begin
with result
do
begin
x := _x;
y := _y;
z := _z;
color := _color;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
d3ddm : TD3DDISPLAYMODE;
d3dpp : TD3DPRESENT_PARAMETERS;
//DeviceTypeFlag : Cardinal;
begin
// Erstellen von Direct3D9
d3d9 := Direct3DCreate9( D3D_SDK_VERSION );
if ( d3d9 =
nil )
then
Application.Terminate;
// Auslesen der aktuellen Bildschirmeinstellungen (Auflösung, Format, Refreshrate)
if ( d3d9.GetAdapterDisplayMode( D3DADAPTER_DEFAULT, d3ddm ) <> D3D_OK )
then
Application.Terminate;
// Alle Werte des Records d3dpp werden auf 0 bzw Nil gestellt
ZeroMemory( @d3dpp, sizeof( d3dpp ) );
// Das zukünftige Device wird über das Record eingestellt
d3dpp.Windowed := TRUE;
d3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat := d3ddm.Format;
d3dpp.EnableAutoDepthStencil := TRUE;
d3dpp.AutoDepthStencilFormat := D3DFMT_D16;
// Das Device wird erstellt
if ( d3d9.CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
handle,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
@d3dpp, d3ddev9 ) <> D3D_OK )
then
Application.Terminate;
InitGeometry;
d3ddev9.SetRenderState( D3DRS_LIGHTING, Cardinal( FALSE ) );
d3ddev8.SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
Application.OnIdle := OnIdle;
end;
procedure TForm1.OnIdle (Sender: TObject;
var done: Boolean);
begin
done := false;
d3ddev9.Clear( 0,
nil, D3DCLEAR_TARGET
or D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
d3ddev9.BeginScene;
// Rendern des Vertexbuffers
d3dDev9.SetStreamSource( 0, vBuffer, sizeof( CUSTOMVERTEX ) , 0);
d3dDev9.SetVertexShader(
nil );
d3dDev9.SetFVF( D3DFVF_CUSTOMVERTEX );
d3dDev9.DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
d3ddev9.EndScene;
d3ddev9.Present(
nil,
nil, 0,
nil);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if vbuffer <>
nil then vbuffer :=
nil;
if d3ddev9 <>
nil then d3ddev9 :=
nil;
if d3d9 <>
nil then d3d9:=
nil;
end;
end.