![]() |
DirectX 9 mit Delphi 2005
Microsoft stellt für das Zeichnen per 3D mit DirectX9 in .Net gute Beispiele zur Verfügung:
![]() Leider ist der Einstieg für Delphi sehr verworren, darum habe ich Tutorial 3 für Delphi umgearbeitet. Was wird benötigt: Delphi 2005 DirectX SDK von Microsoft Das DirectX SDK installiert die notwendigen Assemblies nach: C:\WINDOWS\Microsoft.NET\Managed DirectX\v9.05.132\ Microsoft.DirectX, Microsoft.DirectX.Direct3D muss dem Projekt als Referenz hinzugefügt werden. Folgende Klasse sollte in eine eigene Unit implementiert werden:
Delphi-Quellcode:
Zum Aufruf benötigt man folgende Variablendeklaration:
interface
uses Microsoft.DirectX, Microsoft.DirectX.Direct3D, System.Drawing, System.Windows.Forms; type TPaintDirectX9 = class private Fdevice: Device; // Our rendering device FVertexBuffer: VertexBuffer; procedure InitializeGraphics(OutControl: System.Windows.Forms.Control); procedure OnCreateDevice(sender: TObject; e: EventArgs); procedure OnResetDevice(sender: TObject; e: EventArgs); procedure OnCreateVertexBuffer(sender: TObject; e: EventArgs); procedure SetupMatrices; procedure SetupLights; public constructor Create(OutControl: System.Windows.Forms.Control); procedure Render; end; implementation constructor TPaintDirectX9.Create(OutControl: System.Windows.Forms.Control); begin inherited Create; try InitializeGraphics(OutControl); except on e: DirectXException do Raise Exception.Create('Fehler beim Zugriff auf DirectX 9: ' + e.Message); end; end; procedure TPaintDirectX9.InitializeGraphics(OutControl: System.Windows.Forms.Control); var FPresentParams: PresentParameters; begin FPresentParams := PresentParameters.Create; FPresentParams.Windowed := true; // We don't want to run fullscreen FPresentParams.SwapEffect := SwapEffect.Discard; // Discard the frames FPresentParams.EnableAutoDepthStencil := true; // Turn on a Depth stencil FPresentParams.AutoDepthStencilFormat := DepthFormat.D16; // And the stencil format Fdevice := Device.Create(0, DeviceType.Hardware, OutControl, CreateFlags.SoftwareVertexProcessing, [FPresentParams]); //Create a device Borland.Delphi.System.Include(Fdevice.DeviceReset, Self.OnResetDevice); self.OnCreateDevice(Fdevice, NIL); self.OnResetDevice(Fdevice, NIL); end; procedure TPaintDirectX9.OnCreateVertexBuffer(sender: TObject; e: EventArgs); var vb: VertexBuffer; verts: System.&Array; //of CustomVertex.PositionNormal; i: Integer; theta: Single; begin vb := VertexBuffer(sender); // Create a vertex buffer (100 customervertex) verts := vb.Lock(0,LockFlags.None); // Lock the buffer (which will return our structs) try for i := 0 to 49 do begin // Fill up our structs theta := (2 * Math.PI * i) / 49; verts.SetValue(CustomVertex.PositionNormal.Create( Vector3.Create(Math.Sin(theta), -1, Math.Cos(theta)), Vector3.Create(Math.Sin(theta), 0, Math.Cos(theta))), 2*i); verts.SetValue(CustomVertex.PositionNormal.Create( Vector3.Create(Math.Sin(theta), 1, Math.Cos(theta)), Vector3.Create(Math.Sin(theta), 0, Math.Cos(theta))), 2*i+1); end; finally vb.Unlock; end; end; procedure TPaintDirectX9.OnCreateDevice(sender: TObject; e: EventArgs); var dev: Microsoft.DirectX.Direct3D.Device; begin dev := Device(sender); // Hier wird der Puffer für die Dreiecke erzeugt FvertexBuffer := VertexBuffer.Create(typeof(CustomVertex.PositionNormal), 100, dev, Usage.WriteOnly, CustomVertex.PositionNormal.Format, Pool.Default); Borland.Delphi.System.Include(FvertexBuffer.Created, Self.OnCreateVertexBuffer); Self.OnCreateVertexBuffer(FvertexBuffer, NIL); end; procedure TPaintDirectX9.OnResetDevice(sender: TObject; e: EventArgs); var dev: Device; begin dev := Device(sender); // Turn off culling, so we see the front and back of the triangle dev.RenderState.CullMode := Microsoft.DirectX.Direct3D.Cull.None; // Turn on the ZBuffer dev.RenderState.ZBufferEnable := true; dev.RenderState.Lighting := true; //make sure lighting is enabled end; procedure TPaintDirectX9.SetupLights; var col: System.Drawing.Color; mtrl: Material; begin col := System.Drawing.Color.White; //Set up a material. The material here just has the diffuse and ambient //colors set to yellow. Note that only one material can be used at a time. mtrl := Microsoft.DirectX.Direct3D.Material.Create; mtrl.Diffuse := col; mtrl.Ambient := col; Fdevice.Material := mtrl; //Set up a white, directional light, with an oscillating direction. //Note that many lights may be active at a time (but each one slows down //the rendering of our scene). However, here we are just using one. Also, //we need to set the D3DRS_LIGHTING renderstate to enable lighting Fdevice.Lights[0].&Type := LightType.Directional; Fdevice.Lights[0].Diffuse := System.Drawing.Color.DarkTurquoise; Fdevice.Lights[0].Direction := Vector3.Create(Math.Cos(Environment.TickCount / 250.0), 1.0, Math.Sin(Environment.TickCount / 250.0)); Fdevice.Lights[0].Enabled := true;//turn it on //Finally, turn on some ambient light. //Ambient light is light that scatters and lights all objects evenly Fdevice.RenderState.Ambient := System.Drawing.Color.FromArgb(32,32,32); end; procedure TPaintDirectX9.SetupMatrices; begin // For our world matrix, we will just rotate the object about the y-axis. Fdevice.Transform.World := Matrix.RotationAxis(Vector3.Create(Math.Cos(Environment.TickCount / 250.0),1, Math.Sin(Environment.TickCount / 250.0)), Environment.TickCount / 3000.0 ); // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction. Fdevice.Transform.View := Matrix.LookAtLH(Vector3.Create( 0.0, 3.0,-5.0 ), Vector3.Create( 0.0, 0.0, 0.0), Vector3.Create( 0.0, 1.0, 0.0 ) ); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered). Fdevice.Transform.Projection := Matrix.PerspectiveFovLH( Math.PI / 4.0, 1.0, 1.0, 100.0); end; procedure TPaintDirectX9.Render; begin //Clear the backbuffer to a blue color Fdevice.Clear(ClearFlags.Target or ClearFlags.ZBuffer, System.Drawing.Color.Blue, 1.0, 0); //Begin the scene Fdevice.BeginScene(); // Setup the lights and materials SetupLights(); // Setup the world, view, and projection matrices SetupMatrices(); Fdevice.SetStreamSource(0, FVertexBuffer, 0); Fdevice.VertexFormat := CustomVertex.PositionNormal.Format; Fdevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, (4*25)-2); //End the scene Fdevice.EndScene(); // Update the screen Fdevice.Present(); end;
Delphi-Quellcode:
Das Objekt wird dann wie folgt erzeugt
F3D: TPaintDirectX9;
Delphi-Quellcode:
Das Zeichnen der 3D-Animation kann aus einem Timer aufgerufen werden:
try
// Die 3D Ausgabe wird hier auf Ein Panel gelegt F3D := TPaintDirectX9.Create(Self.Panel1); except on e: Exception do MessageBox.Show('Beim Erzeugen der 3D-Anzeige ist ein Fehler aufgetreten:'+ #13#10 + E.Message); end;
Delphi-Quellcode:
[edit=Matze]Code formatiert. Mfg, Matze[/edit]
F3D.Render;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz