Kamera (1)
Danke
Nachdem ich viel Zeit damit verbracht habe, eine funktionierende Kamera zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität auch Anderen zur Verfügung stellen. Da mir schon viel geholfen wurde, kann ich so einen Teil meiner "Schuld" zurück zahlen.
Bitte seht ab und zu mal hier nach, ob es für diese Kamera Updates gibt. Sollte es so sein, habe ich das im Code (Kamera (2)) vermerkt. Ladet in diesem Fall bitte den Source Code der Kamera und(!) die Utilities herunter.
Meine Kamera
Die wie folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt benötigen (z.B. zum Anzeigen eines Koordinatenkreuzes, ...), so kann man auf die Property PointOfRotation zugreifen (read only).
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur Verfügung stehen, habe ich einfach mal einen Großteil meiner Funktionssammlung beigefügt (Kamera (3)). Diese Funktionen/Prozeduren werden so oder in leicht abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.
Gebrauch der Funktionen:
1. PositionCamera mit Vektoren für Position, Blickpunkt und Ausrichtung aufrufen. Die Blickrichtung gibt auch gleichzeitig den Drehpunkt der Szene an, um den dann mit RotateCamera gedreht werden kann. PositionCamera positioniert den angegebenen Blickpunkt in der Mitte des Bildschirms. PositionCamera sollte nur zur Positionierung der Kamera benutzt werden, also einmal am Anfang. Alle weiteren Kameraveränderungen sollten mit den zur Verfügung gestellten Methoden durchgeführt werden.
2. Aufruf der Funktionen RotateCamera und TranslateCamera um die Ausrichtung/Lage der Kamera zu verändern. Um das unten angegebene Beispiel implementieren zu können, müssen folgende Variablen im aktuellen Modul definiert werden:
FMousePressX, FMousePressY, FRightMousePressed, FLeftMousePressed, FxDelta, FyDelta, FxStart, FyStart, FxRot und FyRot (sind alle als var im aktuellen Modul definiert)
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.
FxRot und FyRot müssen mit 0 initialisiert werden.
procedure TExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren if not (FRightMousePressed or FLeftMousePressed) then exit; //ausrechenen um wieviel der Mauszeiger bewegt wurde FxDelta := FxStart-X; FyDelta := FyStart-Y; //Rotation anpassen, damit es nicht zu schnell wird FxRot := FxRot - FyDelta/20; Fyrot := FyRot - FxDelta/20; //das naechste mal ist das hier unser startpunkt: FxStart := X; FyStart := Y; if FRightMousePressed then begin if FxRot <> 0 then FCamera.RotateCamera (FxRot, 0, 0); if FyRot <> 0 then FCamera.RotateCamera (0, FyRot, 0); end; if FLeftMousePressed then begin if FxRot <> 0 then FCamera.TranslateCamera (FxRot, 0, 0); if FyRot <> 0 then FCamera.TranslateCamera (0, FyRot, 0); end; Paint; FxRot := 0; FyRot := 0; end;
procedure TExample.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbRight then begin //rechte maustaste gedrückt FRightMousePressed:=true; //Startposition merken FxStart:=X; FyStart:=Y; Screen.Cursor := crCursorRotate; end else if Button = mbLeft then begin //rechte maustaste gedrückt FLeftMousePressed:=true; //Startposition merken FxStart:=X; FyStart:=Y; Screen.Cursor := crCursorMove; end; // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden // welches Objekt an der aktuellen Mausposition liegt FMousePressX := X; FMousePressY := Y; end;
procedure TExample.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbRight then begin FRightMousePressed:=false; end; if Button = mbLeft then begin FLeftMousePressed:=false; end; end;
procedure TExample.FormCreate(Sender: TObject); begin inherited; FxRot:=0; FyRot:=0; FRightMousePressed := false; FLeftMousePressed := false; end;
Dieses Beispiel ist vereinfacht dargestellt und es kann sein, dass man daran noch etwas herumspielen muss. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)). Durch modifizieren der Geschwindigkeit (+/-) für die einzelnen Achsen, die an die Prozeduren TranslateCamera und RotateCamera übergeben werden kann man entweder die Szene oder die Kamera bewegen.
3. Szene zeichnen:
Lichteigenschaften setzen
Materialeigenschaften setzen
... (die üblichen Vorbereitungen treffen)
FCamera.Apply
Szene zeichnen
wenn Terrain gewünscht:
FCamera.ApplyForTerrain Terrain zeichnen
ende wenn
Swapbuffers...
usw.
Den Kameracode findet ihr unter Kamera (2).
Die verwendete Toolsammlung findet ihr unter Kamera (3).