Einzelnen Beitrag anzeigen

schmorbraten

Registriert seit: 11. Mär 2004
16 Beiträge
 
#4

Re: Re: Leichter Zugriff auf DirectX durch Kapselung

  Alt 19. Sep 2004, 19:30
Hallo und Danke für Dein Lob.

Zu Deinen Bemerkungen:

HilfeDatei
Zur Zeit vervollständige ich die englische Hilfe, so etwas raubt unheimlich Zeit und hat nur begrenzten Spaßfaktor. Eine englische Hilfe trifft ein größeres Publikum habe ich mir so gesagt...

Position
Du benutzt ein TxorDXRect. Das ist ein n x m - Gitter (in Deinem Fall 2x2), dessen Knoten entlang eines a x b - Rechtecks gleichmäßig positioniert werden. Die Knoten-Positionen werden automatisch berechnet, hier (0,0)(a,0)(0,b)(a,b). Du hast aber volle Kontrolle über Eigenschaften eines jeden Knotens mittels der Vertex-property:
Delphi-Quellcode:
//u = 0..n-1 v=0..m-1
PxorDXVertexClassic(Rect.Vertex[u,v])^ := GetVertexClassic(-0.5,0,-0.3, 0,0,0, clBlack,0); //Pos x,y,z; Normal nx,ny,nz; VertexColor, VertexAlpha
Die PxorDXVertexClassic-Konvertierung ist notwendig, da Knoten auch andere Formate haben können. Bearbeitest Du sowieso alle Positionen manuell, kannst Du auch eine TxorDXMap, also ein n x m - Gitter, benutzen. Details siehe mitgeliefertes Beispiel Polygon.exe und Crash Course (in der Hilfe). (Eventuell neue xorDX8Update.zip runterladen)

Rotation
Rotationen finden stets um die globalen Szenen-Achsen statt. Du solltest daher
1. eventuell mit Rect.MoveCenter(True) den Schwerpunkt des Objektes in den Szenen-Nullpunkt verschieben
2. Rect.Rotate... das Objekt drehen
3. dann erst verschieben
(s. Beispiel Polygon.exe)
Alternativ kann man auch mit RotateAxis die Drehachse direkt angeben.

DrawStart
Jedes Objekt besteht aus Primitives (entweder Dreiecke oder Linien bzw. Punkte). Ein n x m - TxorDXRect besteht aus (n-1)*(m-1) Vierecken und jedes Viereck aus 2 Dreiecken. Dein 2x2-Rect besteht demzufolge aus genau 2 Dreiecken. Mit DrawStart (klassisch 0) kann man angeben, ab welchem dieser Primitives der Rendervorgang begonnen wird, bei dir also 0 oder 1. (s.a. Polygon.exe und VertexAndIndex.exe)

AlphaBlending
Mit der Alpha-Property hast Du jedem Knoten einen Alpha-Wert zugewiesen, sehr gut. Um AlphaBlending zu benutzen musst Du noch ein TxorDXAlphaBlending erzeugen und einen Blend-Effekt (z.B. BlendSrcAlpha) + Activate aufrufen. Oder einfach nur ein TxorDXTransparency und Activate. (s.a. Beispiel AlphaBlending.exe)

Camera
Nun, die Kamera braucht noch ein anschließendes Activate, um Änderungen an ihr zu realisieren. Ein Move oder Rotate bei Kameras hat jedoch keinen Einfluss auf die Vektoren LookAt, Direction, Position und Up. Besser ist es MoveTo, MoveHoriz, MoveVert, RotateHoriz etc zu benutzen (i.a. mit Parameter xorDXCamHuman oder xorDXCamID), da sich diese Änderungen auch auf die Vektoren auswirken. (s.a. Beispiel Demo.exe)

PS
Wand1 und Wand2 wieder freigeben!
Anbei geänderter Code als Attachment

Viel Erfolg,
xor alias schmorbraten

Neuer Code:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin

  //creation
  Scene := TxorDXScene.Create(Handle);
  Camera := TxorDXCamera.Create(Scene);
  Rect := TxorDXRect.Create(Scene, 2, 2, 2, 2); //set standard coordinates and colors
  Rect.MonoAlpha(0.7);

  Wand1:= TxorDXRect.Create(Scene,2,2,2,2);
  Wand1.Color[1,0]:=clWhite; // rechts Unten
  Wand1.Color[1,1]:=clBlack; // rechts oben
  Wand1.Color[0,1]:=clYellow; // Oben links
  Wand1.Color[0,0]:=clBlue; // links Unten
  Wand1.MonoAlpha(0.7);

  Wand2:= TxorDXRect.Create(Scene,2,2,2,2);
  Wand2.Color[1,0]:=clWhite; // rechts Unten
  Wand2.Color[1,1]:=clBlack; // rechts oben
  Wand2.Color[0,1]:=clYellow; // Oben links
  Wand2.Color[0,0]:=clBlue; // links Unten
  Wand2.MonoAlpha(0.7);

  AlphaBlending := TxorDXAlphaBlending.Create(Scene);
  AlphaBlending.BlendSrcAlpha;

  Scene.CreateBuffers;
  //start
  Camera.SetStandard;
  Camera.Activate;
  Scene.BackgroundColor:=clBlue;
  Scene.SetAmbientLight(255,125,255,250); //Anmerkung: statt hellem Hintergrundlicht vielleicht ein TxorDXDirectionalLight einsetzen
  Scene.LightsOn:=True;
  Scene.StartLooping(Draw);
  Scene.Move(-1,1,1);
  Scene.RotateY(-10);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //free in inverted order of creation
  FreeAndNil(AlphaBlending);
  FreeAndNil(Wand2);
  FreeAndNil(Wand1);
  FreeAndNil(Rect);
  FreeAndNil(Camera);
  FreeAndNil(Scene);
end;

//repeated drawing routine
procedure TForm1.Draw(Sender: TObject);
begin
  Scene.Clear;

  Rect.Insert;
  Rect.RotateZ(-0.10);
  Rect.Draw;

  Wand1.Insert;
  Wand1.RotateX(-0.01);
  Wand1.Draw;

  //Achtung: AlphaBlending funktioniert von hinten nach vorne,
  //also das aktuelle Objekt ist nur transparent zu zuvor eingefügten Objekten!!!!
  AlphaBlending.Activate; //wand2 ist zu 30% transparent da scralpha=wand2alpha=0.7;

  Wand2.UndoTransformation;
  Wand2.Insert;
  Wand2.MoveCenter(True); //Schwerpunkt nach 000 verschieben
  //Wand2.RotateZ(0.3); //feste rotation da undotransformation nach jedem draw
  Wand2.RotateZ(RotationsPerSecond(0.3)); //bei jedem draw wird um einen größeren winkel gedreht (0.3 umdrehungen pro sec)
  Wand2.Move(1.9,0,0); //erst nach dem drehen verschieben
  Wand2.Draw;

  AlphaBlending.Deactivate;

  Camera.MoveHoriz(0.007, xorDXCamID); //camera wird bei jedem draw etwas verschoben
  Camera.Activate;

end;

initialization

  xorDXThrowAllOtherExceptions := True;
  xorDXThrowCameraTransformationExceptions := False;
  xorDXThrowIndexSizeException := True;
  xorDXThrowCapsException := True;
  InitRotationPerSecond;

end.
  Mit Zitat antworten Zitat