Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Grafik / Sound / Multimedia (https://www.delphipraxis.net/21-library-grafik-sound-multimedia/)
-   -   Prism DirectX 9 mit Delphi 2005 (https://www.delphipraxis.net/41848-directx-9-mit-delphi-2005-a.html)

Mario 9. Mär 2005 16:03


DirectX 9 mit Delphi 2005
 
Microsoft stellt für das Zeichnen per 3D mit DirectX9 in .Net gute Beispiele zur Verfügung:
http://msdn.microsoft.com/archive/en.../tutorials.asp

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:
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;
Zum Aufruf benötigt man folgende Variablendeklaration:
Delphi-Quellcode:
 F3D: TPaintDirectX9;
Das Objekt wird dann wie folgt erzeugt
Delphi-Quellcode:
  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;
Das Zeichnen der 3D-Animation kann aus einem Timer aufgerufen werden:
Delphi-Quellcode:
  F3D.Render;
[edit=Matze]Code formatiert. Mfg, Matze[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz