Multimedia Delphi

//DirectX nesneleri/dcu'ları kurulu olmalı
//http://www.delphi-jedi.org/DelphiGraphics/jedi-index.htm inceleyiniz
// Name: Lights Direct3D Tutorial
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
// Delphi version by Ludwig Hähne (whiskex@gmx.net)
// History
// 2000-NOV-21 * Lighting & Camera
// 2000-NOV-20 * Initialization & VertexBuffer
unit Main;
interface
uses
// Standard Includes
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
// DX8 Headers by Tim Baumgarten
DirectXGraphics,
// This file contains procs of Erik Unger's Direct3D and some written by me
DXGUtils,
// A High-Resolution Timer by Arne Schäpers
DXTimer;
type
TMainForm = class(TForm)
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure TimerTimer(Sender: TObject);
private
Res : HResult;
D3D8 : IDirect3D8;
D3DDevice : IDirect3DDevice8;
VB : IDirect3DVertexBuffer8;
Timer : TDXTimer;
public
procedure InitD3D;
procedure InitVB;
procedure CleanUp;
procedure Render;
procedure SetupMatrices;
procedure SetupLights;
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
begin
// Initialize Direct Graphics
InitD3D;
// Init Timer
Timer := TDXTimer.Create(Self);
Timer.OnTimer := TimerTimer;
Timer.Interval := 10;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
// Delete Timer
Timer.Enabled := False;
Timer.Free;
// Finalize Direct Graphics
CleanUp;
end;
procedure TMainForm.FormPaint(Sender: TObject);
begin
Render;
end;
procedure TMainForm.TimerTimer(Sender: TObject);
begin
Render;
end;
procedure TMainForm.InitD3D;
var
DisplayMode: TD3DDisplayMode;
PresentParameters: TD3DPRESENT_PARAMETERS;
Res : HResult;
begin
// Create the D3D object, which is needed to create the D3DDevice.
D3D8 := Direct3DCreate8(D3D_SDK_VERSION);
if D3D8 = nil then
begin
ShowMessage('Could not Create Direct3D8!');
Exit;
end;
// Get the current desktop display mode
Res := D3D8.GetAdapterDisplayMode( D3DADAPTER_DEFAULT, DisplayMode );
if Failed( Res ) then
begin
ShowMessage(Format('Direct3D8.GetAdapterDisplayMode reported ''%s''',[DXGErrorString(Res)]));
Exit;
end;
// Set up the structure used to create the D3DDevice.
ZeroMemory( @PresentParameters, SizeOf(PresentParameters) );
// Select Windowed Mode
PresentParameters.Windowed := True;
// Method of presenting the back buffer to the display
PresentParameters.SwapEffect := D3DSWAPEFFECT_DISCARD;
// Use the same format for the backbuffer that our desktop has
PresentParameters.BackBufferFormat := DisplayMode.Format;
// Create a ZBuffer
PresentParameters.EnableAutoDepthStencil := True;
// Use a 16bit ZBuffer
PresentParameters.AutoDepthStencilFormat := D3DFMT_D16;
// Create the Direct3D device using the default adapter and requesting HAL
Res := D3D8.CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, PresentParameters,
D3DDevice );
if Failed( Res ) then
begin
ShowMessage(Format('Direct3D8.CreateDevice reported ''%s''',[DXGErrorString(Res)]));
Exit;
end;
// Render States
// Turn off culling, so we see the front and back of the triangle
D3DDevice.SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn on ZBuffering
D3DDevice.SetRenderState( D3DRS_ZENABLE, 1 );
// Set some ambient light
D3DDevice.SetRenderState( D3DRS_AMBIENT, $00202020 );
// Turn on Lighting
D3DDevice.SetRenderState( D3DRS_LIGHTING, 1 );
// Init Vertex Buffer
InitVB;
end;
procedure TMainForm.CleanUp;
begin
if VB <> nil then VB := nil;
if D3DDevice <> nil then D3DDevice := nil;
if D3D8 <> nil then D3D8 := nil;
end;
type
// A structure for our custom vertex type
PCustomVertex = ^TCustomVertex;
TCustomVertex = record
Position : TD3DVector;
Normal : TD3DVector;
end;
const
// Our custom FVF, which describes our custom vertex structure
D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_NORMAL;
procedure TMainForm.InitVB;
var
Vertices : PCustomVertex;
i : Cardinal;
theta : Single;
begin
// Create the vertex buffer - Specify size, FVF, which memory to use
Res := D3DDevice.CreateVertexBuffer(50*2*SizeOf(TCustomVertex),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,VB);
if Failed( Res ) then
begin
ShowMessage(Format('Direct3DDevice8.CreateVertexBuffer reported ''%s''',[DXGErrorString(Res)]));
Exit;
end;
// Lock the Vertex Buffer to gain access to the vertices
Res := VB.Lock( 0, 50*2*SizeOf(TCustomVertex), PByte(Vertices), 0 );
if Failed( Res ) then
begin
ShowMessage(Format('Direct3DVertexBuffer8.Lock reported ''%s''',[DXGErrorString(Res)]));
Exit;
end;
// Fill the vertex buffer. We are algorithmically generating a cylinder
// here, including the normals, which are used for lighting.
for i := 0 to 49 do
begin
theta := (2*Pi*i) / 49;
Vertices.Position := D3DVector( sin(theta), -1, cos(theta) );
Vertices.Normal := D3DVector( sin(theta), 0, cos(theta) );
Inc(Vertices);
Vertices.Position := D3DVector( sin(theta), 1, cos(theta) );
Vertices.Normal := D3DVector( sin(theta), 0, cos(theta) );
Inc(Vertices);
end;
// And Unlock it
VB.Unlock;
end;
procedure TMainForm.Render;
begin
if D3DDevice = nil then Exit;
// Clear the backbuffer and ZBuffer
D3DDevice.Clear( 0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,255), 1.0, 0 );
// Begin the scene
D3DDevice.BeginScene;
// Apply Materials and Lights
SetupLights;
// Set Transformstates (World,View,Projection)
SetupMatrices;
// Specify our VB as the Source of the stream
D3DDevice.SetStreamSource( 0, VB, SizeOf(TCustomVertex) );
// Use standard Vertex Shader (just the FVF)
D3DDevice.SetVertexShader( D3DFVF_CUSTOMVERTEX );
// Render Geometry
D3DDevice.DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 50*2-2 );
// End the scene
D3DDevice.EndScene;
// Present the backbuffer contents to the display
D3DDevice.Present( nil, nil, 0, nil );
end;
procedure TMainForm.SetupMatrices;
var
World, View, Proj: TD3DMatrix;
begin
// For our world matrix, we will just rotate the object about the x-axis
SetRotateXMatrix(World, sin(GetTickCount/500)*0.4 );
D3DDevice.SetTransform( D3DTS_WORLD, World );
// Set up our view matrix
SetViewMatrix( View, D3DVector(0,0,-5), D3DVector(0,0,0), D3DVector(0,1,0));
D3DDevice.SetTransform( D3DTS_VIEW, View );
// Set up projection matrix
SetProjectionMatrix( Proj, PI/4, ClientWidth / ClientHeight, 1, 100 );
D3DDevice.SetTransform( D3DTS_PROJECTION, Proj );
end;
procedure TMainForm.SetupLights;
var
Material : TD3DMaterial8;
Light : TD3DLight8;
Direction : TD3DVector;
begin
// Init the material with yellow diffuse and ambient colors
Material := InitMaterial(1,1,0,1);
// Send Material to device
D3DDevice.SetMaterial( Material );
// Set oscillating Light Direction
Direction := D3DVector( cos(GetTickCount/350), 0, sin(GetTickCount/350) );
// Init a white light
Light := InitDirectionalLight( Direction, 1, 1, 1, 1000 );
// Send it to the Device
D3DDevice.SetLight( 0, Light );
// And enable it
D3DDevice.LightEnable( 0, True );
end;
end.