BGRABitmap tutorial 15/de
│ Deutsch (de) │ English (en) │
Home | Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8 | Tutorial 9 | Tutorial 10 | Tutorial 11 | Tutorial 12 | Tutorial 13 | Tutorial 14 | Tutorial 15 | Tutorial 16 | Edit
Dieses Tutorial zeigt Ihnen, wie Sie 3D-Objekte mittels des TBGRAScene3D-Objekts darstellen.
Das Szenenobjekt
Das Szenenobjekt ist in der Unit "BGRAScene3D" enthalten. Hier ist ein einfaches Beispiel:
uses BGRAScene3D, BGRABitmap, BGRABitmapTypes;
procedure TForm1.FormPaint(Sender: TObject);
var
scene: TBGRAScene3D;
bmp: TBGRABitmap;
base: array of IBGRAVertex3D;
topV: IBGRAVertex3D;
begin
bmp := TBGRABitmap.Create(ClientWidth,ClientHeight,BGRABlack);
scene := TBGRAScene3D.Create(bmp);
//erzeugt eine Pyramide
with scene.CreateObject(BGRA(255,240,128)) do
begin
//erzeugt die Kanten
topV := MainPart.Add(0,-15,0);
//die Basis der Pyramide ist im Uhrzeigersinn angeordnet, wenn wir von unten auf die Pyramide sehen
base := MainPart.Add([-20,15,-20, 20,15,-20, 20,15,20, -20,15,20]);
AddFace(base);
//fügt vier Flächen hinzu, die drei Kanten sind im Uhrzeigersinn angeordnet
AddFace([base[0],topV,base[1]]);
AddFace([base[1],topV,base[2]]);
AddFace([base[2],topV,base[3]]);
AddFace([base[3],topV,base[0]]);
topV := nil;
base := nil;
end;
scene.Render;
scene.Free;
bmp.Draw(Canvas,0,0);
bmp.Free;
end;
Das Szenenobjekt zeichnet sich selbst auf ein TBGRABitmap-Objekt. Sie können die Bitmap entweder als Parameter beim Erzeugen des Objekts übergeben, so wie hier, oder nachträglich der Eigenschaft "Surface" zuweisen. Die Szene wird automatisch in der Bitmap zentriert.
Das Szenenobjekt bietet die Funktion "CreateObject", welche eine Schnittstelle auf das erzeugte Objekt zurückgibt. Objekte innerhalb einer Szene werden automatisch freigegeben, wenn Sie die Szene freigeben.
Ein Objekt hat eine Eigenschaft "MainPart", die es erlaubt, Kanten zu erzeugen und auf diese zuzugreifen. Die Koordinaten können als drei einzelne Werte angegeben werden, als TPoint3D-Records, oder als Array von einzelnen Werten, dessen Länge ein Vielfaches von 3 ist. Wenn Sie eine Kante erzeugen, erhalten Sie eine IBGRAVertex3D-Schnittstelle, die Sie zum Erzeugen von Flächen verwenden können.
Die X-Achse zeigt nach rechts, die Y-Achse zeigt nach unten, und die Z-Achse zeigt vorwärts (hinter den Bildschirm). Das bedeutet, dass XY gleich liegt wie in einer Bitmap, und dass es einen Wert für die Tiefe gibt. Die Flächen müssen im Uhrzeigersinn geordnet sein, um sichtbar zu sein.
Hier wird die Farbe für das gesamte Objekt beim Erzeugen festgelegt, aber Sie können sie auch individuell für jede Fläche setzen, oder für jede Kante.
Wie Sie sehen, wird die Pyramide von der Seite gezeigt, wir können also nur eine Fläche sehen. Es gibt auch keine Beleuchtung.
Fügen Sie im 'with'-Block folgende Zeilen ein:
MainPart.Scale(1.3);
MainPart.RotateYDeg(30);
MainPart.RotateXDeg(20);
MainPart.Translate(0,-5,0);
Die erste Zeile macht das Objekt etwas größer. Zwei Drehungen werden angewendet. Die erste erfolgt um die Y-Achse und die zweite um die X-Achse. Um den Drehsinn festzulegen, schauen wir in Richtung einer Achse. Ein positiver Wert in Grad bedeutet eine Drehung im Uhrzeigersinn, ein positiver Wert in Radiant bedeutet eine Drehung im Gegenzeigersinn.
Zuletzt erfolgt eine vertikale Schiebung, um das Objekt zu zentrieren.
Jetzt fügen wir etwas Licht hinzu:
//setzt die ambiente Helligkeit auf Dunkel (1 ist normale Helligkeit, 2 ist völliges Weiss)
scene.AmbiantLightness := 0.5;
//fügt eine direktionale Beleuchtung von links-oben hinzu, die maximale Helligkeit ist 0.5 + 1 = 1.5
scene.AddDirectionalLight(Point3D(1,1,1), 1);
Das Beispiel verwendet Helligkeitswerte. 0 ist schwarz, 1 bedeutet unveränderte Farbe, und 2 ist weiss. Die direktionale Beleuchtung braucht einen Point3D-Parameter, um die Richtung des Lichtstrahls anzuzeigen. Dieser muss nicht normalisiert werden.
Ableiten von TBGRAScene3D
Der Szenencode kann in ein Objekt eingebettet werden. Hier ist das vorige Beispiel in einer einzelnen Unit:
unit ex1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, BGRAScene3D, BGRABitmapTypes;
type
{ TExample1 }
TExample1 = class(TBGRAScene3D)
SandColor: TBGRAPixel;
constructor Create;
procedure Render; override;
end;
implementation
{ TExample1 }
constructor TExample1.Create;
var
base: array of IBGRAVertex3D;
top: IBGRAVertex3D;
begin
inherited Create;
SandColor := BGRA(255,240,128);
//erzeugt eine Pyramide
with CreateObject(SandColor) do
begin
top := MainPart.Add(0,-15,0);
//die Basis der Pyramide ist im Uhrzeigersinn angeordnet, wenn wir von unten auf die Pyramide sehen
base := MainPart.Add([-20,15,-20, 20,15,-20, 20,15,20, -20,15,20]);
AddFace(base);
//fügt vier Flächen hinzu, die drei Kanten sind im Uhrzeigersinn angeordnet
AddFace([base[0],top,base[1]]);
AddFace([base[1],top,base[2]]);
AddFace([base[2],top,base[3]]);
AddFace([base[3],top,base[0]]);
MainPart.Scale(1.3);
MainPart.RotateYDeg(30);
MainPart.RotateXDeg(20);
MainPart.Translate(0,-5,0);
end;
//setzt die ambiente Helligkeit auf Dunkel (1 ist normale Helligkeit, 2 ist völliges Weiss)
AmbiantLightness := 0.5;
//fügt eine direktionale Beleuchtung von links-oben hinzu, die maximale Helligkeit ist 0.5 + 1 = 1.5
AddDirectionalLight(Point3D(1,1,1),1);
//wir können Antialiasing eisetzen, weil es eine einfache Szene ist
Antialiasing := True;
end;
procedure TExample1.Render;
begin
//füllt den Hintergrund
Surface.GradientFill(0,0,Surface.Width,Surface.Height,SandColor,MergeBGRA(SandColor,BGRABlack),gtRadial,PointF(0,0),PointF(Surface.Width,Surface.Height),dmSet);
inherited Render;
end;
end.
Um die Szene jetzt zu zeichnen, geben wir ein:
uses BGRABitmap, BGRABitmapTypes, BGRAScene3D, ex1;
procedure TForm1.FormPaint(Sender: TObject);
var
bmp: TBGRABitmap;
scene: TBGRAScene3D;
begin
bmp := TBGRABitmap.Create(ClientWidth,ClientHeight,BGRABlack);
scene := TExample1.Create;
scene.Surface := bmp;
scene.Render;
scene.Free;
bmp.Draw(Canvas,0,0);
bmp.Free;
end;
Nebenbei, es wurde Antialiasing und ein Hintergrund hinzugefügt. Beachten Sie, dass Antialiasing nur bei einfachen Szenen funktioniert. Komplexe Szenen mit Texturen und transparenten Farben werden nicht korrekt dargestellt.
Voriges Tutorial (Canvas 2D) | Nächstes Tutorial (Texturen mit 3D-Objekten)
Seite übersetzt von: --billyraybones 00:05, 21 October 2011 (CEST)