<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://wiki.delphigl.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Andyh</id>
		<title>DGL Wiki - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.delphigl.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Andyh"/>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php/Spezial:Beitr%C3%A4ge/Andyh"/>
		<updated>2026-05-30T22:19:42Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.27.4</generator>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=27059</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=27059"/>
				<updated>2022-01-30T11:59:27Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurückzahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
Die hier vorzufindende Beschreibung stellt keine komplette Anleitung für die Verwendung der Kamera dar. Um bis in die &amp;quot;Tiefen&amp;quot; des Objekts hinabzusteigen seht Euch bitte das von mir bereit gestellte Beispielprogramm an ([[Kamera]]). Wenn Ihr das herunterladet habt Ihr auch auf jeden Fall die neueste Version der Sourcen, die ich zuletzt am 26.12.2007 aktualisert habe. Diese Sourcen vereinfachen die Verarbeitung von Tastatur- und Mausevents. Die u.a. Anleitung entspricht daher nicht mehr dem aktuellen Vorgehen, kann aber auch weiterhin so angewendet werden.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then&lt;br /&gt;
    Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFExample.Render: wglMakeCurrent failed with ';&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=25079</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=25079"/>
				<updated>2011-03-22T16:37:27Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: /* Gebrauch der Funktionen: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
Die hier vorzufindende Beschreibung stellt keine komplette Anleitung für die Verwendung der Kamera dar. Um bis in die &amp;quot;Tiefen&amp;quot; des Objekts hinabzusteigen seht Euch bitte das von mir bereit gestellte Beispielprogramm an ([[Kamera]]). Wenn Ihr das herunterladet habt Ihr auch auf jeden Fall die neueste Version der Sourcen, die ich zuletzt am 26.12.2007 aktualisert habe. Diese Sourcen vereinfachen die Verarbeitung von Tastatur- und Mausevents. Die u.a. Anleitung entspricht daher nicht mehr dem aktuellen Vorgehen, kann aber auch weiterhin so angewendet werden.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then&lt;br /&gt;
    Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFExample.Render: wglMakeCurrent failed with ';&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24886</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24886"/>
				<updated>2010-07-24T06:39:39Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: Links zu Homepage haben sich geändert, habe ich angepasst&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
}}&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
{{ArchivLink|file=kamera_heyroth‎‎|text=Das Beispielprogramm findet Ihr hier}}. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Projekt habe ich auf meiner Homepage veröffentlicht. Es ist ein simples Spiel, welches mit verschiedenen Kameraeinstellungen arbeitet. Dadurch kann man einiges über die Kamera erfahren. Die letzten Entwicklungen sind nur hier eingeflossen. Das Projekt auf dieser Seite werde ich nicht mehr aktualisieren. Wollt Ihr also den neuesten Source Code, dann schaut Euch auf meiner Homepage entweder das neueste [http://www.heyroth.biz/main.html?src=%2F#2,5 Kamerabeispiel] oder [http://www.heyroth.biz/main.html?src=%2F#2,6 Spiel] an. &lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesen Modulen geben, so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andree Heyroth, Alias: AndyH).&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24270</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24270"/>
				<updated>2009-10-31T06:52:16Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
}}&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [http://files.delphigl.com/Download/kamera_heyroth.zip Download]. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Projekt habe ich auf meiner Homepage veröffentlicht. Es ist ein simples Spiel, welches mit verschiedenen Kameraeinstellungen arbeitet. Dadurch kann man einiges über die Kamera erfahren. Die letzten Entwicklungen sind nur hier eingeflossen. Das Projekt auf dieser Seite werde ich nicht mehr aktualisieren. Wollt Ihr also den neuesten Source Code, dann schaut Euch auf meiner Homepage entweder das neueste [http://www.heyroth.biz/main.html?src=%2F#2,2 Kamerabeispiel] oder [http://www.heyroth.biz/main.html?src=%2F#2,3 Spiel] an. &lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesen Modulen geben, so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andree Heyroth, Alias: AndyH).&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24269</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24269"/>
				<updated>2009-10-31T06:51:42Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
}}&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [http://files.delphigl.com/Download/kamera_heyroth.zip Download]. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Projekt habe ich auf meiner Homepage veröffentlicht. Es ist ein simples Spiel, welches mit verschiedenen Kameraeinstellungen arbeitet. Dadurch kann einiges über die Kamera erfahren. Die letzten Entwicklungen sind nur hier eingeflossen. Das Projekt auf dieser Seite werde ich nicht mehr aktualisieren. Wollt Ihr also den neuesten Source Code, dann schaut Euch auf meiner Homepage entweder das neueste [http://www.heyroth.biz/main.html?src=%2F#2,2 Kamerabeispiel] oder [http://www.heyroth.biz/main.html?src=%2F#2,3 Spiel] an. &lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesen Modulen geben, so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andree Heyroth, Alias: AndyH).&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24253</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24253"/>
				<updated>2009-10-27T08:04:31Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
}}&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [http://files.delphigl.com/Download/kamera_heyroth.zip Download]. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Projekt habe ich auf meiner Homepage veröffentlicht. Es ist ein simples Spiel. das mit verschiedenen Kameraeinstellungen spielt. Man kann einiges über die Kamera erfahren. Die letzten Entwicklungen sind nur hier eingeflossen. Das Projekt auf dieser Seite werde ich niht mehr aktualisieren. Wollt Ihr also den neuesten Source Code, dann schaut Euch auf meiner Homepage entweder das neueste [http://www.heyroth.biz/main.html?src=%2F#2,2 Kamerabeispiel] oder [http://www.heyroth.biz/main.html?src=%2F#2,3 Spiel] an. &lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesen Modulen geben, so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andree Heyroth, Alias: AndyH).&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24114</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=24114"/>
				<updated>2009-08-10T03:35:57Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
}}&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[http://files.delphigl.com/Download/kamera_heyroth.zip&lt;br /&gt;
]]. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andree Heyroth, Alias: AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=21115</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=21115"/>
				<updated>2008-02-08T08:40:10Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[http://files.delphigl.com/Download/kamera_heyroth.zip&lt;br /&gt;
]]. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andree Heyroth, Alias: AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(3)&amp;diff=21091</id>
		<title>Kamera (3)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(3)&amp;diff=21091"/>
				<updated>2008-02-05T05:04:25Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&lt;br /&gt;
&lt;br /&gt;
Ich habe einfach alle Funktionen meiner Toolsammlung hierhin kopiert. Ich wollte jetzt nicht offline etwas weglöschen was vielleicht benötigt wird. Ihr findet also hier einen ganzen Wust von Funktionen, der zum Betrieb der Kamera nicht benötigt wird. Vielleicht könnt Ihr das eine oder andere aber brauchen...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
{******************************************************************}&lt;br /&gt;
(*&lt;br /&gt;
  Released as part of the camera example program&lt;br /&gt;
  Visit us @ http://www.delphigl.com&lt;br /&gt;
  Maintained by Florian Sievert (Phobeus)&lt;br /&gt;
  Phobeus@DelphiGL.com&lt;br /&gt;
-------------------------------------------------------------------&lt;br /&gt;
  License&lt;br /&gt;
  -------&lt;br /&gt;
  Copyright (C) 2007 Andree Heyroth&lt;br /&gt;
&lt;br /&gt;
  This license applies to everything on www.delphigl.com, except where&lt;br /&gt;
  otherwise noted.&lt;br /&gt;
&lt;br /&gt;
  This software is provided 'as-is', without any express or implied warranty.&lt;br /&gt;
  In no event will the authors be held liable for any damages arising from&lt;br /&gt;
  the use of this software.&lt;br /&gt;
&lt;br /&gt;
  Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
  including commercial applications, and to alter it and redistribute it&lt;br /&gt;
  freely, subject to the following restrictions:&lt;br /&gt;
&lt;br /&gt;
  1. The origin of this software must not be misrepresented; you must not&lt;br /&gt;
     claim that you wrote the original software. If you use this software in a&lt;br /&gt;
     product, an acknowledgment in the product documentation would be&lt;br /&gt;
     appreciated but is not required.&lt;br /&gt;
  2. Altered source versions must be plainly marked as such, and must not be&lt;br /&gt;
     misrepresented as being the original software.&lt;br /&gt;
  3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
&lt;br /&gt;
  Description&lt;br /&gt;
  -----------&lt;br /&gt;
  Include file which contains common functions to perform OpenGL specific tasks&lt;br /&gt;
  like rotating a point around a specific axis or invert matrices or calculate&lt;br /&gt;
  a vectors normal or calculate a cross product or ...&lt;br /&gt;
&lt;br /&gt;
  Requirements&lt;br /&gt;
  ------------&lt;br /&gt;
  - SDL 1.2 (http://www.libsdl.org/download-1.2.php or your distribution)&lt;br /&gt;
  - Borland Delphi version 5.0 and above&lt;br /&gt;
&lt;br /&gt;
  History&lt;br /&gt;
  -------&lt;br /&gt;
  -&lt;br /&gt;
&lt;br /&gt;
  Contact&lt;br /&gt;
  -------&lt;br /&gt;
  I created this source code in my spare time. If you find a bug or just&lt;br /&gt;
  wanna say hello, feel free to write to the contributor:&lt;br /&gt;
&lt;br /&gt;
    Andree Heyroth (AndyH)&lt;br /&gt;
    email : heyroth@syncro-concept.de&lt;br /&gt;
    Visit: http://www.delphigl.com&lt;br /&gt;
&lt;br /&gt;
*******************************************************************************)&lt;br /&gt;
unit Util;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses DglOpenGL, Math, Windows, Graphics, SysUtils, Dialogs{, glBmp};&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TProjection=(Frustum, Orthographic, Perspective);&lt;br /&gt;
&lt;br /&gt;
  TGLPlace=packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TScale=packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLPosition=packed record&lt;br /&gt;
    X,Y,Z,W: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TPosition = packed record&lt;br /&gt;
    X,Y,Z,W: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLVector = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
  TPGLvector=^TGLvector;&lt;br /&gt;
&lt;br /&gt;
  TTextureCoord=record&lt;br /&gt;
    X, Y, Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TTextureCoordArray = array of TTextureCoord;&lt;br /&gt;
  TGLvectorArray = array of TGLvector;&lt;br /&gt;
  TGLdoubleArray = array of GLdouble;&lt;br /&gt;
  TGLfloatArray = array of GLfloat;&lt;br /&gt;
&lt;br /&gt;
  TGKVector = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TAngle = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLColor=record&lt;br /&gt;
    red,green,blue,alpha: GLclampf;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TRotation = packed record&lt;br /&gt;
    angle, x, y, z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TTextureInfo = packed record&lt;br /&gt;
    BitmapName: string;&lt;br /&gt;
    TextureNum: GLUint;&lt;br /&gt;
    //theBmp: TGLbmp;&lt;br /&gt;
  end;&lt;br /&gt;
  TTextureList = array of TTextureInfo;&lt;br /&gt;
&lt;br /&gt;
  TMatrix = array [0..3,0..3] of GLdouble;&lt;br /&gt;
  TArrMatrix = array [0..15] of GLdouble;&lt;br /&gt;
  TFrustum = array [0..5,0..3] of GLdouble;&lt;br /&gt;
  TArrVector = array [0..3] of GLdouble;&lt;br /&gt;
&lt;br /&gt;
  function GetMatrixX (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixY (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixZ (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixPos (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  procedure SetMatrixX (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixY (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixZ (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixPos (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  function Multiply (Color: TGLcolor; m: GLdouble): TGLcolor;overload;&lt;br /&gt;
  function Multiply (V1, V2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function Multiply (M1, M2: TArrMatrix): TArrMatrix;overload;&lt;br /&gt;
  function Divide (V1, V2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function Divide (V1: TGLVector; d: GLdouble): TGLVector;overload;&lt;br /&gt;
  function MakeVector(X,Y,Z:GLdouble):TArrVector;overload;&lt;br /&gt;
  function MakeVector(X,Y,Z,W:GLdouble):TArrVector;overload;&lt;br /&gt;
  function Normalize(aVector:TArrVector):TArrVector;overload;&lt;br /&gt;
  function Normalize(aVector:TGLVector):TGLVector;overload;&lt;br /&gt;
  function GetIdentity(Matrix:TMatrix):TMatrix;overload;&lt;br /&gt;
  function GetIdentity(Matrix:TArrMatrix):TArrMatrix;overload;&lt;br /&gt;
  function MatrixTranspose(const M:TMatrix):TMatrix;register;&lt;br /&gt;
  function NearestPoint(Axis, Point: TGLVector): TGLVector;&lt;br /&gt;
  function VectorRotateX(v:TArrVector;a:GLdouble):TArrVector;overload;&lt;br /&gt;
  function VectorRotateY(v:TArrVector;a:GLdouble):TArrVector;overload;&lt;br /&gt;
  function VectorRotateZ(v:TArrVector;a:GLdouble):TArrVector;overload;&lt;br /&gt;
  function VectorRotateX(v:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateX(v,c:TGLvector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v,c:TGLvector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v,c:TGLvector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateX(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
&lt;br /&gt;
  function AxisXRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
  function AxisYRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
  function AxisZRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
&lt;br /&gt;
  function GL2GKVector (V: TGLVector): TGKVector;&lt;br /&gt;
  function GK2GLVector (V: TGKVector): TGLVector;&lt;br /&gt;
  function GL2WinColor (GLcol: TGLcolor): TColor;&lt;br /&gt;
  function Win2GLColor (WinCol: Tcolor): TGLcolor;&lt;br /&gt;
  function CalcNormale (V1, V2, V3: TGLVector): TGLVector;&lt;br /&gt;
  function CrossProduct(V1, V2: TGLVector): TGLVector;&lt;br /&gt;
  function DotProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
  function LoadTexture(Filename: String; var Texture: GLuint): Boolean;&lt;br /&gt;
  function Magnitude(V1: TGLVector): GLdouble;overload;&lt;br /&gt;
  function Magnitude(X, Y: GLdouble): GLdouble;overload;&lt;br /&gt;
  function ScalarProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
  function MinVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
  function MaxVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
  function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function SubtractVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;overload;&lt;br /&gt;
  function AddVector (Vec1, Vec2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function AddVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;overload;&lt;br /&gt;
  function ForceForegroundWindow(hwnd: THandle): Boolean;&lt;br /&gt;
  function ValidTexture (tex: GLUint; ErrStr: string): boolean;&lt;br /&gt;
  procedure ResetGLErrorFlags;&lt;br /&gt;
  procedure InitGLEnv (dc: HDC; rc: HGLRC; hndl: THandle);// pixelformat setzen&lt;br /&gt;
  procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);&lt;br /&gt;
  procedure InitVector (var V1: TGLVector; x, y, z: GLdouble);overload;&lt;br /&gt;
  procedure InitVector (var V1: TGKVector; x, y, z: GLdouble);overload;&lt;br /&gt;
  procedure InitVector (var V1: TArrVector; x, y, z: GLdouble);overload;&lt;br /&gt;
  procedure InitScale (var S1: TScale; x, y, z: GLdouble);&lt;br /&gt;
  procedure LoadBitmap(Filename: String;&lt;br /&gt;
                       out Width: Cardinal;&lt;br /&gt;
                       out Height: Cardinal;&lt;br /&gt;
                       out pData: Pointer);&lt;br /&gt;
  procedure GetRotation (V1, V2: TGLVector;&lt;br /&gt;
                         var Rotation: TRotation);&lt;br /&gt;
  function MakeTextureFromBitmap (Bitmap: string;&lt;br /&gt;
                                  var BitmapList: TTextureList): GLenum;&lt;br /&gt;
  procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);&lt;br /&gt;
  procedure DisableTexture;&lt;br /&gt;
  function TextToGLVector (VTxt: string): TGLVector;&lt;br /&gt;
  function TextToGKVector (VTxt: string): TGKVector;&lt;br /&gt;
  function GKVectorToText (V1: TGKVector): string;overload;&lt;br /&gt;
  function GKVectorToText (V1: TGKVector; digits, decimals: byte): string;overload;&lt;br /&gt;
  function GLVectorToText (V1: TGLVector): string;overload;&lt;br /&gt;
  function GLVectorToText (V1: TGLVector; digits, decimals: byte): string;overload;&lt;br /&gt;
  function MatrixToText (M: TArrMatrix): string;&lt;br /&gt;
  function CheckFormat (number: string; digits, decimals: byte): string;&lt;br /&gt;
  function MyCone (Start, Ende: TGLVector;&lt;br /&gt;
                   RadiusStart, RadiusEnde: GLdouble;&lt;br /&gt;
                   Slices: integer; TileX, TileY: GLdouble): boolean;&lt;br /&gt;
  function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;&lt;br /&gt;
  function ExePath: string;&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  C_X = 0;&lt;br /&gt;
  C_Y = 1;&lt;br /&gt;
  C_Z = 2;&lt;br /&gt;
  C_W = 3;&lt;br /&gt;
  C_EPS:GLdouble=0.01;&lt;br /&gt;
  C_DEGTORAD:GLdouble=3.1412/180;&lt;br /&gt;
  C_RADTODEG:GLdouble=180/3.1412;&lt;br /&gt;
  C_LAMBDA_INCREMENT:GLdouble=0.01;&lt;br /&gt;
  C_PI=3.1415926535;&lt;br /&gt;
  C_PI_DIV_180=C_PI/180;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses Forms, {KanalUtil,} OGLinclude, Controls;&lt;br /&gt;
&lt;br /&gt;
function MyPower (Base: extended; Exp: integer): extended;&lt;br /&gt;
//var&lt;br /&gt;
//  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
//  result := Base;&lt;br /&gt;
//  for i := 2 to Exp do&lt;br /&gt;
//    result := result * Base;&lt;br /&gt;
&lt;br /&gt;
  result := Base * Base;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);&lt;br /&gt;
begin&lt;br /&gt;
  ToVektor.X := FromVektor.X;&lt;br /&gt;
  ToVektor.Y := FromVektor.Y;&lt;br /&gt;
  ToVektor.Z := FromVektor.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixX (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den X-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[00];&lt;br /&gt;
  result.Y := matrix[01];&lt;br /&gt;
  result.Z := matrix[02];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixY (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Y-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[04];&lt;br /&gt;
  result.Y := matrix[05];&lt;br /&gt;
  result.Z := matrix[06];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixZ (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Z-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[08];&lt;br /&gt;
  result.Y := matrix[09];&lt;br /&gt;
  result.Z := matrix[10];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixPos (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Position-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[12];&lt;br /&gt;
  result.Y := matrix[13];&lt;br /&gt;
  result.Z := matrix[14];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixX (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten X-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[00] := v.X;&lt;br /&gt;
  matrix[01] := v.Y;&lt;br /&gt;
  matrix[02] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixY (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Y-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[04] := v.X;&lt;br /&gt;
  matrix[05] := v.Y;&lt;br /&gt;
  matrix[06] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixZ (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Z-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[08] := v.X;&lt;br /&gt;
  matrix[09] := v.Y;&lt;br /&gt;
  matrix[10] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixPos (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Position-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[12] := v.X;&lt;br /&gt;
  matrix[13] := v.Y;&lt;br /&gt;
  matrix[14] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MinVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
// gibt den Vector mit der geringeren Länge zurück&lt;br /&gt;
begin&lt;br /&gt;
  result := V1;&lt;br /&gt;
  if Magnitude (V1) &amp;gt; Magnitude (V2) then&lt;br /&gt;
    result := V2;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MaxVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
// gibt den Vector mit der größeren Länge zurück&lt;br /&gt;
begin&lt;br /&gt;
  result := V1;&lt;br /&gt;
  if Magnitude (V1) &amp;lt; Magnitude (V2) then&lt;br /&gt;
    result := V2;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;&lt;br /&gt;
// subtrahiert Vec2 von vec1 und gibt das ergebnis in vec3 zurück&lt;br /&gt;
var&lt;br /&gt;
  Vec3: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  Vec3 .X := Vec1.X - Vec2.X;&lt;br /&gt;
  Vec3 .Y := Vec1.Y - Vec2.Y;&lt;br /&gt;
  Vec3 .Z := Vec1.Z - Vec2.Z;&lt;br /&gt;
  result := Vec3;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SubtractVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;&lt;br /&gt;
// subtrahiert X, Y, Z von vec.x, vec.y, vec.z  und gibt das&lt;br /&gt;
// ergebnis zurück&lt;br /&gt;
begin&lt;br /&gt;
  Vec .X := Vec.X - X;&lt;br /&gt;
  Vec .Y := Vec.Y - Y;&lt;br /&gt;
  Vec .Z := Vec.Z - Z;&lt;br /&gt;
  result := Vec;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AddVector (Vec1, Vec2: TGLVector): TGLVector;&lt;br /&gt;
// addiert Vec2 auf vec1 und gibt das ergebnis in vec3 zurück&lt;br /&gt;
var&lt;br /&gt;
  Vec3: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  Vec3 .X := Vec1.X + Vec2.X;&lt;br /&gt;
  Vec3 .Y := Vec1.Y + Vec2.Y;&lt;br /&gt;
  Vec3 .Z := Vec1.Z + Vec2.Z;&lt;br /&gt;
  result := Vec3;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AddVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;&lt;br /&gt;
// addiert X, Y, Z auf vec.x, vec.y, vec.z  und gibt das&lt;br /&gt;
// ergebnis zurück&lt;br /&gt;
begin&lt;br /&gt;
  Vec .X := Vec.X + X;&lt;br /&gt;
  Vec .Y := Vec.Y + Y;&lt;br /&gt;
  Vec .Z := Vec.Z + Z;&lt;br /&gt;
  result := Vec;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Magnitude(V1: TGLVector): GLdouble;&lt;br /&gt;
var&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // gibt die länge des vektors im dreidimensionalen raum zurück&lt;br /&gt;
  Ergebnis := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);&lt;br /&gt;
  try&lt;br /&gt;
    result := sqrt(Ergebnis);&lt;br /&gt;
  except&lt;br /&gt;
    result := 0;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Magnitude(X, Y: GLdouble): GLdouble;&lt;br /&gt;
var&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // gibt die länge des vektors im zweidimensionalen raum zurück&lt;br /&gt;
  Ergebnis := MyPower(X,2)+MyPower(Y,2);&lt;br /&gt;
  try&lt;br /&gt;
    result := sqrt(Ergebnis);&lt;br /&gt;
  except&lt;br /&gt;
    result := 0;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function DotProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
// errechnet den winkel zwischen zwei vektoren&lt;br /&gt;
var&lt;br /&gt;
  len1, len2: GLdouble;&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  //len1 := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);&lt;br /&gt;
  //len2 := MyPower(V2.X,2)+MyPower(V2.Y,2)+MyPower(V2.Z,2);&lt;br /&gt;
  len1 := Magnitude (V1);&lt;br /&gt;
  len2 := Magnitude (V2);&lt;br /&gt;
  Ergebnis := ScalarProduct (V1, V2);&lt;br /&gt;
  Ergebnis := arccos (Ergebnis / (len1 * len2));&lt;br /&gt;
  result := radtodeg (Ergebnis) * 2.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function CrossProduct(V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  CrossVec: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
	//CrossVec.X := +((V1.Y*V2.Z) - (V1.Z*V2.Y));&lt;br /&gt;
	//CrossVec.Y := -((V1.X*V2.Z) - (V1.Z*V2.X));&lt;br /&gt;
	//CrossVec.Z := +((V1.X*V2.Y) - (V1.Y*V2.X));&lt;br /&gt;
	CrossVec.X := ((V1.Y*V2.Z) - (V1.Z*V2.Y));&lt;br /&gt;
	CrossVec.Y := ((V1.Z*V2.X) - (V1.X*V2.Z));&lt;br /&gt;
	CrossVec.Z := ((V1.X*V2.Y) - (V1.Y*V2.X));&lt;br /&gt;
  result := CrossVec;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
function CalcNormale (V1, V2, V3: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  Kreuz: TGLvector;&lt;br /&gt;
  V1V2, V1V3: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zum testen:&lt;br /&gt;
  InitVector (result, 0, 0, 0);&lt;br /&gt;
  // gibt die normale von 3 vektoren zurück (die senkrechte auf die&lt;br /&gt;
  // durch die drei vektoren gebildete ebene)&lt;br /&gt;
  V1V2 := SubtractVector (V2, V1);&lt;br /&gt;
  V1V3 := SubtractVector (V3, V1);&lt;br /&gt;
&lt;br /&gt;
  Kreuz := CrossProduct (V1V2, V1V3);&lt;br /&gt;
&lt;br /&gt;
  result := Normalize (Kreuz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TGLVector; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1.x := x;&lt;br /&gt;
  V1.y := y;&lt;br /&gt;
  V1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TGKVector; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1.x := x;&lt;br /&gt;
  V1.y := y;&lt;br /&gt;
  V1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TArrVector; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1[C_X] := x;&lt;br /&gt;
  V1[C_Y] := y;&lt;br /&gt;
  V1[C_Z] := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitScale (var S1: TScale; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  S1.x := x;&lt;br /&gt;
  S1.y := y;&lt;br /&gt;
  S1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Multiply (V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
// zwei vektoren miteinander multiplizieren&lt;br /&gt;
  ret.X := V1.X * V2.X;&lt;br /&gt;
  ret.Y := V1.Y * V2.Y;&lt;br /&gt;
  ret.Z := V1.Z * V2.Z;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Divide (V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
// zwei vektoren miteinander multiplizieren&lt;br /&gt;
  ret.X := V1.X / V2.X;&lt;br /&gt;
  ret.Y := V1.Y / V2.Y;&lt;br /&gt;
  ret.Z := V1.Z / V2.Z;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ScalarProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
// die summe der potenzen der einzelnen achsen von zwei vektoren errechnen&lt;br /&gt;
  result := (V1.X*V2.X +&lt;br /&gt;
             V1.Y*V2.Y +&lt;br /&gt;
             V1.Z*V2.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LoadTexture(Filename: String; var Texture: GLuint): Boolean;&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_LoadUnable = 'Unable to load ';&lt;br /&gt;
  Res_LoadingTex = 'Loading Textures';&lt;br /&gt;
var&lt;br /&gt;
  pData: Pointer;&lt;br /&gt;
  Width: Cardinal;&lt;br /&gt;
  Height: Cardinal;&lt;br /&gt;
  newTexture: GLint;&lt;br /&gt;
begin&lt;br /&gt;
  pData :=nil;&lt;br /&gt;
  LoadBitmap(Filename, Width, Height, pData);&lt;br /&gt;
&lt;br /&gt;
  if (Assigned(pData)) then&lt;br /&gt;
    Result := True&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    Result := False;&lt;br /&gt;
    MessageBox(0, PChar(Res_LoadUnable + filename),&lt;br /&gt;
               pchar (Res_LoadingTex), MB_OK);&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  glGenTextures(1, @NewTexture);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, NewTexture);&lt;br /&gt;
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}&lt;br /&gt;
&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }&lt;br /&gt;
&lt;br /&gt;
  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);&lt;br /&gt;
&lt;br /&gt;
  Texture := newTexture;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure LoadBitmap(Filename: String;&lt;br /&gt;
                     out Width: Cardinal;&lt;br /&gt;
                     out Height: Cardinal;&lt;br /&gt;
                     out pData: Pointer);&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_ReadErr = 'Error reading palette';&lt;br /&gt;
  Res_OpenErr = 'Error opening: ';&lt;br /&gt;
  Res_BitmapDataErr = 'Error reading bitmap data';&lt;br /&gt;
  Res_BmpUnit = 'BMP Unit';&lt;br /&gt;
var&lt;br /&gt;
  FileHeader: BITMAPFILEHEADER;&lt;br /&gt;
  InfoHeader: BITMAPINFOHEADER;&lt;br /&gt;
  Palette: array of RGBQUAD;&lt;br /&gt;
  BitmapFile: THandle;&lt;br /&gt;
  BitmapLength: Cardinal;&lt;br /&gt;
  PaletteLength: Cardinal;&lt;br /&gt;
  ReadBytes: Cardinal;&lt;br /&gt;
  Front: ^Byte;&lt;br /&gt;
  Back: ^Byte;&lt;br /&gt;
  Temp: Byte;&lt;br /&gt;
  I : Cardinal;&lt;br /&gt;
begin&lt;br /&gt;
  BitmapFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);&lt;br /&gt;
  if (BitmapFile = INVALID_HANDLE_VALUE) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_OpenErr+Filename), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // Get header information&lt;br /&gt;
  ReadFile(BitmapFile, FileHeader, SizeOf(FileHeader), ReadBytes, nil);&lt;br /&gt;
  ReadFile(BitmapFile, InfoHeader, SizeOf(InfoHeader), ReadBytes, nil);&lt;br /&gt;
&lt;br /&gt;
  // Get palette&lt;br /&gt;
  PaletteLength := InfoHeader.biClrUsed;&lt;br /&gt;
  SetLength(Palette, PaletteLength);&lt;br /&gt;
  ReadFile(BitmapFile, Palette, PaletteLength, ReadBytes, nil);&lt;br /&gt;
  if (ReadBytes &amp;lt;&amp;gt; PaletteLength) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_ReadErr), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    CloseHandle(BitmapFile);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  Width := InfoHeader.biWidth;&lt;br /&gt;
  Height := InfoHeader.biHeight;&lt;br /&gt;
  BitmapLength := InfoHeader.biSizeImage;&lt;br /&gt;
  if BitmapLength = 0 then&lt;br /&gt;
    BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;&lt;br /&gt;
&lt;br /&gt;
  // Get the actual pixel data&lt;br /&gt;
  GetMem(pData, BitmapLength);&lt;br /&gt;
  ReadFile(BitmapFile, pData^, BitmapLength, ReadBytes, nil);&lt;br /&gt;
  if (ReadBytes &amp;lt;&amp;gt; BitmapLength) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_BitmapDataErr), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    CloseHandle(BitmapFile);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
  CloseHandle(BitmapFile);&lt;br /&gt;
&lt;br /&gt;
  // Bitmaps are stored BGR and not RGB, so swap the R and B bytes.&lt;br /&gt;
  for I :=0 to Width * Height - 1 do&lt;br /&gt;
  begin&lt;br /&gt;
    Front := Pointer(Cardinal(pData) + I*3);&lt;br /&gt;
    Back := Pointer(Cardinal(pData) + I*3 + 2);&lt;br /&gt;
    Temp := Front^;&lt;br /&gt;
    Front^ := Back^;&lt;br /&gt;
    Back^ := Temp;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GK2GLVector (V: TGKVector): TGLVector;&lt;br /&gt;
// ändert Gauss-Krüger Koordinaten in OpenGL Koordinaten um&lt;br /&gt;
begin&lt;br /&gt;
  result.X := V.X;&lt;br /&gt;
  result.Y := V.Z;&lt;br /&gt;
  result.Z := V.Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GL2GKVector (V: TGLVector): TGKVector;&lt;br /&gt;
// ändert OpenGL Koordinaten in Gauss-Krüger Koordinaten um&lt;br /&gt;
begin&lt;br /&gt;
  result.X := V.X;&lt;br /&gt;
  result.Y := V.Z;&lt;br /&gt;
  result.Z := V.Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Win2GLColor (WinCol: TColor): TGLcolor;&lt;br /&gt;
begin&lt;br /&gt;
  result.Red := GetRValue (WinCol) / 255;&lt;br /&gt;
  result.Green := GetGValue (WinCol) / 255;&lt;br /&gt;
  result.Blue := GetBValue (WinCol) / 255;&lt;br /&gt;
  result.Alpha := 0.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GL2WinColor (GLcol: TGLcolor): TColor;&lt;br /&gt;
begin&lt;br /&gt;
  result := Rgb (StrToInt (FloatToStr (int (GLcol.Red * 255))),&lt;br /&gt;
                 StrToInt (FloatToStr (int (GLcol.Green * 255))),&lt;br /&gt;
                 StrToInt (FloatToStr (int (GLcol.Blue * 255))));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure GetRotation (V1, V2: TGLVector;&lt;br /&gt;
                       var Rotation: TRotation);&lt;br /&gt;
var&lt;br /&gt;
  tmpCyl, tmpZiel, nullVec: TGLVector;&lt;br /&gt;
  normale, ResultLen: TGLVector;&lt;br /&gt;
  VectorLength: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // temporäre vektoren initialisieren&lt;br /&gt;
  InitVector (nullVec, 0,0,0);&lt;br /&gt;
  InitVector (tmpCyl, 0,0,0);&lt;br /&gt;
&lt;br /&gt;
  // länge des zu drehenden objekts ermitteln&lt;br /&gt;
  ResultLen := SubtractVector (V2, V1);&lt;br /&gt;
  VectorLength := Magnitude (ResultLen);&lt;br /&gt;
&lt;br /&gt;
  // vektoren zur bildung der dreiecksfläche bilden.&lt;br /&gt;
  // die schenkel schneiden sich im nullpunkt&lt;br /&gt;
  // der Cylinder läuft immer entlang der Z-Achse&lt;br /&gt;
  tmpCyl.Z := VectorLength;&lt;br /&gt;
  tmpZiel := SubtractVector (V2, V1);&lt;br /&gt;
  tmpZiel.Z := tmpZiel.Z + VectorLength;&lt;br /&gt;
&lt;br /&gt;
  // senkrechte zu den beiden vektoren bilden&lt;br /&gt;
  // (um diese achse soll nachher gedreht werden)&lt;br /&gt;
  // drehachse für späteren gebrauch speichern&lt;br /&gt;
  normale := CalcNormale (tmpCyl, tmpZiel, nullVec);&lt;br /&gt;
&lt;br /&gt;
  // um &amp;quot;Angle&amp;quot; Grad soll nachher gedreht werden&lt;br /&gt;
  Rotation.Angle := DotProduct(tmpCyl, tmpZiel);&lt;br /&gt;
  Rotation.X     := normale.X;&lt;br /&gt;
  Rotation.Y     := normale.Y;&lt;br /&gt;
  Rotation.Z     := normale.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeTextureFromBitmap (Bitmap: string;&lt;br /&gt;
                                var BitmapList: TTextureList): GLenum;&lt;br /&gt;
// die funktion lädt die in Bitmap übergebene Grafik und gibt die Textturnummer&lt;br /&gt;
// zurück. ist das bitmap schon im array BitmapList enthalten, wird die bereits&lt;br /&gt;
// vergeben nummer zurückgegeben.&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_TextureNotFound = 'Texturdatei nicht gefunden: ';&lt;br /&gt;
  Res_Error = 'Error';&lt;br /&gt;
var&lt;br /&gt;
  i, Laenge: integer;&lt;br /&gt;
begin&lt;br /&gt;
  result := 0;&lt;br /&gt;
  if length (trim (Bitmap)) = 0 then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  BitMap := uppercase (BitMap);  // wegen dem folgenden vergleich&lt;br /&gt;
&lt;br /&gt;
  // suchen, ob die textur schon geladen wurde&lt;br /&gt;
  Laenge := length (BitmapList);&lt;br /&gt;
  if Laenge &amp;gt; 0 then&lt;br /&gt;
    for i := low (BitMapList) to high (BitMapList) do&lt;br /&gt;
    begin&lt;br /&gt;
      if (BitmapList[i].BitmapName = Bitmap) and&lt;br /&gt;
         //(glIsTexture (BitmapList[i].TextureNum)) then&lt;br /&gt;
         (BitmapList[i].TextureNum &amp;gt; 0) then&lt;br /&gt;
        result := BitmapList[i].TextureNum;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
  if result = 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    if not fileexists (Bitmap) then&lt;br /&gt;
    begin&lt;br /&gt;
      MessageBox (0, PChar (Res_TextureNotFound+Bitmap),&lt;br /&gt;
                  pchar (Res_Error), MB_OK or MB_ICONERROR);&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if (result = 0) then&lt;br /&gt;
  begin&lt;br /&gt;
    setlength (BitmapList, Laenge+1);&lt;br /&gt;
    BitmapList[Laenge].BitmapName := Bitmap;&lt;br /&gt;
    BitmapList[Laenge].TextureNum := 0;&lt;br /&gt;
    {&lt;br /&gt;
    BitMapList[Laenge].theBmp := TglBmp.Create;&lt;br /&gt;
    if BitMapList[Laenge].theBmp.LoadImage (BitMap) then&lt;br /&gt;
    begin&lt;br /&gt;
      BitMapList[Laenge].theBmp.SetTextureWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);&lt;br /&gt;
      BitMapList[Laenge].theBmp.GenTexture (false, false);&lt;br /&gt;
      result := BitmapList[Laenge].theBmp.TextureID;&lt;br /&gt;
      BitmapList[Laenge].TextureNum := BitmapList[Laenge].theBmp.TextureID;&lt;br /&gt;
    end;&lt;br /&gt;
    }&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);&lt;br /&gt;
begin&lt;br /&gt;
  glEnable(GL_TEXTURE_2D);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, Texture);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);&lt;br /&gt;
  if TextureTiled then&lt;br /&gt;
  begin&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure DisableTexture;&lt;br /&gt;
begin&lt;br /&gt;
  glDisable(GL_TEXTURE_2D);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TextToGLVector (VTxt: string): TGLVector;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  posi: integer;&lt;br /&gt;
  V1: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (V1,0,0,0);&lt;br /&gt;
  posi := pos (subdelim, VTxt);&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.X := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
    posi := pos (subdelim, VTxt);&lt;br /&gt;
  end;&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.Y := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
  end;&lt;br /&gt;
  if length (VTxt) &amp;gt; 0 then V1.Z := StrToFloat (VTxt);&lt;br /&gt;
&lt;br /&gt;
  result := V1;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TextToGKVector (VTxt: string): TGKVector;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  posi: integer;&lt;br /&gt;
  V1: TGKVector;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (V1,0,0,0);&lt;br /&gt;
  posi := pos (subdelim, VTxt);&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.X := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
    posi := pos (subdelim, VTxt);&lt;br /&gt;
  end;&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.Y := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
  end;&lt;br /&gt;
  if length (VTxt) &amp;gt; 0 then V1.Z := StrToFloat (VTxt);&lt;br /&gt;
&lt;br /&gt;
  result := V1;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GKVectorToText (V1: TGKVector): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := FloatToStr (V1.X) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Y) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Z);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GKVectorToText (V1: TGKVector; digits, decimals: byte): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt, frmt, sX, sY, sZ: string;&lt;br /&gt;
begin&lt;br /&gt;
  {&lt;br /&gt;
  VTxt := Format('%*.*f', [digits, decimals, V1.X]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Y]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Z]);&lt;br /&gt;
  }&lt;br /&gt;
  frmt := '%'+IntToStr(digits)+'.'+IntToStr(decimals)+'f';&lt;br /&gt;
&lt;br /&gt;
  sX   := Format(frmt, [V1.X]);&lt;br /&gt;
  sY   := Format(frmt, [V1.Y]);&lt;br /&gt;
  sZ   := Format(frmt, [V1.Z]);&lt;br /&gt;
  //sX   := FloatToStrF(V1.X, fffixed, digits, decimals);&lt;br /&gt;
  //sY   := FloatToStrF(V1.Y, fffixed, digits, decimals);&lt;br /&gt;
  //sZ   := FloatToStrF(V1.Z, fffixed, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
  sX   := trim (sX);&lt;br /&gt;
  sY   := trim (sY);&lt;br /&gt;
  sZ   := trim (sZ);&lt;br /&gt;
&lt;br /&gt;
  sX := CheckFormat (sX, digits, decimals);&lt;br /&gt;
  sY := CheckFormat (sY, digits, decimals);&lt;br /&gt;
  sZ := CheckFormat (sZ, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
  VTxt := sX + subdelim + sY + subdelim + sZ;&lt;br /&gt;
&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GLVectorToText (V1: TGLVector): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := FloatToStr (V1.X) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Y) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Z);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GLVectorToText (V1: TGLVector; digits, decimals: byte): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt, frmt, sX, sY, sZ: string;&lt;br /&gt;
begin&lt;br /&gt;
  {&lt;br /&gt;
  VTxt := Format('%*.*f', [digits, decimals, V1.X]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Y]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Z]);&lt;br /&gt;
  }&lt;br /&gt;
  frmt := '%'+IntToStr(digits)+'.'+IntToStr(decimals)+'f';&lt;br /&gt;
&lt;br /&gt;
  sX   := Format(frmt, [V1.X]);&lt;br /&gt;
  sY   := Format(frmt, [V1.Y]);&lt;br /&gt;
  sZ   := Format(frmt, [V1.Z]);&lt;br /&gt;
  //sX   := FloatToStrF(V1.X, fffixed, digits, decimals);&lt;br /&gt;
  //sY   := FloatToStrF(V1.Y, fffixed, digits, decimals);&lt;br /&gt;
  //sZ   := FloatToStrF(V1.Z, fffixed, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  sX   := trim (sX);&lt;br /&gt;
  sY   := trim (sY);&lt;br /&gt;
  sZ   := trim (sZ);&lt;br /&gt;
&lt;br /&gt;
  sX := CheckFormat (sX, digits, decimals);&lt;br /&gt;
  sY := CheckFormat (sY, digits, decimals);&lt;br /&gt;
  sZ := CheckFormat (sZ, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
  VTxt := sX + subdelim + sY + subdelim + sZ;&lt;br /&gt;
&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MatrixToText (M: TArrMatrix): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := '';&lt;br /&gt;
  for i := low (M) to high(M) do&lt;br /&gt;
  begin&lt;br /&gt;
    VTxt := VTxt + Format('%14.6f', [M[i]]);&lt;br /&gt;
    if i &amp;lt; high (M) then&lt;br /&gt;
      VTxt := VTxt + subdelim;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MyCone (Start, Ende: TGLVector;&lt;br /&gt;
                 RadiusStart, RadiusEnde: GLdouble;&lt;br /&gt;
                 Slices: integer; TileX, TileY: GLdouble): boolean;&lt;br /&gt;
var&lt;br /&gt;
  Slice: Integer;&lt;br /&gt;
  Laenge, xdelta, zdelta: GLdouble;&lt;br /&gt;
  V1, V2, V3, V4: TGLvector;&lt;br /&gt;
  A, B: double;&lt;br /&gt;
  //tmpVec: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  result := true;&lt;br /&gt;
&lt;br /&gt;
  // laenge des kegels berechnen&lt;br /&gt;
  // hierbei wird davon ausgegangen, dass der kegel senkrecht steht&lt;br /&gt;
  Laenge := Ende.y - Start.y;&lt;br /&gt;
&lt;br /&gt;
  // die folgende längenberechnung stimmt nicht mit der senkrechten&lt;br /&gt;
  // verbindungslinie der beiden konusebenen überein, wenn die radien&lt;br /&gt;
  // sich unterscheiden, da sich dann ein schiefer vektor ergibt. der&lt;br /&gt;
  // ist natürlich länger als die senkrechte.&lt;br /&gt;
  //tmpVec := SubtractVector (Start, Ende);&lt;br /&gt;
  //Laenge := Magnitude (tmpVec);&lt;br /&gt;
&lt;br /&gt;
  // radiusdifferenz der oberen und unteren ebene des konus berechnen&lt;br /&gt;
  xdelta := Start.x - Ende.x;&lt;br /&gt;
  zdelta := Start.z - Ende.z;&lt;br /&gt;
  xdelta := -xdelta;&lt;br /&gt;
  //zdelta := zdelta;&lt;br /&gt;
&lt;br /&gt;
  glBegin (GL_TRIANGLE_STRIP);&lt;br /&gt;
  // der kegel wird entlang der z-achse gezeichnet&lt;br /&gt;
  V1.z := 0;&lt;br /&gt;
  V2.z := 0;&lt;br /&gt;
  V3.z := Laenge;&lt;br /&gt;
  V4.z := Laenge;&lt;br /&gt;
  // immer ein dreieck an das andere: mit zwei punkten des oberen&lt;br /&gt;
  // radius und einem des unteren bzw. einem des oberen und zwei des&lt;br /&gt;
  // unteren ein dreieck zeichnen. mit dem nächsten neu errechneten punkt&lt;br /&gt;
  // und den zwei vorhergehenden haben wir immer das nächste dreieck.&lt;br /&gt;
  // so viele dreiecke wie pizzastücke (slices) gewünscht.&lt;br /&gt;
  for Slice := 1 to Slices do begin&lt;br /&gt;
    A := 2 * PI * Slice / Slices;&lt;br /&gt;
    B := 2 * PI * (Slice+1) / Slices;&lt;br /&gt;
    V1.x := sin(A)*RadiusStart;&lt;br /&gt;
    V1.y := cos(A)*RadiusStart;&lt;br /&gt;
    V2.x := sin(B)*RadiusStart;&lt;br /&gt;
    V2.y := cos(B)*RadiusStart;&lt;br /&gt;
    // umsetzung von y nach z-achse&lt;br /&gt;
    V3.x := (sin(B)*RadiusEnde)+xdelta;&lt;br /&gt;
    V3.y := (cos(B)*RadiusEnde)+zdelta;&lt;br /&gt;
    V4.x := (sin(A)*RadiusEnde)+xdelta;&lt;br /&gt;
    V4.y := (cos(A)*RadiusEnde)+zdelta;&lt;br /&gt;
    //Normale := CalcNormale (V1, V3, V2);&lt;br /&gt;
    //glNormal3fv(@Normale);&lt;br /&gt;
    if Slice = 1 then&lt;br /&gt;
    begin&lt;br /&gt;
      glTexCoord2d(1*TileX,0); glVertex3dv(@V1);&lt;br /&gt;
      glTexCoord2d(1*TileX,1*TileY); glVertex3dv(@V4);&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,0); glVertex3dv(@V2);&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,1*TileY); glVertex3dv(@V3);&lt;br /&gt;
    end&lt;br /&gt;
    else&lt;br /&gt;
    begin&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,0); glVertex3dv(@V2);&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,1*TileX); glVertex3dv(@V3);&lt;br /&gt;
    end;&lt;br /&gt;
    // so hatte ich mir das zuerst gedacht:&lt;br /&gt;
    // aktuellen und nächsten punkt des kreises (oben und unten)&lt;br /&gt;
    // nehmen und ein rechteck zeichnen. alle rechtecke zusammen sollten&lt;br /&gt;
    // einen geschlossenen kegel ergeben.&lt;br /&gt;
    //glBegin(GL_QUADS);&lt;br /&gt;
    //  glNormal3dv(@Normale);&lt;br /&gt;
    //  glTexCoord2d(0,0); glVertex3dv(@V2);&lt;br /&gt;
    //  glTexCoord2d(1,0); glVertex3dv(@V1);&lt;br /&gt;
    //  glTexCoord2d(1,1); glVertex3dv(@V4);&lt;br /&gt;
    //  glTexCoord2d(0,1); glVertex3dv(@V3);&lt;br /&gt;
    //glEnd;&lt;br /&gt;
  end;&lt;br /&gt;
  glEnd;  // (GL_TRIANGLE_STRIP)&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
{----------------------------- für TRUVCamera --------------------------------}&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
&lt;br /&gt;
function Multiply(M1, M2: TArrMatrix): TArrMatrix;&lt;br /&gt;
// multiplies two 4x4 matrices&lt;br /&gt;
var&lt;br /&gt;
  ret: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadMatrixd(@M1);&lt;br /&gt;
  glMultMatrixd(@M2);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX,@ret);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeVector(X,Y,Z:GLdouble):TArrVector;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=x;&lt;br /&gt;
  result[1]:=y;&lt;br /&gt;
  result[2]:=z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeVector(X,Y,Z,W:GLdouble):TArrVector;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=x;&lt;br /&gt;
  result[1]:=y;&lt;br /&gt;
  result[2]:=z;&lt;br /&gt;
  result[3]:=w;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Normalize(aVector:TArrVector):TArrVector;overload;&lt;br /&gt;
var&lt;br /&gt;
   d:double;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (result,1,1,1);&lt;br /&gt;
  d:=Sqrt(Sqr(aVector[C_X])+Sqr(aVector[C_Y])+Sqr(aVector[C_Z]));&lt;br /&gt;
  if d=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    //raise exception.Create('Zero length vector(Normalize 1)');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  result[C_X]:=aVector[C_X]/d;&lt;br /&gt;
  result[C_Y]:=aVector[C_Y]/d;&lt;br /&gt;
  result[C_Z]:=aVector[C_Z]/d;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Normalize(aVector:TGLVector):TGLVector;overload;&lt;br /&gt;
var&lt;br /&gt;
   d:double;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (result,1,1,1);&lt;br /&gt;
  d:=Sqrt(Sqr(aVector.X)+Sqr(aVector.Y)+Sqr(aVector.Z));&lt;br /&gt;
  if d=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    //raise exception.Create('Zero length vector(Normalize 2)');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  result.X:=aVector.X/d;&lt;br /&gt;
  result.Y:=aVector.Y/d;&lt;br /&gt;
  result.Z:=aVector.Z/d;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetIdentity(Matrix:TMatrix):TMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result[0,0]:=1.0;result[0,1]:=0.0;result[0,2]:=0.0;result[0,3]:=0.0;&lt;br /&gt;
  result[1,0]:=0.0;result[1,1]:=1.0;result[1,2]:=0.0;result[1,3]:=0.0;&lt;br /&gt;
  result[2,0]:=0.0;result[2,1]:=0.0;result[2,2]:=1.0;result[2,3]:=0.0;&lt;br /&gt;
  result[3,0]:=0.0;result[3,1]:=0.0;result[3,2]:=0.0;result[3,3]:=1.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetIdentity(Matrix:TArrMatrix):TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=1.0;result[1]:=0.0;result[2]:=0.0;result[3]:=0.0;&lt;br /&gt;
  result[4]:=0.0;result[5]:=1.0;result[6]:=0.0;result[7]:=0.0;&lt;br /&gt;
  result[8]:=0.0;result[9]:=0.0;result[10]:=1.0;result[11]:=0.0;&lt;br /&gt;
  result[12]:=0.0;result[13]:=0.0;result[14]:=0.0;result[15]:=1.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MatrixTranspose(const M:TMatrix):TMatrix;register;&lt;br /&gt;
var&lt;br /&gt;
   i,j:integer;&lt;br /&gt;
begin&lt;br /&gt;
     for i:=0 to 3 do&lt;br /&gt;
         for j:=0 to 3 do&lt;br /&gt;
             result[i,j]:=M[j,i];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v:TArrVector;a:GLdouble):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
   temp: TArrVector;&lt;br /&gt;
   sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
     temp[C_X] := v[C_x];&lt;br /&gt;
     temp[C_Y] := (v[C_Y] * cosine) + (v[C_Z] * -sine);&lt;br /&gt;
     temp[C_Z] := (v[C_Y] * sine) + (v[C_Z] * cosine);&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v: TArrVector;a:GLdouble):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp[C_x] := (v[C_x] * cosine) + (v[C_z] * sine);&lt;br /&gt;
  temp[C_y] := v[C_y];&lt;br /&gt;
  temp[C_z] := (v[C_x] * -sine) + (v[C_z] * cosine);&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v: TArrVector; a: GLdouble):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
  temp[C_x] := (v[C_x] * cosine) + (v[C_y] * -sine);&lt;br /&gt;
  temp[C_y] := (v[C_x] * sin(a)) + (v[C_y] * cosine);&lt;br /&gt;
  temp[C_z] := v[C_z];&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v:TGLVector;a:GLdouble):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp.X := v.x;&lt;br /&gt;
  temp.Y := (v.Y * cosine) + (v.Z * -sine);&lt;br /&gt;
  temp.Z := (v.Y * sine) + (v.Z * cosine);&lt;br /&gt;
&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v: TGLVector;a:GLdouble):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp.x := (v.x * cosine) + (v.z * sine);&lt;br /&gt;
  temp.y := v.y;&lt;br /&gt;
  temp.z := (v.X * -sine) + (v.z * cosine);&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v: TGLVector; a: GLdouble):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp.x := (v.x * cosine) + (v.y * -sine);&lt;br /&gt;
  temp.y := (v.x * sin(a)) + (v.y * cosine);&lt;br /&gt;
  temp.z := v.z;&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v,c: TGLvector;a: GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// c: zentrum&lt;br /&gt;
// a: winkel&lt;br /&gt;
var&lt;br /&gt;
  temp, temp2: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // das übergebene zentrum in den nullpunkt holen&lt;br /&gt;
  temp2 := SubtractVector (v, c);&lt;br /&gt;
&lt;br /&gt;
  // jetzt so drehen, als ob alles um den nullpunkt angeordnet wäre&lt;br /&gt;
  temp  := VectorRotateX (temp2, a);&lt;br /&gt;
&lt;br /&gt;
  // und das ergebnis wieder in den ausgangspunkt zurück verschieben&lt;br /&gt;
  result := AddVector (temp, c);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v,c: TGLvector;a: GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// c: zentrum&lt;br /&gt;
// a: winkel&lt;br /&gt;
var&lt;br /&gt;
   temp, temp2: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // das übergebene zentrum in den nullpunkt holen&lt;br /&gt;
  temp2 := SubtractVector (v, c);&lt;br /&gt;
&lt;br /&gt;
  // jetzt so drehen, als ob alles um den nullpunkt angeordnet wäre&lt;br /&gt;
  temp  := VectorRotateY (temp2, a);&lt;br /&gt;
&lt;br /&gt;
  // und das ergebnis wieder in den ausgangspunkt zurück verschieben&lt;br /&gt;
  result := AddVector (temp, c);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v,c: TGLvector; a: GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// c: zentrum&lt;br /&gt;
// a: winkel&lt;br /&gt;
var&lt;br /&gt;
  temp, temp2: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // das übergebene zentrum in den nullpunkt holen&lt;br /&gt;
  temp2 := SubtractVector (v, c);&lt;br /&gt;
&lt;br /&gt;
  // jetzt so drehen, als ob alles um den nullpunkt angeordnet wäre&lt;br /&gt;
  temp  := VectorRotateZ (temp2, a);&lt;br /&gt;
&lt;br /&gt;
  // und das ergebnis wieder in den ausgangspunkt zurück verschieben&lt;br /&gt;
  result := AddVector (temp, c);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;&lt;br /&gt;
// v1: zu drehender punkt&lt;br /&gt;
// v2, v3, v4: vektoren die zusammen mit v1 eine fläche beschreiben,&lt;br /&gt;
//             durch welche die drehachse läuft.&lt;br /&gt;
// a: drehwinkel&lt;br /&gt;
var&lt;br /&gt;
  PlaneVec, PlaneCenter: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zuerst das zentrum der vektoren herausfinden&lt;br /&gt;
  PlaneCenter.X := (v1.X+v2.X+v3.X+v4.X) / 4;&lt;br /&gt;
  PlaneCenter.Y := (v1.Y+v2.Y+v3.Y+v4.Y) / 4;&lt;br /&gt;
  PlaneCenter.Z := (v1.Z+v2.Z+v3.Z+v4.Z) / 4;&lt;br /&gt;
&lt;br /&gt;
  // den zu drehenden vector in den nullpunkt holen&lt;br /&gt;
  PlaneVec := SubtractVector (v1, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  // jetzt um die gewünschte achse drehen&lt;br /&gt;
  PlaneVec := VectorRotateX (PlaneVec, a);&lt;br /&gt;
&lt;br /&gt;
  // die drehung auf den eigentlichen vector aufaddieren&lt;br /&gt;
  // und zurückgeben&lt;br /&gt;
  result := AddVector (PlaneVec, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  result := VectorRotateX (v1, PlaneCenter, a);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v1,v2,v3,v4:TGLvector;a:GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// v2, v3, v4: vektoren die zusammen mit v1 eine fläche beschreiben,&lt;br /&gt;
//             durch welche die drehachse läuft.&lt;br /&gt;
// a: drehwinkel&lt;br /&gt;
var&lt;br /&gt;
  PlaneVec, PlaneCenter: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zuerst das zentrum der vektoren herausfinden&lt;br /&gt;
  PlaneCenter.X := (v1.X+v2.X+v3.X+v4.X) / 4;&lt;br /&gt;
  PlaneCenter.Y := (v1.Y+v2.Y+v3.Y+v4.Y) / 4;&lt;br /&gt;
  PlaneCenter.Z := (v1.Z+v2.Z+v3.Z+v4.Z) / 4;&lt;br /&gt;
&lt;br /&gt;
  // den zu drehenden vector in den nullpunkt holen&lt;br /&gt;
  PlaneVec := SubtractVector (v1, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  // jetzt um die gewünschte achse drehen&lt;br /&gt;
  PlaneVec := VectorRotateY (PlaneVec, a);&lt;br /&gt;
&lt;br /&gt;
  // die drehung auf den eigentlichen vector aufaddieren&lt;br /&gt;
  // und zurückgeben&lt;br /&gt;
  result := AddVector (PlaneVec, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  result := VectorRotateY (v1, PlaneCenter, a);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v1,v2,v3,v4:TGLvector;a:GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// v2, v3, v4: vektoren die zusammen mit v1 eine fläche beschreiben,&lt;br /&gt;
//             durch welche die drehachse läuft.&lt;br /&gt;
// a: drehwinkel&lt;br /&gt;
var&lt;br /&gt;
  PlaneVec, PlaneCenter: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zuerst das zentrum der vektoren herausfinden&lt;br /&gt;
  PlaneCenter.X := (v1.X+v2.X+v3.X+v4.X) / 4;&lt;br /&gt;
  PlaneCenter.Y := (v1.Y+v2.Y+v3.Y+v4.Y) / 4;&lt;br /&gt;
  PlaneCenter.Z := (v1.Z+v2.Z+v3.Z+v4.Z) / 4;&lt;br /&gt;
&lt;br /&gt;
  // den zu drehenden vector in den nullpunkt holen&lt;br /&gt;
  PlaneVec := SubtractVector (v1, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  // jetzt um die gewünschte achse drehen&lt;br /&gt;
  PlaneVec := VectorRotateZ (PlaneVec, a);&lt;br /&gt;
&lt;br /&gt;
  // die drehung auf den eigentlichen vector aufaddieren&lt;br /&gt;
  // und zurückgeben&lt;br /&gt;
  result := AddVector (PlaneVec, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  result := VectorRotateZ (v1, PlaneCenter, a);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{ Finds the point on the axis, closest to the&lt;br /&gt;
  source vector }&lt;br /&gt;
function NearestPoint(Axis, Point: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: double;&lt;br /&gt;
begin&lt;br /&gt;
  temp := DotProduct(Axis, Point) / DotProduct(Axis, Axis);&lt;br /&gt;
  Axis.X := Axis.X * temp;&lt;br /&gt;
  Axis.Y := Axis.Y * temp;&lt;br /&gt;
  Axis.Z := Axis.Z * temp;&lt;br /&gt;
  Result := Axis;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
{-------------------------------- allgemein ----------------------------------}&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
&lt;br /&gt;
function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;&lt;br /&gt;
var&lt;br /&gt;
  t: GLdouble;&lt;br /&gt;
  i, j, k, swap: integer;&lt;br /&gt;
  tmp: TMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
  inverse := GetIdentity(inverse);&lt;br /&gt;
&lt;br /&gt;
  for i := 0 to 3 do&lt;br /&gt;
  begin&lt;br /&gt;
    for j := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      tmp[i][j] := src[i*4+j];&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  for i := 0 to 3 do&lt;br /&gt;
  begin&lt;br /&gt;
    // look for largest element in column.&lt;br /&gt;
    swap := i;&lt;br /&gt;
    for j := i+1 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      if abs(tmp[j][i]) &amp;gt; abs(tmp[i][i]) then&lt;br /&gt;
      begin&lt;br /&gt;
        swap := j;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    if not (swap = i) then&lt;br /&gt;
    begin&lt;br /&gt;
      // swap rows.&lt;br /&gt;
      for k := 0 to 3 do&lt;br /&gt;
      begin&lt;br /&gt;
        t := tmp[i][k];&lt;br /&gt;
        tmp[i][k] := tmp[swap][k];&lt;br /&gt;
        tmp[swap][k] := t;&lt;br /&gt;
&lt;br /&gt;
        t := inverse[i*4+k];&lt;br /&gt;
        inverse[i*4+k] := inverse[swap*4+k];&lt;br /&gt;
        inverse[swap*4+k] := t;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    if tmp[i][i] = 0 then&lt;br /&gt;
    begin&lt;br /&gt;
    { no non-zero pivot.  the matrix is singular, which&lt;br /&gt;
      shouldn't happen.  This means the user gave us a bad&lt;br /&gt;
      matrix. }&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    t := tmp[i][i];&lt;br /&gt;
    for k := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      tmp[i][k] := tmp[i][k]/t;&lt;br /&gt;
      inverse[i*4+k] := inverse[i*4+k]/t;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    for j := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      if not (j = i) then&lt;br /&gt;
      begin&lt;br /&gt;
        t := tmp[j][i];&lt;br /&gt;
        for k := 0 to 3 do&lt;br /&gt;
        begin&lt;br /&gt;
          tmp[j][k] := tmp[j][k]-tmp[i][k]*t;&lt;br /&gt;
          inverse[j*4+k] := inverse[j*4+k]-inverse[i*4+k]*t;&lt;br /&gt;
        end;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
  result := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Multiply (Color: TGLcolor; m: GLdouble): TGLcolor;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLcolor;&lt;br /&gt;
begin&lt;br /&gt;
  ret.red := Color.red * m;&lt;br /&gt;
  ret.green := Color.green * m;&lt;br /&gt;
  ret.blue := Color.blue * m;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Divide (V1: TGLvector; d: GLdouble): TGLvector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  ret.x := V1.x / d;&lt;br /&gt;
  ret.y := V1.y / d;&lt;br /&gt;
  ret.z := V1.z / d;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ForceForegroundWindow(hwnd: THandle): Boolean;&lt;br /&gt;
{&lt;br /&gt;
  Manchmal funktioniert die SetForeGroundWindow Funktion&lt;br /&gt;
  nicht so, wie sie sollte; besonders unter Windows 98/2000,&lt;br /&gt;
  wenn ein anderes Fenster den Fokus hat.&lt;br /&gt;
  ForceForegroundWindow ist eine &amp;quot;verbesserte&amp;quot; Version von&lt;br /&gt;
  der SetForeGroundWindow API-Funktion, um ein Fenster in&lt;br /&gt;
  den Vordergrund zu bringen.&lt;br /&gt;
}&lt;br /&gt;
const&lt;br /&gt;
  SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;&lt;br /&gt;
  SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;&lt;br /&gt;
var&lt;br /&gt;
  ForegroundThreadID: DWORD;&lt;br /&gt;
  ThisThreadID: DWORD;&lt;br /&gt;
  timeout: DWORD;&lt;br /&gt;
begin&lt;br /&gt;
  if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);&lt;br /&gt;
&lt;br /&gt;
  if GetForegroundWindow = hwnd then Result := True&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    // Windows 98/2000 doesn't want to foreground a window when some other&lt;br /&gt;
    // window has keyboard focus&lt;br /&gt;
&lt;br /&gt;
    if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion &amp;gt; 4)) or&lt;br /&gt;
      ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and&lt;br /&gt;
      ((Win32MajorVersion &amp;gt; 4) or ((Win32MajorVersion = 4) and&lt;br /&gt;
      (Win32MinorVersion &amp;gt; 0)))) then&lt;br /&gt;
    begin&lt;br /&gt;
      // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm&lt;br /&gt;
      // Converted to Delphi by Ray Lischner&lt;br /&gt;
      // Published in The Delphi Magazine 55, page 16&lt;br /&gt;
&lt;br /&gt;
      Result := False;&lt;br /&gt;
      ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);&lt;br /&gt;
      ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);&lt;br /&gt;
      if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then&lt;br /&gt;
      begin&lt;br /&gt;
        BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
        SetForegroundWindow(hwnd);&lt;br /&gt;
        AttachThreadInput(ThisThreadID, ForegroundThreadID, False);&lt;br /&gt;
        Result := (GetForegroundWindow = hwnd);&lt;br /&gt;
      end;&lt;br /&gt;
      if not Result then&lt;br /&gt;
      begin&lt;br /&gt;
        // Code by Daniel P. Stasinski&lt;br /&gt;
        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);&lt;br /&gt;
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),&lt;br /&gt;
          SPIF_SENDCHANGE);&lt;br /&gt;
        BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
        SetForegroundWindow(hWnd);&lt;br /&gt;
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);&lt;br /&gt;
      end;&lt;br /&gt;
    end&lt;br /&gt;
    else&lt;br /&gt;
    begin&lt;br /&gt;
      BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
      SetForegroundWindow(hwnd);&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    Result := (GetForegroundWindow = hwnd);&lt;br /&gt;
  end;&lt;br /&gt;
end; { ForceForegroundWindow }&lt;br /&gt;
&lt;br /&gt;
procedure InitGLEnv (dc: HDC; rc: HGLRC; hndl: THandle);&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_ChooseFailed = 'ChoosePixelFormat failed with ';&lt;br /&gt;
var&lt;br /&gt;
  pfd: TPixelFormatDescriptor;&lt;br /&gt;
  PixelFormat: TGLUint;&lt;br /&gt;
  pFlags: TPFDFlags;&lt;br /&gt;
  flags: word absolute pFlags;&lt;br /&gt;
  StencilBits,&lt;br /&gt;
  ColorBits,&lt;br /&gt;
  DepthBits: integer;&lt;br /&gt;
begin&lt;br /&gt;
  pflags := [];&lt;br /&gt;
  include (pflags, DoubleBuffer);&lt;br /&gt;
  include (pflags, Stereo);&lt;br /&gt;
  include (pflags, Draw_To_Window);&lt;br /&gt;
  include (pflags, Draw_To_Bitmap);&lt;br /&gt;
  include (pflags, Support_GDI);&lt;br /&gt;
  include (pflags, Support_OpenGL);&lt;br /&gt;
  include (pflags, Generic_Format);&lt;br /&gt;
  include (pflags, Need_Palette);&lt;br /&gt;
  include (pflags, Need_System_Palette);&lt;br /&gt;
  include (pflags, Swap_Exchange);&lt;br /&gt;
  include (pflags, Swap_Copy);&lt;br /&gt;
  include (pflags, Swap_Layer_Buffers);&lt;br /&gt;
  include (pflags, Generic_Accelerated);&lt;br /&gt;
&lt;br /&gt;
  ColorBits := 24;&lt;br /&gt;
  DepthBits := 32;&lt;br /&gt;
  StencilBits := 0;&lt;br /&gt;
&lt;br /&gt;
  with TWinControl(hndl) do&lt;br /&gt;
  begin&lt;br /&gt;
    fillchar(pfd,SizeOf(pfd),0);&lt;br /&gt;
    with pfd do&lt;br /&gt;
    begin&lt;br /&gt;
      nSize           := SizeOf(pfd);&lt;br /&gt;
      nVersion        := 1;&lt;br /&gt;
      dwFlags         := flags or&lt;br /&gt;
                         PFD_DRAW_TO_WINDOW&lt;br /&gt;
                         or PFD_SUPPORT_OPENGL&lt;br /&gt;
                         or PFD_DOUBLEBUFFER;&lt;br /&gt;
      iPixelType      := PFD_TYPE_RGBA;&lt;br /&gt;
      cColorBits      := ColorBits;&lt;br /&gt;
      cDepthBits      := DepthBits;&lt;br /&gt;
      cStencilBits    := StencilBits;&lt;br /&gt;
      iLayerType      := PFD_MAIN_PLANE;&lt;br /&gt;
      cRedBits        := 0;&lt;br /&gt;
      cRedShift       := 0;&lt;br /&gt;
      cGreenBits      := 0;&lt;br /&gt;
      cBlueBits       := 0;&lt;br /&gt;
      cBlueShift      := 0;&lt;br /&gt;
      cAlphaBits      := 0;&lt;br /&gt;
      cAlphaShift     := 0;&lt;br /&gt;
      cAccumBits      := 0;&lt;br /&gt;
      cAccumRedBits   := 0;&lt;br /&gt;
      cAccumGreenBits := 0;&lt;br /&gt;
      cAccumBlueBits  := 0;&lt;br /&gt;
      cAccumAlphaBits := 0;&lt;br /&gt;
      cAuxBuffers     := 0;&lt;br /&gt;
      bReserved       := 0;&lt;br /&gt;
      dwLayerMask     := 0;&lt;br /&gt;
      dwVisibleMask   := 0;&lt;br /&gt;
      dwDamageMask    := 0;&lt;br /&gt;
    end; {with}&lt;br /&gt;
&lt;br /&gt;
    PixelFormat := ChoosePixelFormat(dc, @pfd);&lt;br /&gt;
    if PixelFormat=0 then&lt;br /&gt;
      raise Exception.Create(Res_ChooseFailed+IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
    //if not SetPixelFormat(FglDC, PixelFormat, @pfd) then&lt;br /&gt;
    //  raise Exception.Create('SetPixelFormat failed with '+&lt;br /&gt;
    //    IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function CheckFormat (number: string; digits, decimals: byte): string;&lt;br /&gt;
// wandelt ein mögliches dezimalkomma in einen punkt um&lt;br /&gt;
// beschneidet den übergebenen zahlenstring auf die gewünschten&lt;br /&gt;
// vorkomma- und nachkommastellen&lt;br /&gt;
// der übergebene zahlenstring darf keine tausender-kommas&lt;br /&gt;
// oder punkte enthalten!&lt;br /&gt;
var&lt;br /&gt;
  sdigits, sdecimals, temp: string;&lt;br /&gt;
  posi: integer;&lt;br /&gt;
begin&lt;br /&gt;
  if digits+decimals = 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    temp := '';&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    sdigits := '';&lt;br /&gt;
    sdecimals := '';&lt;br /&gt;
    posi := pos (',', number);&lt;br /&gt;
    if posi = 0 then&lt;br /&gt;
      posi := pos ('.', number);&lt;br /&gt;
    if posi &amp;gt; 0 then&lt;br /&gt;
      sdigits := copy (number, 1, posi-1);&lt;br /&gt;
    if length (number) &amp;gt; posi then&lt;br /&gt;
      sdecimals := copy (number, posi+1);&lt;br /&gt;
    if length (sdigits) &amp;gt; digits then&lt;br /&gt;
      sdigits := copy (sdigits, length (sdigits)-(digits-1));&lt;br /&gt;
    if length (sdecimals) &amp;gt; decimals then&lt;br /&gt;
      sdecimals := copy (sdecimals, 1, decimals);&lt;br /&gt;
    temp := sdigits + '.' + sdecimals;&lt;br /&gt;
  end;&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure ResetGLErrorFlags;&lt;br /&gt;
var&lt;br /&gt;
  err: GLenum;&lt;br /&gt;
begin&lt;br /&gt;
  repeat&lt;br /&gt;
    err := glGetError;&lt;br /&gt;
  until err = GL_NO_ERROR;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ValidTexture (tex: GLUint; ErrStr: string): boolean;&lt;br /&gt;
var&lt;br /&gt;
  error: GLenum;&lt;br /&gt;
begin&lt;br /&gt;
  result := true;&lt;br /&gt;
&lt;br /&gt;
  ResetGLErrorFlags;&lt;br /&gt;
  if not glIsTexture (tex) then&lt;br /&gt;
  begin&lt;br /&gt;
    error := glGetError;&lt;br /&gt;
    Application.MessageBox(pChar ('Textur wurde nicht erkannt!'+chr(13)+chr(10)+&lt;br /&gt;
                           ErrStr+chr(13)+chr(10)+&lt;br /&gt;
                           'Fehler: '+IntToStr (error)),&lt;br /&gt;
                           'Fehler',&lt;br /&gt;
                           0);&lt;br /&gt;
    result := false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AxisXRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  V1.Z := 0;&lt;br /&gt;
  V2.Z := 0;&lt;br /&gt;
  result := DotProduct (V1, V2);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AxisYRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  V1.Z := 0;&lt;br /&gt;
  V2.Z := 0;&lt;br /&gt;
  result := DotProduct (V1, V2);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AxisZRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  V1.Y := 0;&lt;br /&gt;
  V2.Y := 0;&lt;br /&gt;
  result := DotProduct (V1, V2);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ExePath: string;&lt;br /&gt;
var&lt;br /&gt;
  pfad: string;&lt;br /&gt;
begin&lt;br /&gt;
  pfad := ExtractFilePath (Application.Exename);&lt;br /&gt;
  if copy (pfad, length (pfad), 1) &amp;lt;&amp;gt; '\' then&lt;br /&gt;
    pfad := pfad + '\';&lt;br /&gt;
  result := pfad;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=21090</id>
		<title>Kamera (2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=21090"/>
				<updated>2008-02-05T05:00:37Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
{******************************************************************}&lt;br /&gt;
(*&lt;br /&gt;
  Released as part of the camera example program&lt;br /&gt;
  Visit us @ http://www.delphigl.com&lt;br /&gt;
  Maintained by Florian Sievert (Phobeus)&lt;br /&gt;
  Phobeus@DelphiGL.com&lt;br /&gt;
-------------------------------------------------------------------&lt;br /&gt;
  License&lt;br /&gt;
  -------&lt;br /&gt;
  Copyright (C) 2007 Andree Heyroth&lt;br /&gt;
&lt;br /&gt;
  This license applies to everything on www.delphigl.com, except where&lt;br /&gt;
  otherwise noted.&lt;br /&gt;
&lt;br /&gt;
  This software is provided 'as-is', without any express or implied warranty.&lt;br /&gt;
  In no event will the authors be held liable for any damages arising from&lt;br /&gt;
  the use of this software.&lt;br /&gt;
&lt;br /&gt;
  Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
  including commercial applications, and to alter it and redistribute it&lt;br /&gt;
  freely, subject to the following restrictions:&lt;br /&gt;
&lt;br /&gt;
  1. The origin of this software must not be misrepresented; you must not&lt;br /&gt;
     claim that you wrote the original software. If you use this software in a&lt;br /&gt;
     product, an acknowledgment in the product documentation would be&lt;br /&gt;
     appreciated but is not required.&lt;br /&gt;
  2. Altered source versions must be plainly marked as such, and must not be&lt;br /&gt;
     misrepresented as being the original software.&lt;br /&gt;
  3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
&lt;br /&gt;
  Description&lt;br /&gt;
  -----------&lt;br /&gt;
  Component containing methods and properties which are useful for moving and&lt;br /&gt;
  rotating an existing scene in any dimension (yaw, pitcxh and roll/vertical,&lt;br /&gt;
  horizontal and depth).&lt;br /&gt;
&lt;br /&gt;
  Requirements&lt;br /&gt;
  ------------&lt;br /&gt;
  - SDL 1.2 (http://www.libsdl.org/download-1.2.php or your distribution)&lt;br /&gt;
  - Borland Delphi version 5.0 and above&lt;br /&gt;
&lt;br /&gt;
  History&lt;br /&gt;
  -------&lt;br /&gt;
  see below (unfortunately in german)&lt;br /&gt;
&lt;br /&gt;
  Contact&lt;br /&gt;
  -------&lt;br /&gt;
  I created this source code in my spare time. If you find a bug or just&lt;br /&gt;
  wanna say hello, feel free to write to the contributor:&lt;br /&gt;
&lt;br /&gt;
    Andree Heyroth (AndyH)&lt;br /&gt;
    email : heyroth@syncro-concept.de&lt;br /&gt;
    Visit: http://www.delphigl.com&lt;br /&gt;
&lt;br /&gt;
*******************************************************************************)&lt;br /&gt;
&lt;br /&gt;
// Wie ich selber immer wieder merken muss, ist eine Software anscheinend&lt;br /&gt;
// nie fertig. Immer moechte man etwas verbessern oder neue Features&lt;br /&gt;
// einbauen.&lt;br /&gt;
// Sollte also jemand Änderungs- oder Verbesserungsvorschläge haben oder&lt;br /&gt;
// neue Ideen einbringen wollen, oder sollten Verstaendnisfragen bestehen,&lt;br /&gt;
// so mailt bitte an&lt;br /&gt;
//&lt;br /&gt;
// heyroth@syncro-concept.de&lt;br /&gt;
//&lt;br /&gt;
// Danke.&lt;br /&gt;
//&lt;br /&gt;
// Updates:&lt;br /&gt;
//&lt;br /&gt;
// 06.11.2005&lt;br /&gt;
// Die Deklaration der DESTROY Methode war falsch. Das fuehrte dazu,&lt;br /&gt;
// dass in der Methode CREATE erzeugte Objekte nicht richtig frei-&lt;br /&gt;
// gegeben wurden und es zu EAccessViolations kam. Die Methode wird&lt;br /&gt;
// jetzt in der PUBLIC Section mit der Direktive OVERRIDE aufgerufen.&lt;br /&gt;
//&lt;br /&gt;
// 11.11.2005&lt;br /&gt;
// Die Positionierung funktioniert jetzt.&lt;br /&gt;
// Wegen eines Verstaendnisproblems wurden die Positionen immer auf den&lt;br /&gt;
// Kamerapunkt aufaddiert. Das bedeutete, dass die Positionierung aus&lt;br /&gt;
// dem Ruder lief wenn sie nicht im Nullpunkt stattfand. Je groesser die&lt;br /&gt;
// gewuenschte Position war um so groesser war die Abweichung von der&lt;br /&gt;
// Darstellung.&lt;br /&gt;
// Ich habe nicht bedacht, dass bei einer &amp;quot;Kamera&amp;quot;-bewegung und -drehung&lt;br /&gt;
// ja eigentlich die Szene bewegt und gedreht wird. Deswegen wurden nach&lt;br /&gt;
// einer Positionierung die folgenden Projektionen immer basierend auf der&lt;br /&gt;
// danach gueltigen Kameraposition gemacht.&lt;br /&gt;
// Jetzt wird die Position so gesetzt, dass die gewuenschte Kameraposition&lt;br /&gt;
// immer vor dem Betrachter steht.&lt;br /&gt;
//&lt;br /&gt;
// 23.11.2005&lt;br /&gt;
// Neues Flag (FFixedAxis) zur Entscheidung zwischen angepasster und realer&lt;br /&gt;
// Drehung. Dadurch wird das Bewegungsmodell angepasst. Siehe Methode Offset,&lt;br /&gt;
// bzw. UpdateMatrixOffset.&lt;br /&gt;
//&lt;br /&gt;
// 10.12.2005&lt;br /&gt;
// Property PointOfRotation ist jetzt nicht mehr ReadOnly.&lt;br /&gt;
// Der Blickpunkt bzw. Rotationspunkt kann jetzt direkt verändert werden.&lt;br /&gt;
// So kann eine neue Blickrichtung angenommen werden ohne vorher die Kamera-&lt;br /&gt;
// eigenschaften zu sichern und nach einem PositionCamera wieder zu setzen.&lt;br /&gt;
//&lt;br /&gt;
// 19.12.2005&lt;br /&gt;
// Neue Methode PositionCross.&lt;br /&gt;
// Die Methode PositionCross schiebt das Fadenkreuz in den angegebenen Punkt&lt;br /&gt;
// ohne die Lage der Szene zu verändern. Diese Funktionalitaet ist anders als&lt;br /&gt;
// ein neues Setzen der Property FPointOfRotation weil dabei die Szene in das&lt;br /&gt;
// Koordinatenkreuz geschoben wird.&lt;br /&gt;
//&lt;br /&gt;
// 31.01.2006&lt;br /&gt;
// Umstellung auf genaueres Zahlenformat&lt;br /&gt;
// Da die Darstellung von Szenen ausserhalb des Bereichs von FLOAT-Zahlen&lt;br /&gt;
// nicht funktioniert, muss alles auf DOUBLE umgestellt werden. Dazu gehört&lt;br /&gt;
// das Ersetzen von Datentypen und der Aufruf der entsprechenden GL-Funktionen.&lt;br /&gt;
//&lt;br /&gt;
// 24.09.2007&lt;br /&gt;
// Um den Einstieg zu erleichtern habe ich die ganzen Steuerfunktionen in die&lt;br /&gt;
// Kamera verlegt. Die &amp;quot;normalen&amp;quot; Funktionen wie Drehen und Verschieben werden&lt;br /&gt;
// jetzt durch Weitergabe der Tastendrücke und Mauseigenschaften an die&lt;br /&gt;
// Kamera abgearbeitet. Die Auswertung erfolgt dort. Sollten andere Tasten&lt;br /&gt;
// als die von mir vorgesehenen gewünscht sein, muss dies in der Kamera&lt;br /&gt;
// geändert werden.&lt;br /&gt;
&lt;br /&gt;
unit Camera;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
  Uses&lt;br /&gt;
    DglOpenGL,&lt;br /&gt;
    Util,&lt;br /&gt;
    Windows,&lt;br /&gt;
    Classes,&lt;br /&gt;
    Messages,&lt;br /&gt;
    Controls;&lt;br /&gt;
&lt;br /&gt;
  type&lt;br /&gt;
  TCameraMatrix=Class&lt;br /&gt;
    StackMatrix: array [0..9] of TArrMatrix;&lt;br /&gt;
    StackCtr: integer;&lt;br /&gt;
    Matrix: TArrMatrix;&lt;br /&gt;
    InverseMatrix: TArrMatrix;&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    //destructor destroy;&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Push;&lt;br /&gt;
    procedure Pop;&lt;br /&gt;
    procedure Load(M: TArrMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TCamera=Class&lt;br /&gt;
    Enabled: boolean;&lt;br /&gt;
    function UpVector: TGLvector;&lt;br /&gt;
    procedure RestorePosition(pos: integer);&lt;br /&gt;
    procedure SavePosition(pos: integer);&lt;br /&gt;
    function GiveStoredPosition(pos: integer): TGLvector;&lt;br /&gt;
    procedure RotateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
    procedure TranslateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
    procedure CameraHome;&lt;br /&gt;
    procedure PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector);&lt;br /&gt;
    procedure Adjust;&lt;br /&gt;
    procedure Apply;&lt;br /&gt;
    procedure ApplyForTerrain;&lt;br /&gt;
  private&lt;br /&gt;
    // Dreh- und Bewegungsrichtung festlegen (in Mousedown).&lt;br /&gt;
    // Pfeil hoch  : Szene nach oben&lt;br /&gt;
    // Pfeil runter: Szene nach unten&lt;br /&gt;
    // Pfeil rechts: Szene nach rechts&lt;br /&gt;
    // Pfeil links : Szene nach links&lt;br /&gt;
    // Page Up     : Szene in den Bildschirm schieben (verkleinern)&lt;br /&gt;
    // Page Down   : Szene aus dem Bildschirm schieben (vergrößern)&lt;br /&gt;
    //&lt;br /&gt;
    // Wird FDir auf true gesetzt ist die Tastenfunktion jeweils umgekehrt.&lt;br /&gt;
    // so verschiebt sich entweder die szene oder das objekt.&lt;br /&gt;
    FDir: boolean;&lt;br /&gt;
    FPosition: TGLvector;&lt;br /&gt;
    FViewDirection: TGLvector;&lt;br /&gt;
&lt;br /&gt;
    FAltPressed,&lt;br /&gt;
    FShiftPressed,&lt;br /&gt;
    FCtrlPressed: boolean;&lt;br /&gt;
&lt;br /&gt;
    FRightMousePressed: boolean;&lt;br /&gt;
    FLeftMousePressed: boolean;&lt;br /&gt;
&lt;br /&gt;
    FSpeedMultiplier: double;&lt;br /&gt;
&lt;br /&gt;
    FxStart,                  // berechnung der mausbewegungen.&lt;br /&gt;
    FxDelta,                  // delta = aktuelle position minus start&lt;br /&gt;
    FyStart,                  // start wird erfasst sobald eine maustaste&lt;br /&gt;
    FyDelta:integer;          // gedrückt wird.&lt;br /&gt;
    FxRot,                    // umrechnung von delta in rotation wenn&lt;br /&gt;
    FyRot:double;             // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
    FPointOfRotation: TGLvector;&lt;br /&gt;
    HomeMatrix: TCameraMatrix;&lt;br /&gt;
    CameraMatrix: TCameraMatrix;&lt;br /&gt;
    Initiated: boolean;&lt;br /&gt;
    PosArray: array [0..9] of TCameraMatrix;&lt;br /&gt;
    RotArray: array [0..9] of TGLvector;&lt;br /&gt;
    FFixedAxis: boolean;&lt;br /&gt;
    procedure Debug (Text: string);&lt;br /&gt;
    function UpdateMatrixOffset(newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
    function GetViewDirection: TGLvector;&lt;br /&gt;
    procedure SetViewDirection (View: TGLvector);&lt;br /&gt;
    procedure Initiate;&lt;br /&gt;
    function GetPosition: TGLvector;&lt;br /&gt;
    procedure SetPosition (Pos: TGLvector);&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Offset(x, y, z: GLdouble);&lt;br /&gt;
    procedure RotateRoundAxis(rx, ry, rz: GLdouble);&lt;br /&gt;
    procedure SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
    function ProcessArrowKeys (Key: integer; Shift: TShiftState): boolean;&lt;br /&gt;
    function GiveSpeed: TGLdouble;&lt;br /&gt;
    procedure RotateScene(Direction: byte; Geschwindigkeit: GLdouble);&lt;br /&gt;
    procedure MoveScene (Direction: byte; Geschwindigkeit: GLdouble);&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    destructor Destroy;override;&lt;br /&gt;
    function InverseMatrix: TArrMatrix;&lt;br /&gt;
    procedure ApplyInvers;&lt;br /&gt;
    procedure PositionCross(CrossVec: TGLvector);&lt;br /&gt;
    function HandleKeyboardInput (Key: Word; Shift: TShiftState): boolean;&lt;br /&gt;
    procedure KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);&lt;br /&gt;
    function KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState): boolean;&lt;br /&gt;
    procedure MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
    procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
    function MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer): boolean;&lt;br /&gt;
    function MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean): boolean;&lt;br /&gt;
    procedure MouseEnter(var msg:TMessage);&lt;br /&gt;
    procedure MouseLeave(var msg: TMessage);&lt;br /&gt;
  published&lt;br /&gt;
    property PointOfRotation: TGLvector read FPointOfRotation write SetPointOfRotation;&lt;br /&gt;
    property Position: TGLvector read GetPosition write SetPosition;&lt;br /&gt;
    property ViewDirection: TGLvector read GetViewDirection write SetViewDirection;&lt;br /&gt;
    property FixedAxis: boolean read FFixedAxis write FFixedAxis;&lt;br /&gt;
    property SpeedMultiplier: double read FSpeedMultiplier write FSpeedMultiplier;&lt;br /&gt;
  end;&lt;br /&gt;
  TPCamera=^TCamera;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FDebugFile: Textfile;&lt;br /&gt;
  FDebugFileName: string;&lt;br /&gt;
  FDebugOn: boolean;&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  VK_0 = $30;&lt;br /&gt;
  VK_1 = $31;&lt;br /&gt;
  VK_2 = $32;&lt;br /&gt;
  VK_3 = $33;&lt;br /&gt;
  VK_4 = $34;&lt;br /&gt;
  VK_5 = $35;&lt;br /&gt;
  VK_6 = $36;&lt;br /&gt;
  VK_7 = $37;&lt;br /&gt;
  VK_8 = $38;&lt;br /&gt;
  VK_9 = $39;&lt;br /&gt;
&lt;br /&gt;
  VK_A = $41;&lt;br /&gt;
  VK_B = $42;&lt;br /&gt;
  VK_C = $43;&lt;br /&gt;
  VK_D = $44;&lt;br /&gt;
  VK_E = $45;&lt;br /&gt;
  VK_F = $46;&lt;br /&gt;
  VK_G = $47;&lt;br /&gt;
  VK_H = $48;&lt;br /&gt;
  VK_I = $49;&lt;br /&gt;
  VK_J = $4A;&lt;br /&gt;
  VK_K = $4B;&lt;br /&gt;
  VK_L = $4C;&lt;br /&gt;
  VK_M = $4D;&lt;br /&gt;
  VK_N = $4E;&lt;br /&gt;
  VK_O = $4F;&lt;br /&gt;
  VK_P = $50;&lt;br /&gt;
  VK_Q = $51;&lt;br /&gt;
  VK_R = $52;&lt;br /&gt;
  VK_S = $53;&lt;br /&gt;
  VK_T = $54;&lt;br /&gt;
  VK_U = $55;&lt;br /&gt;
  VK_V = $56;&lt;br /&gt;
  VK_W = $57;&lt;br /&gt;
  VK_X = $58;&lt;br /&gt;
  VK_Y = $59;&lt;br /&gt;
  VK_Z = $5A;&lt;br /&gt;
&lt;br /&gt;
  // Standard-Keycodes für Tastatureingaben definieren&lt;br /&gt;
  CKeyCameraHome = VK_0;&lt;br /&gt;
  CKeyCameraAdjust = VK_A;&lt;br /&gt;
&lt;br /&gt;
  DIR_HORIZONTAL: byte = 1;&lt;br /&gt;
  DIR_VERTIKAL: byte = 2;&lt;br /&gt;
  DIR_ZENTRAL: byte = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses SysUtils;&lt;br /&gt;
&lt;br /&gt;
constructor TCameraMatrix.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
  StackCtr := 0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Push;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; -1) and (StackCtr &amp;lt; 10) then begin&lt;br /&gt;
    StackMatrix[StackCtr] := Matrix;&lt;br /&gt;
    inc (StackCtr);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Pop;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; 0) and (StackCtr &amp;lt; 11) then begin&lt;br /&gt;
    dec (StackCtr);&lt;br /&gt;
    Load (StackMatrix[StackCtr]);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Identity;&lt;br /&gt;
// GetIdentity: aus OpenGL.pas&lt;br /&gt;
// initialisiert die CameraMatrix mit der Identitaetsmatrix&lt;br /&gt;
begin&lt;br /&gt;
  Matrix := GetIdentity(Matrix);&lt;br /&gt;
  InverseMatrix := GetIdentity(InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Load(M: TArrMatrix);&lt;br /&gt;
// die Matrix mit den Werten einer beliebigen anderen matrix fuellen&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i:=0 to 15 do&lt;br /&gt;
    Matrix[i]:=M[i];&lt;br /&gt;
  // die invertierte Matrix kann benutzt werden um Objkekte z.B.&lt;br /&gt;
  // immer zum Benutzer auszurichten&lt;br /&gt;
  InvertMatrix (M, InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
constructor TCamera.Create;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
&lt;br /&gt;
  // Initiated wird gebraucht um einmal alle Positionsspeicher&lt;br /&gt;
  // mit der Anfangsposition zu belegen&lt;br /&gt;
  Initiated := false;&lt;br /&gt;
&lt;br /&gt;
  // Kameramatrix anlegen&lt;br /&gt;
  CameraMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Matrix der letzten Position von PositionCamera anlegen&lt;br /&gt;
  HomeMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Positionsspeicher anlegen&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    PosArray[i] := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // standardmaessig immer entlang der bildschirmachsen verschieben&lt;br /&gt;
  FFixedAxis := true;&lt;br /&gt;
&lt;br /&gt;
  // flags für die tasten alt, ctrl und shift initialisieren&lt;br /&gt;
  FAltPressed := false;&lt;br /&gt;
  FCtrlPressed := false;&lt;br /&gt;
  FShiftPressed := false;&lt;br /&gt;
&lt;br /&gt;
  // normalerweise wird die geschwindigkeit nicht verändert&lt;br /&gt;
  FSpeedMultiplier := 1.0;&lt;br /&gt;
&lt;br /&gt;
  // normale bildschirmbewegung&lt;br /&gt;
  FDir := false;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCamera.Destroy;&lt;br /&gt;
// alle in create belegten Resourcen wieder freigeben&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FreeAndNil (CameraMatrix);&lt;br /&gt;
  FreeAndNil (HomeMatrix);&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    FreeAndNil (PosArray[i]);&lt;br /&gt;
&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateRoundAxis(rx, ry, rz: GLdouble);&lt;br /&gt;
// hier drehen wir jetzt um die einzelnen Achsen.&lt;br /&gt;
// die Parameter geben die &amp;quot;Drehgeschwindigkeit&amp;quot; vor.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  tempX, tempY, tempZ: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Position und Lage der Kamera herstellen&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
&lt;br /&gt;
  if FFixedAxis then begin&lt;br /&gt;
    // über die bildschirmachsen drehen&lt;br /&gt;
    tempX := GetMatrixX (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempY := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempZ := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rx,tempX.X,tempX.Y,tempX.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(ry,tempY.X,tempY.Y,tempY.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rz,tempZ.X,tempZ.Y,tempZ.Z);&lt;br /&gt;
  end&lt;br /&gt;
  else begin&lt;br /&gt;
    // über die achsen des koordinatenkreuzes drehen&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rx,1,0,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(ry,0,1,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rz,0,0,1);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // die neu erzeugte Matrix auslesen&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  // und in die Kameramatrix sichern&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Identity;&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Identity;&lt;br /&gt;
  HomeMatrix.Identity;&lt;br /&gt;
&lt;br /&gt;
  Enabled := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Offset(x, y, z: GLdouble);&lt;br /&gt;
// verschieben der Kamera auf einer beliebigen Achse&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  //OldView: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- Offset - Start --------------------------------------------------');&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslated(x,y,z);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  Debug ('Position: '+GLvectorToText (GetMatrixPos (newMatrix)));&lt;br /&gt;
  newMatrix := UpdateMatrixOffset (newMatrix);&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  Debug ('- Offset - Ende- --------------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
			                           ViewVec: TGLvector;&lt;br /&gt;
			                           upVec: TGLvector);&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  i: integer;&lt;br /&gt;
  P, V, U: TGLvector;&lt;br /&gt;
  Laenge: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCamera - Start ------------------------------------------');&lt;br /&gt;
  // die gewuenschte konstruktion immer auf die Z-ebene projizieren.&lt;br /&gt;
  // zuerst die position in den nullpunkt holen&lt;br /&gt;
  InitVector (P, 0, 0, 0);&lt;br /&gt;
  // jetzt den viewpoint um den gleichen betrag reduzieren, damit&lt;br /&gt;
  // die gerade parallel verschoben wird.&lt;br /&gt;
  V := SubtractVector (ViewVec, PositionVec);&lt;br /&gt;
  // U ist halt schneller geschrieben als upVec...&lt;br /&gt;
  U := upVec;&lt;br /&gt;
&lt;br /&gt;
  // den betrag ermitteln, um den die kamera nachher auf der Z-Achse&lt;br /&gt;
  // verschoben werden muss&lt;br /&gt;
  Laenge := Magnitude (SubtractVector (P, V));&lt;br /&gt;
&lt;br /&gt;
  Identity;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  // glulookat wird die matrix parallel zur Z-achse ausrichten&lt;br /&gt;
  gluLookAt (P.X, P.Y, P.Z, V.X, V.Y, V.Z, U.X, U.Y, U.Z);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  HomeMatrix.Load(newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // da wir uns jetzt am zielpunkt befinden, müssen wir auf der Z-achse&lt;br /&gt;
  // wieder zurueck zur kameraposition&lt;br /&gt;
  Offset (0, 0, -Laenge);&lt;br /&gt;
&lt;br /&gt;
  // alle positionsspeicher mit der Kameraposition, Blickrichtung&lt;br /&gt;
  // und dem upVector belegen. Nur beim ersten Aufruf von&lt;br /&gt;
  // PositionCamera&lt;br /&gt;
  if not Initiated then&lt;br /&gt;
    Initiate;&lt;br /&gt;
&lt;br /&gt;
  FPointOfRotation := ViewVec;&lt;br /&gt;
  Debug ('PointOfRotation: '+GLvectorToText (FPointOfRotation));&lt;br /&gt;
  Debug ('- PositionCamera - Ende -------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCross (CrossVec: TGLvector);&lt;br /&gt;
// diese prozedur verschiebt, im gegensatz zu einem verändern von&lt;br /&gt;
// PointOfRotation, das Koordinatenkreuz und nicht die Szene.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  PosDiff: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCross - Start -------------------------------------------');&lt;br /&gt;
&lt;br /&gt;
  PosDiff := SubtractVector (FPointOfRotation, CrossVec);&lt;br /&gt;
&lt;br /&gt;
  // Szene in das koordinatenkreuz verschieben&lt;br /&gt;
  FPointOfRotation := CrossVec;&lt;br /&gt;
&lt;br /&gt;
  // jetzt die Szene wieder um den gleichen betrag zurückverschieben&lt;br /&gt;
  // das sieht dann so aus, als ob das koordinatenkreuz verschoben&lt;br /&gt;
  // worden wäre&lt;br /&gt;
  // zuerst die aktuelle neue Situation herstellen&lt;br /&gt;
  // (mit neuem FPointOfRotation)&lt;br /&gt;
  Apply;&lt;br /&gt;
&lt;br /&gt;
  // jetzt um den Differenzbetrag des alten und neuen&lt;br /&gt;
  // Rotationspunkts zurück verschieben&lt;br /&gt;
  glTranslated (-PosDiff.X, 0, 0);&lt;br /&gt;
  glTranslated (0, -PosDiff.Y, 0);&lt;br /&gt;
  glTranslated (0, 0, -PosDiff.Z);&lt;br /&gt;
&lt;br /&gt;
  // jetzt vom neuen Rotationspunktes zurück ins Zentrum, damit beim&lt;br /&gt;
  // nächsten Apply das glTranslatef (-FPointOfRotation, ...) klappt&lt;br /&gt;
  glTranslated (CrossVec.X, 0, 0);&lt;br /&gt;
  glTranslated (0, CrossVec.Y, 0);&lt;br /&gt;
  glTranslated (0, 0, CrossVec.Z);&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Matrix holen...&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // und als Kameramatrix abspeichern&lt;br /&gt;
  CameraMatrix.Load(newmatrix);&lt;br /&gt;
  Debug ('- PositionCross - Ende --------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.CameraHome;&lt;br /&gt;
// Kamera in die beim letzten Aufruf von PositionCamera uebergebene&lt;br /&gt;
// Position/Lage bringen&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Load(HomeMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SavePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  PosArray[pos].Load(CameraMatrix.Matrix);&lt;br /&gt;
  RotArray[pos] := FPointOfRotation;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RestorePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(PosArray[pos].Matrix);&lt;br /&gt;
  FPointOfRotation := RotArray[pos];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GiveStoredPosition (pos: integer): TGLvector;&lt;br /&gt;
// gibt den Inhalt des durch pos bestimmten&lt;br /&gt;
// Positionsspecihers zurueck&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  result := GetMatrixPos (PosArray[pos].Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.TranslateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Verschiebung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  Offset (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Drehung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  RotateRoundAxis (-iy, -ix, -iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Apply;&lt;br /&gt;
// hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur&lt;br /&gt;
// sollte die Szene mit allen benoetigten Drehungen, Verschiebungen&lt;br /&gt;
// gezeichnet werden.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
  glTranslated (-FPointOfRotation.X,&lt;br /&gt;
                -FPointOfRotation.y,&lt;br /&gt;
                -FPointOfRotation.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyForTerrain;&lt;br /&gt;
// hier wird wie in Apply die Kamera eingeschaltet. da man um ein terrain&lt;br /&gt;
// (skycube, ...) anzuzeigen aber immer die gleiche entfernung zur welt&lt;br /&gt;
// einhalten muss, wird hier nur gedreht und nicht verschoben.&lt;br /&gt;
var&lt;br /&gt;
  pos: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  // für das Terrain nur die Drehung ausführen&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
  // deswegen jetzt die verschiebung zurücknehmen&lt;br /&gt;
  Pos := GetMatrixPos (CameraMatrix.InverseMatrix);&lt;br /&gt;
  glTranslated (Pos.X, Pos.Y, Pos.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetPosition: TGLvector;&lt;br /&gt;
// diese Property-Funktion fragt die aktuelle Position der Kamera ab&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  result := AddVector (GetMatrixPos (CameraMatrix.InverseMatrix), FPointOfRotation);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPosition (Pos: TGLvector);&lt;br /&gt;
// diese Property-Funktion setzt eine neue Position der Kamera&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  m := CameraMatrix.Matrix;&lt;br /&gt;
  SetMatrixPos (m, SubtractVector (Pos, FPointOfRotation));&lt;br /&gt;
  CameraMatrix.Load (m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetViewDirection: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  result := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetViewDirection (View: TGLvector);&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// gesetzt werden&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  SetMatrixZ (CameraMatrix.InverseMatrix, View);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpVector: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Ausrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // upVector: zweite Spalte der Matrix (Y-Achse)&lt;br /&gt;
  result := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Adjust;&lt;br /&gt;
// mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhaengig&lt;br /&gt;
// von Drehung und Position, zur Y-Achse ausgerichtet werden.&lt;br /&gt;
// Die aktuelle Position wird dabei beibehalten.&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
  v: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // position aus der aktuellen cameramatrix holen&lt;br /&gt;
  v := GetMatrixPos (CameraMatrix.Matrix);&lt;br /&gt;
  // m mit identitätsmatrix initialisieren&lt;br /&gt;
  m := GetIdentity(m);&lt;br /&gt;
  // die position aus der aktuellen cameramatrix in m speichern&lt;br /&gt;
  SetMatrixPos (m, v);&lt;br /&gt;
  // m als aktuelle cameramatrix speichern&lt;br /&gt;
  CameraMatrix.Load(m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.InverseMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := CameraMatrix.InverseMatrix;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Initiate;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    SavePosition (i);&lt;br /&gt;
  Initiated := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpdateMatrixOffset (newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // wenn ich mit Multiply (FixedAxis) arbeite, wird die zeichnung immer&lt;br /&gt;
  // entlang der bildschirmachsen verschoben. wenn ich Multiply, version 2&lt;br /&gt;
  // nehme, wird sie auf den errechneten achsen verschoben.&lt;br /&gt;
  if FFixedAxis then begin&lt;br /&gt;
    result := Multiply (newMatrix, CameraMatrix.Matrix);&lt;br /&gt;
  end&lt;br /&gt;
  else begin&lt;br /&gt;
    result := Multiply (CameraMatrix.Matrix, newMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
// setzt den viewpoint oder rotationpoint  ohne die anderen parameter zu&lt;br /&gt;
// veraendern. so kann man z.B. eine Kamerafahrt in immer der gleichen&lt;br /&gt;
// position simulieren.&lt;br /&gt;
begin&lt;br /&gt;
  FPointOfRotation := NewPoint;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Debug (Text: string);&lt;br /&gt;
begin&lt;br /&gt;
  if not FDebugOn then&lt;br /&gt;
    exit;&lt;br /&gt;
  writeln (FDebugFile, DateToStr (date) + ' | ' +&lt;br /&gt;
                       TimeToStr (time) + ' | ' +&lt;br /&gt;
                       Text);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyInvers;&lt;br /&gt;
var&lt;br /&gt;
  M: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // Um Objekte immer zum benutzer ausrichten, darf nur die drehung angewendet&lt;br /&gt;
  // werden und nicht die verschiebung. Verschiebung wird hier zurückgenommen.&lt;br /&gt;
  // Vorher muss die Kamera angewendet und die nötigen Verschiebungen/&lt;br /&gt;
  // Drehungen ausgeführt werden.&lt;br /&gt;
  M := InverseMatrix;&lt;br /&gt;
  M[12] := 0;&lt;br /&gt;
  M[13] := 0;&lt;br /&gt;
  M[14] := 0;&lt;br /&gt;
  M[15] := 1;&lt;br /&gt;
  glMultMatrixd(@M);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.HandleKeyboardInput (Key: Word; Shift: TShiftState): boolean;&lt;br /&gt;
// diese funktion sollte zur steuerung des bildschirmablaufs gewählt werden,&lt;br /&gt;
// wenn nicht auf die tasteneingabe gewartet wird (bildschirmaufbau nach&lt;br /&gt;
// timer-event).&lt;br /&gt;
// in der Timermethode zB.:&lt;br /&gt;
// if FCamera.HandleDeviceInput then&lt;br /&gt;
//   Render;  // oder wie die routine bei euch heißt ...&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
&lt;br /&gt;
  if not FAltPressed then FAltPressed := ssAlt in Shift;&lt;br /&gt;
  if not FCtrlPressed then FCtrlPressed := ssCtrl in Shift;&lt;br /&gt;
  // das mit Key=16 ist ´ne krücke, aber sendmessage mit VK_SHIFT klappt&lt;br /&gt;
  // bei mir nicht!&lt;br /&gt;
  if not FShiftPressed then FShiftPressed := (ssShift in Shift) or (Key = 16);&lt;br /&gt;
&lt;br /&gt;
  case Key of&lt;br /&gt;
    CKeyCameraHome:           // (ausgangsposition)&lt;br /&gt;
    begin&lt;br /&gt;
      if not (FAltPressed or FCtrlPressed or FShiftPressed) then begin&lt;br /&gt;
        CameraHome;&lt;br /&gt;
        result := true;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    CKeyCameraAdjust:&lt;br /&gt;
    begin                     // (ausrichten)&lt;br /&gt;
      Adjust;&lt;br /&gt;
      result := true;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT:&lt;br /&gt;
      result := ProcessArrowKeys (Key, Shift);&lt;br /&gt;
  else                        // case&lt;br /&gt;
    if (Key &amp;gt; $29) and (Key &amp;lt; $40) then begin   // 0 - 9&lt;br /&gt;
      if FAltPressed then begin                 // position speichern?&lt;br /&gt;
        SavePosition(Key-48);&lt;br /&gt;
        result := true;&lt;br /&gt;
      end;&lt;br /&gt;
      if FShiftPressed then begin&lt;br /&gt;
        RestorePosition(Key-48);&lt;br /&gt;
        result := true;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.ProcessArrowKeys (Key: integer; Shift: TShiftState): boolean;&lt;br /&gt;
// arbeitet die für die jeweiligen kameraaktionen definierten tastendrücke&lt;br /&gt;
// ab. hierbei werden wie gewünscht die kameraeigenschaften geändert:&lt;br /&gt;
// lage, position, ...&lt;br /&gt;
var&lt;br /&gt;
  POR: TGLVector;&lt;br /&gt;
  nDir: double;&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
&lt;br /&gt;
  nDir := 1.0*FSpeedMultiplier;&lt;br /&gt;
  if FDir then&lt;br /&gt;
    nDir := -1.0;&lt;br /&gt;
&lt;br /&gt;
  case Key of&lt;br /&gt;
  VK_UP:            // Szene aus dem Drehpunkt entlang der vertikalen&lt;br /&gt;
  begin             // verschieben&lt;br /&gt;
    if ssShift in Shift then begin&lt;br /&gt;
      RotateScene (DIR_HORIZONTAL, GiveSpeed*-1.0);&lt;br /&gt;
    end else begin&lt;br /&gt;
      POR := PointOfRotation;&lt;br /&gt;
      POR.Y := POR.Y + nDir;&lt;br /&gt;
      PointOfRotation := POR;&lt;br /&gt;
    end;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  VK_DOWN:          // Szene aus dem Drehpunkt entlang der vertikalen&lt;br /&gt;
  begin             // verschieben&lt;br /&gt;
    if ssShift in Shift then begin&lt;br /&gt;
      RotateScene (DIR_HORIZONTAL, GiveSpeed);&lt;br /&gt;
    end else begin&lt;br /&gt;
      POR := PointOfRotation;&lt;br /&gt;
      POR.Y := POR.Y - nDir;&lt;br /&gt;
      PointOfRotation := POR;&lt;br /&gt;
    end;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  VK_LEFT:          // Szene aus dem Drehpunkt entlang der horizontalen&lt;br /&gt;
  begin             // verschieben&lt;br /&gt;
    if ssShift in Shift then begin&lt;br /&gt;
      RotateScene (DIR_VERTIKAL, GiveSpeed*-1.0);&lt;br /&gt;
    end else begin&lt;br /&gt;
      POR := PointOfRotation;&lt;br /&gt;
      POR.X := POR.X - nDir;&lt;br /&gt;
      PointOfRotation := POR;&lt;br /&gt;
    end;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  VK_RIGHT:         // Szene aus dem Drehpunkt entlang der horizontalen&lt;br /&gt;
  begin             // verschieben&lt;br /&gt;
    if ssShift in Shift then begin&lt;br /&gt;
      RotateScene (DIR_VERTIKAL, GiveSpeed);&lt;br /&gt;
    end else begin&lt;br /&gt;
      POR := PointOfRotation;&lt;br /&gt;
      POR.X := POR.X + nDir;&lt;br /&gt;
      PointOfRotation := POR;&lt;br /&gt;
    end;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  VK_PRIOR:         // Szene aus dem Drehpunkt entlang der Bildschirmachse&lt;br /&gt;
  begin             // verschieben&lt;br /&gt;
    if ssShift in Shift then begin&lt;br /&gt;
      RotateScene (DIR_ZENTRAL, GiveSpeed*-1.0);&lt;br /&gt;
    end else begin&lt;br /&gt;
      POR := PointOfRotation;&lt;br /&gt;
      POR.Z := POR.Z - nDir;&lt;br /&gt;
      PointOfRotation := POR;&lt;br /&gt;
    end;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  VK_NEXT:          // Szene aus dem Drehpunkt entlang der Bildschirmachse&lt;br /&gt;
  begin             // verschieben&lt;br /&gt;
    if ssShift in Shift then begin&lt;br /&gt;
      RotateScene (DIR_ZENTRAL, GiveSpeed);&lt;br /&gt;
    end else begin&lt;br /&gt;
      POR := PointOfRotation;&lt;br /&gt;
      POR.Z := POR.Z + nDir;&lt;br /&gt;
      PointOfRotation := POR;&lt;br /&gt;
    end;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);&lt;br /&gt;
// überprüfen ob eine sondertaste wieder losgelassen wurde&lt;br /&gt;
begin&lt;br /&gt;
  if not (ssAlt in Shift) then&lt;br /&gt;
    FAltPressed := false;&lt;br /&gt;
  if not (ssCtrl in Shift) then&lt;br /&gt;
    FCtrlPressed := false;&lt;br /&gt;
  if not (ssAlt in Shift) then&lt;br /&gt;
    FShiftPressed := false;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.KeyDown(Sender: TObject; var Key: Word;&lt;br /&gt;
  Shift: TShiftState): boolean;&lt;br /&gt;
var&lt;br /&gt;
  POR: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // hier werden die aktionen für die angezeigten tastenbelegungen&lt;br /&gt;
  // umgesetzt&lt;br /&gt;
  result := false;&lt;br /&gt;
&lt;br /&gt;
  // wie bei den maustasten: merken, ob eine sondertaste gedrückt&lt;br /&gt;
  // wurde um feststellen zu können ob diese gehalten wird. in&lt;br /&gt;
  // KeyUp wird der zustand entsprechend zurückgesetzt.&lt;br /&gt;
  if not FAltPressed then FAltPressed := ssAlt in Shift;&lt;br /&gt;
  if not FCtrlPressed then FCtrlPressed := ssCtrl in Shift;&lt;br /&gt;
  if not FShiftPressed then FShiftPressed := (ssShift in Shift);&lt;br /&gt;
&lt;br /&gt;
  case key of&lt;br /&gt;
  ord ('A'):        // Szene zum Benutzer ausrichten. Position wird&lt;br /&gt;
  begin             // nicht verändert&lt;br /&gt;
    Adjust;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT:&lt;br /&gt;
    result := ProcessArrowKeys (Key, Shift);&lt;br /&gt;
  ord('0'):         // den Drehpunkt in den Nullpunkt schieben. Die&lt;br /&gt;
  begin             // Kameraposition bleibt unverändert.&lt;br /&gt;
    InitVector (POR, 0, 0, 0);&lt;br /&gt;
    PointOfRotation := POR;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  ord('I'):         // Dreh- und Bewegungsrichtung umschalten&lt;br /&gt;
  begin&lt;br /&gt;
    FDir := not FDir;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  ord('U'):         // Umschalten zwischen Drehung/Bewegung entlang der&lt;br /&gt;
  begin             // angezeigten Achsen bzw. Bildschirmachsen&lt;br /&gt;
    FixedAxis := not FixedAxis;&lt;br /&gt;
    result := true;&lt;br /&gt;
  end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.MouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                            Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
// hier merken wir uns, welche Maustaste gedrückt wurde. Solange die&lt;br /&gt;
// Tastenvariable true ist, kann abgeprüft werden ob die Taste gedrückt&lt;br /&gt;
// ist. In MouseUp wird die entsprechende Variable wieder auf false&lt;br /&gt;
// gesetzt.&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
  end else if Button = mbLeft then begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
  end;&lt;br /&gt;
  //Startposition für die Mausbewegung merken&lt;br /&gt;
  FxStart := X;&lt;br /&gt;
  FyStart := Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.MouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                          Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
// eine maustaste wurde losgelassen. mal sehen, ob eine aktion&lt;br /&gt;
// unterbunden werden muss.&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end else if Button = mbLeft then begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.MouseMove(Sender: TObject; Shift: TShiftState; X,&lt;br /&gt;
                           Y: Integer): boolean;&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
  //Verschieben und Drehen funktioniert nur, wenn eine Maustaste&lt;br /&gt;
  // gedrückt ist&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  //berechnen, wie weit die Maus verschoben wurde&lt;br /&gt;
  FxDelta := FxStart-X;&lt;br /&gt;
  FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
  //anpassen, damit es nicht zu schnell geht&lt;br /&gt;
  FxRot := FxRot - FyDelta;&lt;br /&gt;
  Fyrot := FyRot - FxDelta;&lt;br /&gt;
&lt;br /&gt;
  //Startpunkt für den nächsten Aufruf festlegen&lt;br /&gt;
  FxStart := X;&lt;br /&gt;
  FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
  // Rechte Maustaste:&lt;br /&gt;
  // Kamera drehen (vertikal bei Maus hoch/runter,&lt;br /&gt;
  //                horizontal bei Maus links/rechts&lt;br /&gt;
  //                um die Bildschirmachse bei Mausrad oder wenn shift)&lt;br /&gt;
  if FRightMousePressed then begin&lt;br /&gt;
    if FShiftPressed then begin&lt;br /&gt;
      // wenn kein mausrad vorhanden ist, soll das ja auch gehen&lt;br /&gt;
      if FyRot+FxRot &amp;lt;&amp;gt; 0 then begin&lt;br /&gt;
        RotateScene (DIR_ZENTRAL, (FyRot+FxRot)*GiveSpeed);&lt;br /&gt;
      end;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
      if FxRot &amp;lt;&amp;gt; 0 then begin&lt;br /&gt;
        RotateScene (DIR_HORIZONTAL, FxRot*GiveSpeed);&lt;br /&gt;
      end;&lt;br /&gt;
      if FyRot &amp;lt;&amp;gt; 0 then begin&lt;br /&gt;
        RotateScene (DIR_VERTIKAL, FyRot*GiveSpeed);&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // Linke Maustaste:&lt;br /&gt;
  // Kamera bewegen (vertikal bei Maus hoch/runter,&lt;br /&gt;
  //                horizontal bei Maus links/rechts&lt;br /&gt;
  //                entlang der Bildschirmachse bei Mausrad oder wenn shift)&lt;br /&gt;
  if FLeftMousePressed then begin&lt;br /&gt;
    if FShiftPressed then begin&lt;br /&gt;
      // wenn kein mausrad vorhanden ist, soll das ja auch gehen&lt;br /&gt;
      if FyRot+FxRot &amp;lt;&amp;gt; 0 then begin&lt;br /&gt;
        MoveScene (DIR_ZENTRAL, (FyRot+FxRot)*GiveSpeed);&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
      if FxRot &amp;lt;&amp;gt; 0 then begin&lt;br /&gt;
        MoveScene (DIR_HORIZONTAL, FxRot*GiveSpeed);&lt;br /&gt;
      end;&lt;br /&gt;
      if FyRot &amp;lt;&amp;gt; 0 then begin&lt;br /&gt;
        MoveScene (DIR_VERTIKAL, -FyRot*GiveSpeed);&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FxRot := 0;&lt;br /&gt;
  FyRot := 0;&lt;br /&gt;
&lt;br /&gt;
  result := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateScene (Direction: byte;&lt;br /&gt;
                               Geschwindigkeit: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  if Direction = DIR_HORIZONTAL then // um die X-Achse drehenx&lt;br /&gt;
  begin&lt;br /&gt;
    RotateCamera(0, Geschwindigkeit, 0);&lt;br /&gt;
  end&lt;br /&gt;
  else if Direction = DIR_VERTIKAL then // um die y-Achse drehen&lt;br /&gt;
  begin&lt;br /&gt;
    RotateCamera (Geschwindigkeit, 0, 0);&lt;br /&gt;
  end&lt;br /&gt;
  else if Direction = DIR_ZENTRAL then // um die z-Achse drehen&lt;br /&gt;
  begin&lt;br /&gt;
    RotateCamera(0, 0, Geschwindigkeit);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GiveSpeed: TGLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // Initiale Geschwindigkeit&lt;br /&gt;
  result := 1;&lt;br /&gt;
&lt;br /&gt;
  // wenn die Geschwindigkeit für eine Mausbewegung oder -drehung ist, soll&lt;br /&gt;
  // es nicht so schnell gehen&lt;br /&gt;
  if FRightMousePressed or FLeftMousePressed then begin&lt;br /&gt;
    result := result / 20;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // wenn die alt-taste gedrückt wurde, soll es ja schneller gehen&lt;br /&gt;
  if FAltPressed then begin&lt;br /&gt;
    result := (result * 60.0);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // jetzt mit dem individuellen speemultiplier multiplizieren&lt;br /&gt;
  result := result * FSpeedMultiplier;&lt;br /&gt;
&lt;br /&gt;
  // wenn die drehrichtung umgeschaltet wurde, hier auch&lt;br /&gt;
  // umschalten&lt;br /&gt;
  if FDir then begin&lt;br /&gt;
    result := -result;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.MoveScene (Direction: byte; Geschwindigkeit: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  if Direction = DIR_VERTIKAL then begin&lt;br /&gt;
    TranslateCamera (Geschwindigkeit, 0, 0);&lt;br /&gt;
  end;&lt;br /&gt;
  if Direction = DIR_HORIZONTAL then begin&lt;br /&gt;
    TranslateCamera (0, Geschwindigkeit, 0);&lt;br /&gt;
  end;&lt;br /&gt;
  if Direction = DIR_ZENTRAL then begin&lt;br /&gt;
    TranslateCamera (0, 0, Geschwindigkeit);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.MouseWheel(Sender: TObject; Shift: TShiftState;&lt;br /&gt;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean): boolean;&lt;br /&gt;
begin&lt;br /&gt;
  if FRightMousePressed then begin&lt;br /&gt;
    RotateScene (DIR_ZENTRAL, (WheelDelta/10)*GiveSpeed);&lt;br /&gt;
  end&lt;br /&gt;
  else begin&lt;br /&gt;
    MoveScene (DIR_ZENTRAL, (WheelDelta/360)*GiveSpeed);&lt;br /&gt;
  end;&lt;br /&gt;
  result := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.MouseEnter(var msg:TMessage);&lt;br /&gt;
begin&lt;br /&gt;
  FRightMousePressed:=false;&lt;br /&gt;
  FLeftMousePressed:=false;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.MouseLeave(var msg: TMessage);&lt;br /&gt;
begin&lt;br /&gt;
  FRightMousePressed:=false;&lt;br /&gt;
  FLeftMousePressed:=false;&lt;br /&gt;
  FAltPressed := false;&lt;br /&gt;
  FCtrlPressed := false;&lt;br /&gt;
  FShiftPressed := false;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
Initialization&lt;br /&gt;
  FDebugOn := false; // auf true setzen, wenn debug infos gewünscht sind&lt;br /&gt;
  FDebugFileName := ExePath + 'SKANAL3D_CAMERA.DBG';&lt;br /&gt;
  if FDebugOn then begin&lt;br /&gt;
    AssignFile (FDebugFile, FDebugFileName);&lt;br /&gt;
    Rewrite (FDebugFile);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
finalization&lt;br /&gt;
  if FDebugOn then begin&lt;br /&gt;
    CloseFile (FDebugFile);&lt;br /&gt;
    FDebugFileName := '';&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=21089</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=21089"/>
				<updated>2008-02-05T04:51:40Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
Die hier vorzufindende Beschreibung stellt keine komplette Anleitung für die Verwendung der Kamera dar. Um bis in die &amp;quot;Tiefen&amp;quot; des Objekts hinabzusteigen seht Euch bitte das von mir bereit gestellte Beispielprogramm an ([[Kamera]]). Wenn Ihr das herunterladet habt Ihr auch auf jeden Fall die neueste Version der Sourcen, die ich zuletzt am 26.12.2007 aktualisert habe. Diese Sourcen vereinfachen die Verarbeitung von Tastatur- und Mausevents. Die u.a. Anleitung entspricht daher nicht mehr dem aktuellen vorgehen, kann aber auch weiterhin so angewendet werden.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then&lt;br /&gt;
    Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFExample.Render: wglMakeCurrent failed with ';&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=21088</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=21088"/>
				<updated>2008-02-05T04:43:29Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[http://files.delphigl.com/Download/kamera_heyroth.zip&lt;br /&gt;
]]. Dieses Programm habe ich am 26.12.2007 aktualisiert um die Steuerung per Tastatur und Maus zu vereinfachen. Die bisher in den das Modul benutzenden Methoden KeyDown, KeyUp, ModeDown, MouseUp  usw. nötigen Tätigkeiten habe ich in Kameramethoden ausgelagert. Dadurch kann mit einem einzigen Aufruf dieser Methode(n) die nötige Arbeit abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=20713</id>
		<title>Kamera (2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=20713"/>
				<updated>2007-08-20T08:52:34Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Wie ich selber immer wieder merken muss, ist eine Software anscheinend&lt;br /&gt;
// nie fertig. Immer moechte man etwas verbessern oder neue Features&lt;br /&gt;
// einbauen.&lt;br /&gt;
// Sollte also jemand Änderungs- oder Verbesserungsvorschläge haben oder&lt;br /&gt;
// neue Ideen einbringen wollen, oder sollten Verstaendnisfragen bestehen,&lt;br /&gt;
// so mailt bitte an&lt;br /&gt;
//&lt;br /&gt;
// SpamAndi@gmx.de&lt;br /&gt;
//&lt;br /&gt;
// Danke.&lt;br /&gt;
//&lt;br /&gt;
// Updates:&lt;br /&gt;
//&lt;br /&gt;
// 06.11.2005&lt;br /&gt;
// Die Deklaration der DESTROY Methode war falsch. Das fuehrte dazu,&lt;br /&gt;
// dass in der Methode CREATE erzeugte Objekte nicht richtig frei-&lt;br /&gt;
// gegeben wurden und es zu EAccessViolations kam. Die Methode wird&lt;br /&gt;
// jetzt in der PUBLIC Section mit der Direktive OVERRIDE aufgerufen.&lt;br /&gt;
//&lt;br /&gt;
// 11.11.2005&lt;br /&gt;
// Die Positionierung funktioniert jetzt.&lt;br /&gt;
// Wegen eines Verstaendnisproblems wurden die Positionen immer auf den&lt;br /&gt;
// Kamerapunkt aufaddiert. Das bedeutete, dass die Positionierung aus&lt;br /&gt;
// dem Ruder lief wenn sie nicht im Nullpunkt stattfand. Je groesser die&lt;br /&gt;
// gewuenschte Position war um so groesser war die Abweichung von der&lt;br /&gt;
// Darstellung.&lt;br /&gt;
// Ich habe nicht bedacht, dass bei einer &amp;quot;Kamera&amp;quot;-bewegung und -drehung&lt;br /&gt;
// ja eigentlich die Szene bewegt und gedreht wird. Deswegen wurden nach&lt;br /&gt;
// einer Positionierung die folgenden Projektionen immer basierend auf der&lt;br /&gt;
// danach gueltigen Kameraposition gemacht.&lt;br /&gt;
// Jetzt wird die Position so gesetzt, dass die gewuenschte Kameraposition&lt;br /&gt;
// immer vor dem Betrachter steht.&lt;br /&gt;
//&lt;br /&gt;
// 23.11.2005&lt;br /&gt;
// Neues Flag (FFixedAxis) zur Entscheidung zwischen angepasster und realer&lt;br /&gt;
// Drehung. Dadurch wird das Bewegungsmodell angepasst. Siehe Methode Offset,&lt;br /&gt;
// bzw. UpdateMatrixOffset.&lt;br /&gt;
//&lt;br /&gt;
// 10.12.2005&lt;br /&gt;
// Property PointOfRotation ist jetzt nicht mehr ReadOnly.&lt;br /&gt;
// Der Blickpunkt bzw. Rotationspunkt kann jetzt direkt verändert werden.&lt;br /&gt;
// So kann eine neue Blickrichtung angenommen werden ohne vorher die Kamera-&lt;br /&gt;
// eigenschaften zu sichern und nach einem PositionCamera wieder zu setzen.&lt;br /&gt;
//&lt;br /&gt;
// 19.12.2005&lt;br /&gt;
// Neue Methode PositionCross.&lt;br /&gt;
// Die Methode PositionCross schiebt das Fadenkreuz in den angegebenen Punkt&lt;br /&gt;
// ohne die Lage der Szene zu verändern. Diese Funktionalitaet ist anders als&lt;br /&gt;
// ein neues Setzen der Property FPointOfRotation weil dabei die Szene in das&lt;br /&gt;
// Koordinatenkreuz geschoben wird.&lt;br /&gt;
//&lt;br /&gt;
// 31.01.2006&lt;br /&gt;
// Umstellung auf genaueres Zahlenformat&lt;br /&gt;
// Da die Darstellung von Szenen ausserhalb des Bereichs von FLOAT-Zahlen&lt;br /&gt;
// nicht funktioniert, muss alles auf DOUBLE umgestellt werden. Dazu gehört&lt;br /&gt;
// das Ersetzen von Datentypen und der Aufruf der entsprechenden GL-Funktionen.&lt;br /&gt;
//&lt;br /&gt;
unit Camera;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
  Uses DglOpenGL, Util, Windows, Classes;&lt;br /&gt;
&lt;br /&gt;
  type&lt;br /&gt;
  TCameraMatrix=Class&lt;br /&gt;
    StackMatrix: array [0..9] of TArrMatrix;&lt;br /&gt;
    StackCtr: integer;&lt;br /&gt;
    Matrix: TArrMatrix;&lt;br /&gt;
    InverseMatrix: TArrMatrix;&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    //destructor destroy;&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Push;&lt;br /&gt;
    procedure Pop;&lt;br /&gt;
    procedure Load(M: TArrMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TCamera=Class&lt;br /&gt;
    Enabled: boolean;&lt;br /&gt;
    function UpVector: TGLvector;&lt;br /&gt;
    procedure RestorePosition(pos: integer);&lt;br /&gt;
    procedure SavePosition(pos: integer);&lt;br /&gt;
    function GiveStoredPosition(pos: integer): TGLvector;&lt;br /&gt;
    procedure RotateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
    procedure TranslateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
    procedure CameraHome;&lt;br /&gt;
    procedure PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector);&lt;br /&gt;
    procedure Adjust;&lt;br /&gt;
    procedure Apply;&lt;br /&gt;
    procedure ApplyForTerrain;&lt;br /&gt;
  private&lt;br /&gt;
    FPosition: TGLvector;&lt;br /&gt;
    FViewDirection: TGLvector;&lt;br /&gt;
    FPointOfRotation: TGLvector;&lt;br /&gt;
    HomeMatrix: TCameraMatrix;&lt;br /&gt;
    CameraMatrix: TCameraMatrix;&lt;br /&gt;
    Initiated: boolean;&lt;br /&gt;
    PosArray: array [0..9] of TCameraMatrix;&lt;br /&gt;
    RotArray: array [0..9] of TGLvector;&lt;br /&gt;
    FFixedAxis: boolean;&lt;br /&gt;
    procedure Debug (Text: string);&lt;br /&gt;
    function UpdateMatrixOffset(newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
    function GetViewDirection: TGLvector;&lt;br /&gt;
    procedure SetViewDirection (View: TGLvector);&lt;br /&gt;
    procedure Initiate;&lt;br /&gt;
    function GetPosition: TGLvector;&lt;br /&gt;
    procedure SetPosition (Pos: TGLvector);&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Offset(x, y, z: GLdouble);&lt;br /&gt;
    procedure RotateRoundAxis(rx, ry, rz: GLdouble);&lt;br /&gt;
    procedure SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    destructor Destroy;override;&lt;br /&gt;
    function InverseMatrix: TArrMatrix;&lt;br /&gt;
    procedure ApplyInvers;&lt;br /&gt;
    procedure PositionCross(CrossVec: TGLvector);&lt;br /&gt;
  published&lt;br /&gt;
    property PointOfRotation: TGLvector read FPointOfRotation write SetPointOfRotation;&lt;br /&gt;
    property Position: TGLvector read GetPosition write SetPosition;&lt;br /&gt;
    property ViewDirection: TGLvector read GetViewDirection write SetViewDirection;&lt;br /&gt;
    property FixedAxis: boolean read FFixedAxis write FFixedAxis;&lt;br /&gt;
  end;&lt;br /&gt;
  TPCamera=^TCamera;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FDebugFile: Textfile;&lt;br /&gt;
  FDebugFileName: string;&lt;br /&gt;
  FDebugOn: boolean;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses SysUtils;&lt;br /&gt;
&lt;br /&gt;
constructor TCameraMatrix.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
  StackCtr := 0;&lt;br /&gt;
end;&lt;br /&gt;
{&lt;br /&gt;
destructor TCameraMatrix.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Push;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; -1) and (StackCtr &amp;lt; 10) then&lt;br /&gt;
  begin&lt;br /&gt;
    StackMatrix[StackCtr] := Matrix;&lt;br /&gt;
    inc (StackCtr);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Pop;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; 0) and (StackCtr &amp;lt; 11) then&lt;br /&gt;
  begin&lt;br /&gt;
    dec (StackCtr);&lt;br /&gt;
    Load (StackMatrix[StackCtr]);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Identity;&lt;br /&gt;
// GetIdentity: aus OpenGL.pas&lt;br /&gt;
// initialisiert die CameraMatrix mit der Identitaetsmatrix&lt;br /&gt;
begin&lt;br /&gt;
  Matrix := GetIdentity(Matrix);&lt;br /&gt;
  InverseMatrix := GetIdentity(InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Load(M: TArrMatrix);&lt;br /&gt;
// die Matrix mit den Werten einer beliebigen anderen matrix fuellen&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i:=0 to 15 do&lt;br /&gt;
    Matrix[i]:=M[i];&lt;br /&gt;
  // die invertierte Matrix kann benutzt werden um Objkekte z.B.&lt;br /&gt;
  // immer zum Benutzer auszurichten&lt;br /&gt;
  InvertMatrix (M, InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
constructor TCamera.Create;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
&lt;br /&gt;
  // Initiated wird gebraucht um einmal alle Positionsspeicher&lt;br /&gt;
  // mit der Anfangsposition zu belegen&lt;br /&gt;
  Initiated := false;&lt;br /&gt;
&lt;br /&gt;
  // Kameramatrix anlegen&lt;br /&gt;
  CameraMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Matrix der letzten Position von PositionCamera anlegen&lt;br /&gt;
  HomeMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Positionsspeicher anlegen&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    PosArray[i] := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // standardmaessig immer entlang der bildschirmachsen verschieben&lt;br /&gt;
  FFixedAxis := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCamera.Destroy;&lt;br /&gt;
// alle in create belegten Resourcen wieder freigeben&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FreeAndNil (CameraMatrix);&lt;br /&gt;
  FreeAndNil (HomeMatrix);&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    FreeAndNil (PosArray[i]);&lt;br /&gt;
&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateRoundAxis(rx, ry, rz: GLdouble);&lt;br /&gt;
// hier drehen wir jetzt um die einzelnen Achsen.&lt;br /&gt;
// die Parameter geben die &amp;quot;Drehgeschwindigkeit&amp;quot; vor.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  tempX, tempY, tempZ: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Position und Lage der Kamera herstellen&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
&lt;br /&gt;
  if FFixedAxis then&lt;br /&gt;
  begin&lt;br /&gt;
    // über die bildschirmachsen drehen&lt;br /&gt;
    tempX := GetMatrixX (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempY := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempZ := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rx,tempX.X,tempX.Y,tempX.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(ry,tempY.X,tempY.Y,tempY.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rz,tempZ.X,tempZ.Y,tempZ.Z);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    // über die achsen des koordinatenkreuzes drehen&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rx,1,0,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(ry,0,1,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rz,0,0,1);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // die neu erzeugte Matrix auslesen&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  // und in die Kameramatrix sichern&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Identity;&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Identity;&lt;br /&gt;
  HomeMatrix.Identity;&lt;br /&gt;
&lt;br /&gt;
  Enabled := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Offset(x, y, z: GLdouble);&lt;br /&gt;
// verschieben der Kamera auf einer beliebigen Achse&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  //OldView: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- Offset - Start --------------------------------------------------');&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslated(x,y,z);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  Debug ('Position: '+GLvectorToText (GetMatrixPos (newMatrix)));&lt;br /&gt;
  newMatrix := UpdateMatrixOffset (newMatrix);&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  Debug ('- Offset - Ende- --------------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
			                           ViewVec: TGLvector;&lt;br /&gt;
			                           upVec: TGLvector);&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  i: integer;&lt;br /&gt;
  P, V, U: TGLvector;&lt;br /&gt;
  Laenge: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCamera - Start ------------------------------------------');&lt;br /&gt;
  // die gewuenschte konstruktion immer auf die Z-ebene projizieren.&lt;br /&gt;
  // zuerst die position in den nullpunkt holen&lt;br /&gt;
  InitVector (P, 0, 0, 0);&lt;br /&gt;
  // jetzt den viewpoint um den gleichen betrag reduzieren, damit&lt;br /&gt;
  // die gerade parallel verschoben wird.&lt;br /&gt;
  V := SubtractVector (ViewVec, PositionVec);&lt;br /&gt;
  // U ist halt schneller geschrieben als upVec...&lt;br /&gt;
  U := upVec;&lt;br /&gt;
&lt;br /&gt;
  // den betrag ermitteln, um den die kamera nachher auf der Z-Achse&lt;br /&gt;
  // verschoben werden muss&lt;br /&gt;
  Laenge := Magnitude (SubtractVector (P, V));&lt;br /&gt;
&lt;br /&gt;
  Identity;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  // glulookat wird die matrix parallel zur Z-achse ausrichten&lt;br /&gt;
  gluLookAt (P.X, P.Y, P.Z, V.X, V.Y, V.Z, U.X, U.Y, U.Z);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  HomeMatrix.Load(newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // da wir uns jetzt am zielpunkt befinden, müssen wir auf der Z-achse&lt;br /&gt;
  // wieder zurueck zur kameraposition&lt;br /&gt;
  Offset (0, 0, -Laenge);&lt;br /&gt;
&lt;br /&gt;
  // alle positionsspeicher mit der Kameraposition, Blickrichtung&lt;br /&gt;
  // und dem upVector belegen. Nur beim ersten Aufruf von&lt;br /&gt;
  // PositionCamera&lt;br /&gt;
  if not Initiated then&lt;br /&gt;
    Initiate;&lt;br /&gt;
&lt;br /&gt;
  FPointOfRotation := ViewVec;&lt;br /&gt;
  Debug ('PointOfRotation: '+GLvectorToText (FPointOfRotation));&lt;br /&gt;
  Debug ('- PositionCamera - Ende -------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCross (CrossVec: TGLvector);&lt;br /&gt;
// diese prozedur verschiebt, im gegensatz zu einem verändern von&lt;br /&gt;
// PointOfRotation, das Koordinatenkreuz und nicht die Szene.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  PosDiff: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCross - Start -------------------------------------------');&lt;br /&gt;
&lt;br /&gt;
  PosDiff := SubtractVector (FPointOfRotation, CrossVec);&lt;br /&gt;
&lt;br /&gt;
  // Szene in das koordinatenkreuz verschieben&lt;br /&gt;
  FPointOfRotation := CrossVec;&lt;br /&gt;
&lt;br /&gt;
  // jetzt die Szene wieder um den gleichen betrag zurückverschieben&lt;br /&gt;
  // das sieht dann so aus, als ob das koordinatenkreuz verschoben&lt;br /&gt;
  // worden wäre&lt;br /&gt;
  // zuerst die aktuelle neue Situation herstellen&lt;br /&gt;
  // (mit neuem FPointOfRotation)&lt;br /&gt;
  Apply;&lt;br /&gt;
&lt;br /&gt;
  // jetzt um den Differenzbetrag des alten und neuen&lt;br /&gt;
  // Rotationspunkts zurück verschieben&lt;br /&gt;
  glTranslated (-PosDiff.X, 0, 0);&lt;br /&gt;
  glTranslated (0, -PosDiff.Y, 0);&lt;br /&gt;
  glTranslated (0, 0, -PosDiff.Z);&lt;br /&gt;
&lt;br /&gt;
  // jetzt vom neuen Rotationspunktes zurück ins Zentrum, damit beim&lt;br /&gt;
  // nächsten Apply das glTranslatef (-FPointOfRotation, ...) klappt&lt;br /&gt;
  glTranslated (CrossVec.X, 0, 0);&lt;br /&gt;
  glTranslated (0, CrossVec.Y, 0);&lt;br /&gt;
  glTranslated (0, 0, CrossVec.Z);&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Matrix holen...&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // und als Kameramatrix abspeichern&lt;br /&gt;
  CameraMatrix.Load(newmatrix);&lt;br /&gt;
  Debug ('- PositionCross - Ende --------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.CameraHome;&lt;br /&gt;
// Kamera in die beim letzten Aufruf von PositionCamera uebergebene&lt;br /&gt;
// Position/Lage bringen&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Load(HomeMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SavePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  PosArray[pos].Load(CameraMatrix.Matrix);&lt;br /&gt;
  RotArray[pos] := FPointOfRotation;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RestorePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(PosArray[pos].Matrix);&lt;br /&gt;
  FPointOfRotation := RotArray[pos];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GiveStoredPosition (pos: integer): TGLvector;&lt;br /&gt;
// gibt den Inhalt des durch pos bestimmten&lt;br /&gt;
// Positionsspecihers zurueck&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  result := GetMatrixPos (PosArray[pos].Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.TranslateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Verschiebung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  Offset (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Drehung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  RotateRoundAxis (-iy, -ix, -iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Apply;&lt;br /&gt;
// hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur&lt;br /&gt;
// sollte die Szene mit allen benoetigten Drehungen, Verschiebungen&lt;br /&gt;
// gezeichnet werden.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
  glTranslated (-FPointOfRotation.X,&lt;br /&gt;
                -FPointOfRotation.y,&lt;br /&gt;
                -FPointOfRotation.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyForTerrain;&lt;br /&gt;
// hier wird wie in Apply die Kamera eingeschaltet. da man um ein terrain&lt;br /&gt;
// (skycube, ...) anzuzeigen aber immer die gleiche entfernung zur welt&lt;br /&gt;
// einhalten muss, wird hier nur gedreht und nicht verschoben.&lt;br /&gt;
var&lt;br /&gt;
  pos: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  // für das Terrain nur die Drehung ausführen&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
  // deswegen jetzt die verschiebung zurücknehmen&lt;br /&gt;
  Pos := GetMatrixPos (CameraMatrix.InverseMatrix);&lt;br /&gt;
  glTranslated (Pos.X, Pos.Y, Pos.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetPosition: TGLvector;&lt;br /&gt;
// diese Property-Funktion fragt die aktuelle Position der Kamera ab&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  result := AddVector (GetMatrixPos (CameraMatrix.InverseMatrix), FPointOfRotation);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPosition (Pos: TGLvector);&lt;br /&gt;
// diese Property-Funktion setzt eine neue Position der Kamera&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  m := CameraMatrix.Matrix;&lt;br /&gt;
  SetMatrixPos (m, SubtractVector (Pos, FPointOfRotation));&lt;br /&gt;
  CameraMatrix.Load (m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetViewDirection: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  result := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetViewDirection (View: TGLvector);&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// gesetzt werden&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  SetMatrixZ (CameraMatrix.InverseMatrix, View);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpVector: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Ausrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // upVector: zweite Spalte der Matrix (Y-Achse)&lt;br /&gt;
  result := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Adjust;&lt;br /&gt;
// mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhaengig&lt;br /&gt;
// von Drehung und Position, zur Y-Achse ausgerichtet werden.&lt;br /&gt;
// Die aktuelle Position wird dabei beibehalten.&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
  v: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // position aus der aktuellen cameramatrix holen&lt;br /&gt;
  v := GetMatrixPos (CameraMatrix.Matrix);&lt;br /&gt;
  // m mit identitätsmatrix initialisieren&lt;br /&gt;
  m := GetIdentity(m);&lt;br /&gt;
  // die position aus der aktuellen cameramatrix in m speichern&lt;br /&gt;
  SetMatrixPos (m, v);&lt;br /&gt;
  // m als aktuelle cameramatrix speichern&lt;br /&gt;
  CameraMatrix.Load(m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.InverseMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := CameraMatrix.InverseMatrix;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Initiate;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    SavePosition (i);&lt;br /&gt;
  Initiated := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpdateMatrixOffset (newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // wenn ich mit Multiply (FixedAxis) arbeite, wird die zeichnung immer&lt;br /&gt;
  // entlang der bildschirmachsen verschoben. wenn ich Multiply, version 2&lt;br /&gt;
  // nehme, wird sie auf den errechneten achsen verschoben.&lt;br /&gt;
  if FFixedAxis then&lt;br /&gt;
  begin&lt;br /&gt;
    result := Multiply (newMatrix, CameraMatrix.Matrix);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    result := Multiply (CameraMatrix.Matrix, newMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
// setzt den viewpoint oder rotationpoint  ohne die anderen parameter zu&lt;br /&gt;
// veraendern. so kann man z.B. eine Kamerafahrt in immer der gleichen&lt;br /&gt;
// position simulieren.&lt;br /&gt;
begin&lt;br /&gt;
  FPointOfRotation := NewPoint;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Debug (Text: string);&lt;br /&gt;
begin&lt;br /&gt;
  if not FDebugOn then&lt;br /&gt;
    exit;&lt;br /&gt;
  writeln (FDebugFile, DateToStr (date) + ' | ' +&lt;br /&gt;
                       TimeToStr (time) + ' | ' +&lt;br /&gt;
                       Text);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyInvers;&lt;br /&gt;
var&lt;br /&gt;
  M: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // Um Objekte immer zum benutzer ausrichten, darf nur die drehung angewendet&lt;br /&gt;
  // werden und nicht die verschiebung. Verschiebung wird hier zurückgenommen.&lt;br /&gt;
  // Vorher muss die Kamera angewendet und die nötigen Verschiebungen/&lt;br /&gt;
  // Drehungen ausgeführt werden. &lt;br /&gt;
  M := InverseMatrix;&lt;br /&gt;
  M[12] := 0;&lt;br /&gt;
  M[13] := 0;&lt;br /&gt;
  M[14] := 0;&lt;br /&gt;
  M[15] := 1;&lt;br /&gt;
  glMultMatrixd(@M);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
Initialization&lt;br /&gt;
  FDebugOn := false;&lt;br /&gt;
  FDebugFileName := ExePath + 'SKANAL3D_CAMERA.DBG';&lt;br /&gt;
  if FDebugOn then&lt;br /&gt;
  begin&lt;br /&gt;
    AssignFile (FDebugFile, FDebugFileName);&lt;br /&gt;
    Rewrite (FDebugFile);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
finalization&lt;br /&gt;
  if FDebugOn then&lt;br /&gt;
  begin&lt;br /&gt;
    CloseFile (FDebugFile);&lt;br /&gt;
    FDebugFileName := '';&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=20275</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=20275"/>
				<updated>2007-04-01T01:41:19Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Artikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
{{ZitatVon|Andyh| &lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Bisher glaubte ich, dass man mit der von mir erstellten Kurzanleitung auskommt, habe jetzt aber doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[http://files.delphigl.com/Download/kamera_heyroth.zip&lt;br /&gt;
]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=19894</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=19894"/>
				<updated>2006-11-28T12:45:59Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
Die hier vorzufindende Beschreibung stellt keine komplette Anleitung für die Verwendung der Kamera dar. Um bis in die &amp;quot;Tiefen&amp;quot; des Objekts hinabzusteigen seht Euch bitte das von mir bereit gestellte Beispielprogramm an ([[Kamera]]). Wenn Ihr das herunterladet habt Ihr auch auf jeden Fall die neueste Version der Sourcen.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then&lt;br /&gt;
    Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFExample.Render: wglMakeCurrent failed with ';&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19860</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19860"/>
				<updated>2006-11-12T04:56:35Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: Schreibfehler beseitigt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Kurzanleitung auskommt, habe ich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedingt nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[http://files.delphigl.com/Download/kamera_heyroth.zip&lt;br /&gt;
]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19816</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19816"/>
				<updated>2006-10-17T03:56:52Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: Link zum Beispielprogramm eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Kurzanleitung auskommt, habe ich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[http://files.delphigl.com/Download/kamera_heyroth.zip&lt;br /&gt;
]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19761</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19761"/>
				<updated>2006-10-12T07:37:08Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: Dateinamen OpenGLUtil.pas -&amp;gt; Util.pas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (Util.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Kurzanleitung auskommt, habe ich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[Kamera (1)]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19744</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19744"/>
				<updated>2006-10-09T17:02:12Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Kurzanleitung auskommt, habe ich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[Kamera (1)]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (AndyH).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19743</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19743"/>
				<updated>2006-10-09T16:48:36Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: Benutzeradresse eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Kurzanleitung auskommt, habe ich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[Kamera (1)]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung ([[Benutzer:AndyH|Andree Heyroth]]).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Techniken_und_Algorithmen&amp;diff=19721</id>
		<title>Techniken und Algorithmen</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Techniken_und_Algorithmen&amp;diff=19721"/>
				<updated>2006-10-07T14:00:45Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Artikel dieses Wiki-Abschnittes sind im Gegensatz zu den [[Tutorial]]s meist kürzer. Dafür enthalten sie mitunter sehr viel Code der direkt verwendet werden, oder als Grundlage für die eigene Arbeit dienen kann.&lt;br /&gt;
&lt;br /&gt;
== Was hier hinein gehört ==&lt;br /&gt;
Hier kommen, wie der Name vermuten lässt '''Erklärungen''' zu, in der 3D-Echtzeitprogrammierung verwendeten, '''Techniken''' hin. Z.B. verschiedene Schattentechniken, Bump-Mapping, etc.&lt;br /&gt;
&lt;br /&gt;
[[Hintergrundwissen]] gehört hier nicht rein. Sachen wie ''&amp;quot;was ist ein Tiefenpuffer und wofür ist er gut&amp;quot;'' haben hier nichts zu suchen.&amp;lt;br&amp;gt;&lt;br /&gt;
Sollte es für eine Technik/Thematik (siehe unten für Beispiel) mehrere &amp;quot;Lösungswege&amp;quot; geben, sollte eine kleine Überschrift eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr einen Technik oder Alorithmus Artikel erstellt, so solltet ihr unter den Artikel ein&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[Kategorie:Technik_oder_Algorithmus]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
stellen. Damit wird der Artikel der  [[:Kategorie:Technik_oder_Algorithmus]] zugeordnet.&lt;br /&gt;
Falls dieser Artikel nicht nur erklärt was der Begriff bedeutet, sondern auch noch eine Anleitung ist, wie man die entsprechende Technik realisiert, so könnt ihr den Artikel auch noch der Kategorie [[:Kategorie:Anleitung|Anleitung]] zuweisen.&lt;br /&gt;
&lt;br /&gt;
== Übersicht ==&lt;br /&gt;
=== Nützliche Helfer ===&lt;br /&gt;
In dieser Rubrik findet sich all das, was ein OpenGL/Graphikprogrammierer immer brauch oder schnell mal zur Hand haben muss:&lt;br /&gt;
* [[Framecounter]] (Wie schnell läuft mein Programm?)&lt;br /&gt;
* [[Texture Loader]] (Laden und verwalten von Texturen)&lt;br /&gt;
* [[Model Loader]] (Laden von Modellen die mit Programmen wie 3D Studio Max, Lightwave, Milkshape usw. erstellt wurden.)&lt;br /&gt;
* Eine Möglichkeit zum [[Text ausgeben]]&lt;br /&gt;
* [[Kamera]]&lt;br /&gt;
** [[Kamera (1)]] (Szene in drei Ebenen verschieben und drehen, jetzt mit Beispielprogramm)&lt;br /&gt;
** [[Kamera (2)]] (Kamera Source, letztes Update 1.10.2006)&lt;br /&gt;
** [[Kamera (3)]] (Für die Kamera benötigte Utilities)&lt;br /&gt;
* [[Extensionausgabe]] (Ausgabe der unterstützten Extensions und sonstiger Eigenschaften)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Geometrie Objekte ===&lt;br /&gt;
In dieser Rubrik findet ihr Code zum erzeugen von komplexen geometrischen Objekten, denn nicht immer ist die Kapselung die z.B. eine [[Quadrik]] bietet das was man sucht. &lt;br /&gt;
&lt;br /&gt;
* [[Kreis]]&lt;br /&gt;
* [[Kuchenstück]]&lt;br /&gt;
* [[Kugel]]&lt;br /&gt;
* [[Scheibe]]&lt;br /&gt;
* [[Würfel]]&lt;br /&gt;
* [[Zylinder]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Licht und Schatten ===&lt;br /&gt;
Das Beleuchtungsmodell von OpenGL besitzt von Haus aus keine Möglichkeit zur Darstellung von Schatten (nicht zuletzt weil es dafür immernoch keine einheitliche Methode gibt), allerdings haben sich über die Jahre hinweg einige Techniken mehr oder weniger durchgesetzt :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Lightmaps]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Projezierte Shadowmaps]] / [[Projezierte Textur]]en&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Volumetrische Stencilschatten]]{{excIcon}}&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Silhouette]] {{icpIcon}}&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Bloom(pseudo-HDR)]] {{icpIcon}}&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Statische Umgebungen ===&lt;br /&gt;
Besonders in Aussenszenen ist es oft nötig dem Betrachter den Eindruck zu vermitteln, er befinde sich in einer unendlich großen Umgebung. Da man dies jedoch schlecht über speziell dafür erstellte Geometrie lösen kann (weil das schlichtweg zu viel Aufwand und zu leistungsintensiv wäre), haben sich einige Techniken eingebürgert, mit denen man dem Betrachter eine solche unendliche Landschaft mit  wenig Geometrie und einigen Tricks vorgaugeln kann :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skyboxen]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skydome]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skysphere]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Dynamische Effekte ===&lt;br /&gt;
Das Auge ißt bekanntlich mit. Auch bei 3D Anwendungen, vor allem in der Unterhaltungsindustrie, spielen gigantische Effekte, die dem User ein &amp;quot;Ohhh&amp;quot; und &amp;quot;Ahhh&amp;quot; und vor allem &amp;quot;Wow!&amp;quot; entlocken eine immer größere Rolle. Wie man solche Effekte am besten implementiert finden Sie in den Artikeln dieses Abschnitts.&amp;lt;br&amp;gt;&lt;br /&gt;
(Befassen Sie sich zuerst mit den Grundlagen von [[Partikelsysteme|Partikelsystemen]].)&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Explosionen]] (Allseits gern gesehen. Außer in direkter Nachbarschaft)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Lichtsäulen]] (Bekannt für die magischen Momente in diversen Rollenspielen.) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Partikelsysteme]] {{excIcon}} (Grundlage für viele Effekte) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Natürliche Phänomene ===&lt;br /&gt;
Ziel vieler Echtzeit 3D-Anwendung (auch wenn genau der gegenteilige Trend manchmal interessant sein dürfte) ist eine zumindest optische Annäherung an die Realität, also Szenen möglichst &amp;quot;naturgetreu&amp;quot; (auch urbane Szenen können &amp;quot;naturgetreu&amp;quot; sein, auch wenn diese wenig natürlich sind) darzustellen. Dazu gehören auch natürliche Phänomene, wie z.B. realistisch spiegelndes Wasser, Wetterbedingungen (Regen, Schnee, Nebel), Feuer, etc. Oft gibt es für ein natürliches Phänomen recht fortgeschrittene Umsetzungsmöglichkeiten, manchmal liegt die Lösung aber auch recht nahe :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Bäume|Bäume]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Blitz]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Feuer]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Himmel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Nebel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Staub]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wasser]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wettereffekt]]e (Regen, Schnee)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wolken]] (als Ergänzung zu den statischen Umgebungen)&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raumunterteilungstechniken ===&lt;br /&gt;
Moderne 3D-Anwendungen müssen immer größere und komplexere 3D-Umgebungen darstellen, wobei oft jedoch große Teile eben dieser nicht sichtbar sind, aber ohne entsprechende Optimierungen trotzdem über den Datenbus geschoben (und von der Grafikkarte geclippt) werden müssen. Deshalb finden diverse Raumunterteilungstechniken (die u.a. aus anderen Bereichen stammen) in modernen 3D-Programmen Anwendung :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[BSP-Bäume]] (Binary Space Partitioning = Binäre Raumunterteilung)&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;[[Octree]]s (Dreidimensionale Erweiterung eines Quadtrees)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Portal]]e (Logische Sichtbegrenzung an Durchgängen)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[PVS]] (Potentially Visible Sets = Mögliche sichtbare Sets)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Terrain Darstellung ===&lt;br /&gt;
In vielen 3D Anwendungen, vom Flugsimulator über Egoshooter bis zum Strategiespiel, muss die Umgebung visualisiert werden. Welche Techniken bei der Speicherung (siehe auch '''Raumunterteilungstechniken'''), Bildaufbau und Texturierung zum Einsatz kommen, findet ihr hier:&amp;lt;br&amp;gt;&lt;br /&gt;
:'''[[LOD|Level of Detail]] Algorithmen für Landschaften'''&lt;br /&gt;
&lt;br /&gt;
*[[VDPM]] ('''V'''iew-'''D'''ependent '''P'''rogressive '''M'''eshes)&lt;br /&gt;
*[[ROAM]] ('''R'''eal-time '''O'''ptimally '''A'''dapting '''M'''eshes)&lt;br /&gt;
*[[Tutorial_Terrain3|Röttger Algorithmus]]&lt;br /&gt;
*[[Geometrical Mipmapping]]&lt;br /&gt;
*[[VIPMs]] ('''V'''iew '''I'''ndependent '''P'''rogressive '''M'''eshe'''s''')&lt;br /&gt;
&lt;br /&gt;
:'''Texturierung'''&lt;br /&gt;
&lt;br /&gt;
*[[Texture Splatting]] (Kombination von Texturen mittels [[Blenden|Blending]] und [[Multitexturing]])&lt;br /&gt;
*[[Texture Backing]] (Dynamisches erstellen von Texturen)&lt;br /&gt;
&lt;br /&gt;
=== Prozeduale Grafiken ===&lt;br /&gt;
Prozeduale Grafiken werden häufig verwendet um&lt;br /&gt;
*eine vielfältige Umgebung zu gewährleisten&lt;br /&gt;
*Speicherplatz auf der Festplatte zu sparen&lt;br /&gt;
*den Grafikern die Arbeit zu erleichtern (und teilweise sogar erst zu ermöglichen)&lt;br /&gt;
Die Algorithmen und Möglichkeiten die sich dabei bieten sind hier aufgelistet:&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Perlin Noise]] {{excIcon}} (Algorithmus für Texturen, Landschaft und vieles mehr)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[L-Systems]] (aus wenig mach viel, Landschaftsgenerierung, Baumgenerierung, ...)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Fault Formation]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Landschaft]] (Spezielle Hinweise und Techniken zur Landschaftsgenerierung&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Midpoint Displacement]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Hügel_Algorithmen]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Bäume]] (Techniken und Algorithmen speziell zur Baumgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Texturen]] (Spezielle Hinweise zu Wasser, Lava und ähnliches)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pathfinding ===&lt;br /&gt;
Pathfinding ist einer der grundlegenden Bereiche der Künstlichen Intelligenz, und aus diesem Grund für Spiele mit Computergegnern meistens unumgänglich.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Tiefensuche]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Breitensuche]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[A-Stern]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Dijkstra]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Floyd Warshall]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Navigation Meshes]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Pathfinding-Level of Detail]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sonstiges ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Screenshot]]s von OpenGL Ausgaben&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Interpolation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Bilder als Ressourcen]] speichern und laden&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Tesselierung|Polygone tesselieren]] &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Blenderscript|Exportscript für Blender]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Blenderexporter|Blenderexport ausführliche Anleitung]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Externe Links ==&lt;br /&gt;
Weitere Links zum Thema &amp;quot;Effekte unter OpenGL&amp;quot; findet ihr in der [[Link]]-Sammlung unter [[Link#Effekte_und_Techniken_mit_OpenGL|Effekte und Techniken mit OpenGL]].&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19720</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19720"/>
				<updated>2006-10-07T07:27:54Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Kurzanleitung auskommt, habe ich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt  nehmt einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, zur Textdarstellung, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätzlich habe ich noch den Memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zum ersten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[Kamera (1)]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andyh).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19719</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19719"/>
				<updated>2006-10-07T05:34:45Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Krzanleitung auskommt, hab eich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt, nehmet einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätlich habe ich noch den memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zume rsten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[Kamera (1)]].&lt;br /&gt;
&lt;br /&gt;
Aussehen sollte es nach dem Aufruf so:&lt;br /&gt;
&lt;br /&gt;
[[Bild:CameraExample.jpg]] &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andyh).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:CameraExample.jpg&amp;diff=19718</id>
		<title>Datei:CameraExample.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:CameraExample.jpg&amp;diff=19718"/>
				<updated>2006-10-07T05:31:23Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: Screenshot des Beispielprogramms&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Screenshot des Beispielprogramms&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19717</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19717"/>
				<updated>2006-10-07T05:26:09Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Krzanleitung auskommt, hab eich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt, nehmet einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätlich habe ich noch den memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zume rsten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm findet Ihr unter [[Kamera (1)]].&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andyh).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(3)&amp;diff=19716</id>
		<title>Kamera (3)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(3)&amp;diff=19716"/>
				<updated>2006-10-07T05:18:50Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&lt;br /&gt;
&lt;br /&gt;
Ich habe einfach alle Funktionen meiner Toolsammlung hierhin kopiert. Ich wollte jetzt nicht offline etwas weglöschen was vielleicht benötigt wird. Ihr findet also hier einen ganzen Wust von Funktionen, der zum Betrieb der Kamera nicht benötigt wird. Vielleicht könnt Ihr das eine oder andere aber brauchen...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Util;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses DglOpenGL, Math, Windows, Graphics, SysUtils, Dialogs{, glBmp};&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TProjection=(Frustum, Orthographic, Perspective);&lt;br /&gt;
&lt;br /&gt;
  TGLPlace=packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TScale=packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLPosition=packed record&lt;br /&gt;
    X,Y,Z,W: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TPosition = packed record&lt;br /&gt;
    X,Y,Z,W: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLVector = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
  TPGLvector=^TGLvector;&lt;br /&gt;
&lt;br /&gt;
  TTextureCoord=record&lt;br /&gt;
    X, Y, Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TTextureCoordArray = array of TTextureCoord;&lt;br /&gt;
  TGLvectorArray = array of TGLvector;&lt;br /&gt;
  TGLdoubleArray = array of GLdouble;&lt;br /&gt;
  TGLfloatArray = array of GLfloat;&lt;br /&gt;
&lt;br /&gt;
  TGKVector = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TAngle = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLColor=record&lt;br /&gt;
    red,green,blue,alpha: GLclampf;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TRotation = packed record&lt;br /&gt;
    angle, x, y, z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TTextureInfo = packed record&lt;br /&gt;
    BitmapName: string;&lt;br /&gt;
    TextureNum: GLUint;&lt;br /&gt;
    //theBmp: TGLbmp;&lt;br /&gt;
  end;&lt;br /&gt;
  TTextureList = array of TTextureInfo;&lt;br /&gt;
&lt;br /&gt;
  TMatrix = array [0..3,0..3] of GLdouble;&lt;br /&gt;
  TArrMatrix = array [0..15] of GLdouble;&lt;br /&gt;
  TFrustum = array [0..5,0..3] of GLdouble;&lt;br /&gt;
  TArrVector = array [0..3] of GLdouble;&lt;br /&gt;
&lt;br /&gt;
  function GetMatrixX (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixY (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixZ (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixPos (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  procedure SetMatrixX (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixY (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixZ (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixPos (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  function Multiply (Color: TGLcolor; m: GLdouble): TGLcolor;overload;&lt;br /&gt;
  function Multiply (V1, V2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function Multiply (M1, M2: TArrMatrix): TArrMatrix;overload;&lt;br /&gt;
  function Divide (V1, V2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function Divide (V1: TGLVector; d: GLdouble): TGLVector;overload;&lt;br /&gt;
  function MakeVector(X,Y,Z:GLdouble):TArrVector;overload;&lt;br /&gt;
  function MakeVector(X,Y,Z,W:GLdouble):TArrVector;overload;&lt;br /&gt;
  function Normalize(aVector:TArrVector):TArrVector;overload;&lt;br /&gt;
  function Normalize(aVector:TGLVector):TGLVector;overload;&lt;br /&gt;
  function GetIdentity(Matrix:TMatrix):TMatrix;overload;&lt;br /&gt;
  function GetIdentity(Matrix:TArrMatrix):TArrMatrix;overload;&lt;br /&gt;
  function MatrixTranspose(const M:TMatrix):TMatrix;register;&lt;br /&gt;
  function NearestPoint(Axis, Point: TGLVector): TGLVector;&lt;br /&gt;
  function VectorRotateX(v:TArrVector;a:GLdouble):TArrVector;overload;&lt;br /&gt;
  function VectorRotateY(v:TArrVector;a:GLdouble):TArrVector;overload;&lt;br /&gt;
  function VectorRotateZ(v:TArrVector;a:GLdouble):TArrVector;overload;&lt;br /&gt;
  function VectorRotateX(v:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateX(v,c:TGLvector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v,c:TGLvector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v,c:TGLvector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateX(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;overload;&lt;br /&gt;
&lt;br /&gt;
  function AxisXRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
  function AxisYRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
  function AxisZRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
&lt;br /&gt;
  function GL2GKVector (V: TGLVector): TGKVector;&lt;br /&gt;
  function GK2GLVector (V: TGKVector): TGLVector;&lt;br /&gt;
  function GL2WinColor (GLcol: TGLcolor): TColor;&lt;br /&gt;
  function Win2GLColor (WinCol: Tcolor): TGLcolor;&lt;br /&gt;
  function CalcNormale (V1, V2, V3: TGLVector): TGLVector;&lt;br /&gt;
  function CrossProduct(V1, V2: TGLVector): TGLVector;&lt;br /&gt;
  function DotProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
  function LoadTexture(Filename: String; var Texture: GLuint): Boolean;&lt;br /&gt;
  function Magnitude(V1: TGLVector): GLdouble;overload;&lt;br /&gt;
  function Magnitude(X, Y: GLdouble): GLdouble;overload;&lt;br /&gt;
  function ScalarProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
  function MinVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
  function MaxVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
  function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function SubtractVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;overload;&lt;br /&gt;
  function AddVector (Vec1, Vec2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function AddVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;overload;&lt;br /&gt;
  function ForceForegroundWindow(hwnd: THandle): Boolean;&lt;br /&gt;
  function ValidTexture (tex: GLUint; ErrStr: string): boolean;&lt;br /&gt;
  procedure ResetGLErrorFlags;&lt;br /&gt;
  procedure InitGLEnv (dc: HDC; rc: HGLRC; hndl: THandle);// pixelformat setzen&lt;br /&gt;
  procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);&lt;br /&gt;
  procedure InitVector (var V1: TGLVector; x, y, z: GLdouble);overload;&lt;br /&gt;
  procedure InitVector (var V1: TGKVector; x, y, z: GLdouble);overload;&lt;br /&gt;
  procedure InitVector (var V1: TArrVector; x, y, z: GLdouble);overload;&lt;br /&gt;
  procedure InitScale (var S1: TScale; x, y, z: GLdouble);&lt;br /&gt;
  procedure LoadBitmap(Filename: String;&lt;br /&gt;
                       out Width: Cardinal;&lt;br /&gt;
                       out Height: Cardinal;&lt;br /&gt;
                       out pData: Pointer);&lt;br /&gt;
  procedure GetRotation (V1, V2: TGLVector;&lt;br /&gt;
                         var Rotation: TRotation);&lt;br /&gt;
  function MakeTextureFromBitmap (Bitmap: string;&lt;br /&gt;
                                  var BitmapList: TTextureList): GLenum;&lt;br /&gt;
  procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);&lt;br /&gt;
  procedure DisableTexture;&lt;br /&gt;
  function TextToGLVector (VTxt: string): TGLVector;&lt;br /&gt;
  function TextToGKVector (VTxt: string): TGKVector;&lt;br /&gt;
  function GKVectorToText (V1: TGKVector): string;overload;&lt;br /&gt;
  function GKVectorToText (V1: TGKVector; digits, decimals: byte): string;overload;&lt;br /&gt;
  function GLVectorToText (V1: TGLVector): string;overload;&lt;br /&gt;
  function GLVectorToText (V1: TGLVector; digits, decimals: byte): string;overload;&lt;br /&gt;
  function MatrixToText (M: TArrMatrix): string;&lt;br /&gt;
  function CheckFormat (number: string; digits, decimals: byte): string;&lt;br /&gt;
  function MyCone (Start, Ende: TGLVector;&lt;br /&gt;
                   RadiusStart, RadiusEnde: GLdouble;&lt;br /&gt;
                   Slices: integer; TileX, TileY: GLdouble): boolean;&lt;br /&gt;
  function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;&lt;br /&gt;
  function ExePath: string;&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  C_X = 0;&lt;br /&gt;
  C_Y = 1;&lt;br /&gt;
  C_Z = 2;&lt;br /&gt;
  C_W = 3;&lt;br /&gt;
  C_EPS:GLdouble=0.01;&lt;br /&gt;
  C_DEGTORAD:GLdouble=3.1412/180;&lt;br /&gt;
  C_RADTODEG:GLdouble=180/3.1412;&lt;br /&gt;
  C_LAMBDA_INCREMENT:GLdouble=0.01;&lt;br /&gt;
  C_PI=3.1415926535;&lt;br /&gt;
  C_PI_DIV_180=C_PI/180;&lt;br /&gt;
&lt;br /&gt;
  HORIZONTAL: byte = 1;&lt;br /&gt;
  VERTIKAL: byte = 2;&lt;br /&gt;
  ZENTRAL: byte = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses Forms, {KanalUtil,} OGLinclude, Controls;&lt;br /&gt;
&lt;br /&gt;
function MyPower (Base: extended; Exp: integer): extended;&lt;br /&gt;
//var&lt;br /&gt;
//  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
//  result := Base;&lt;br /&gt;
//  for i := 2 to Exp do&lt;br /&gt;
//    result := result * Base;&lt;br /&gt;
&lt;br /&gt;
  result := Base * Base;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);&lt;br /&gt;
begin&lt;br /&gt;
  ToVektor.X := FromVektor.X;&lt;br /&gt;
  ToVektor.Y := FromVektor.Y;&lt;br /&gt;
  ToVektor.Z := FromVektor.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixX (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den X-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[00];&lt;br /&gt;
  result.Y := matrix[01];&lt;br /&gt;
  result.Z := matrix[02];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixY (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Y-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[04];&lt;br /&gt;
  result.Y := matrix[05];&lt;br /&gt;
  result.Z := matrix[06];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixZ (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Z-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[08];&lt;br /&gt;
  result.Y := matrix[09];&lt;br /&gt;
  result.Z := matrix[10];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixPos (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Position-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[12];&lt;br /&gt;
  result.Y := matrix[13];&lt;br /&gt;
  result.Z := matrix[14];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixX (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten X-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[00] := v.X;&lt;br /&gt;
  matrix[01] := v.Y;&lt;br /&gt;
  matrix[02] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixY (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Y-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[04] := v.X;&lt;br /&gt;
  matrix[05] := v.Y;&lt;br /&gt;
  matrix[06] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixZ (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Z-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[08] := v.X;&lt;br /&gt;
  matrix[09] := v.Y;&lt;br /&gt;
  matrix[10] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixPos (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Position-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[12] := v.X;&lt;br /&gt;
  matrix[13] := v.Y;&lt;br /&gt;
  matrix[14] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MinVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
// gibt den Vector mit der geringeren Länge zurück&lt;br /&gt;
begin&lt;br /&gt;
  result := V1;&lt;br /&gt;
  if Magnitude (V1) &amp;gt; Magnitude (V2) then&lt;br /&gt;
    result := V2;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MaxVector (V1, V2: TGLvector): TGLvector;&lt;br /&gt;
// gibt den Vector mit der größeren Länge zurück&lt;br /&gt;
begin&lt;br /&gt;
  result := V1;&lt;br /&gt;
  if Magnitude (V1) &amp;lt; Magnitude (V2) then&lt;br /&gt;
    result := V2;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;&lt;br /&gt;
// subtrahiert Vec2 von vec1 und gibt das ergebnis in vec3 zurück&lt;br /&gt;
var&lt;br /&gt;
  Vec3: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  Vec3 .X := Vec1.X - Vec2.X;&lt;br /&gt;
  Vec3 .Y := Vec1.Y - Vec2.Y;&lt;br /&gt;
  Vec3 .Z := Vec1.Z - Vec2.Z;&lt;br /&gt;
  result := Vec3;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SubtractVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;&lt;br /&gt;
// subtrahiert X, Y, Z von vec.x, vec.y, vec.z  und gibt das&lt;br /&gt;
// ergebnis zurück&lt;br /&gt;
begin&lt;br /&gt;
  Vec .X := Vec.X - X;&lt;br /&gt;
  Vec .Y := Vec.Y - Y;&lt;br /&gt;
  Vec .Z := Vec.Z - Z;&lt;br /&gt;
  result := Vec;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AddVector (Vec1, Vec2: TGLVector): TGLVector;&lt;br /&gt;
// addiert Vec2 auf vec1 und gibt das ergebnis in vec3 zurück&lt;br /&gt;
var&lt;br /&gt;
  Vec3: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  Vec3 .X := Vec1.X + Vec2.X;&lt;br /&gt;
  Vec3 .Y := Vec1.Y + Vec2.Y;&lt;br /&gt;
  Vec3 .Z := Vec1.Z + Vec2.Z;&lt;br /&gt;
  result := Vec3;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AddVector (Vec: TGLVector; X, Y, Z: GLdouble): TGLVector;&lt;br /&gt;
// addiert X, Y, Z auf vec.x, vec.y, vec.z  und gibt das&lt;br /&gt;
// ergebnis zurück&lt;br /&gt;
begin&lt;br /&gt;
  Vec .X := Vec.X + X;&lt;br /&gt;
  Vec .Y := Vec.Y + Y;&lt;br /&gt;
  Vec .Z := Vec.Z + Z;&lt;br /&gt;
  result := Vec;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Magnitude(V1: TGLVector): GLdouble;&lt;br /&gt;
var&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // gibt die länge des vektors im dreidimensionalen raum zurück&lt;br /&gt;
  Ergebnis := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);&lt;br /&gt;
  try&lt;br /&gt;
    result := sqrt(Ergebnis);&lt;br /&gt;
  except&lt;br /&gt;
    result := 0;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Magnitude(X, Y: GLdouble): GLdouble;&lt;br /&gt;
var&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // gibt die länge des vektors im zweidimensionalen raum zurück&lt;br /&gt;
  Ergebnis := MyPower(X,2)+MyPower(Y,2);&lt;br /&gt;
  try&lt;br /&gt;
    result := sqrt(Ergebnis);&lt;br /&gt;
  except&lt;br /&gt;
    result := 0;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function DotProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
// errechnet den winkel zwischen zwei vektoren&lt;br /&gt;
var&lt;br /&gt;
  len1, len2: GLdouble;&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  //len1 := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);&lt;br /&gt;
  //len2 := MyPower(V2.X,2)+MyPower(V2.Y,2)+MyPower(V2.Z,2);&lt;br /&gt;
  len1 := Magnitude (V1);&lt;br /&gt;
  len2 := Magnitude (V2);&lt;br /&gt;
  Ergebnis := ScalarProduct (V1, V2);&lt;br /&gt;
  Ergebnis := arccos (Ergebnis / (len1 * len2));&lt;br /&gt;
  result := radtodeg (Ergebnis) * 2.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function CrossProduct(V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  CrossVec: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
	//CrossVec.X := +((V1.Y*V2.Z) - (V1.Z*V2.Y));&lt;br /&gt;
	//CrossVec.Y := -((V1.X*V2.Z) - (V1.Z*V2.X));&lt;br /&gt;
	//CrossVec.Z := +((V1.X*V2.Y) - (V1.Y*V2.X));&lt;br /&gt;
	CrossVec.X := ((V1.Y*V2.Z) - (V1.Z*V2.Y));&lt;br /&gt;
	CrossVec.Y := ((V1.Z*V2.X) - (V1.X*V2.Z));&lt;br /&gt;
	CrossVec.Z := ((V1.X*V2.Y) - (V1.Y*V2.X));&lt;br /&gt;
  result := CrossVec;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
function CalcNormale (V1, V2, V3: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  Kreuz: TGLvector;&lt;br /&gt;
  V1V2, V1V3: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zum testen:&lt;br /&gt;
  InitVector (result, 0, 0, 0);&lt;br /&gt;
  // gibt die normale von 3 vektoren zurück (die senkrechte auf die&lt;br /&gt;
  // durch die drei vektoren gebildete ebene)&lt;br /&gt;
  V1V2 := SubtractVector (V2, V1);&lt;br /&gt;
  V1V3 := SubtractVector (V3, V1);&lt;br /&gt;
&lt;br /&gt;
  Kreuz := CrossProduct (V1V2, V1V3);&lt;br /&gt;
&lt;br /&gt;
  result := Normalize (Kreuz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TGLVector; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1.x := x;&lt;br /&gt;
  V1.y := y;&lt;br /&gt;
  V1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TGKVector; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1.x := x;&lt;br /&gt;
  V1.y := y;&lt;br /&gt;
  V1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TArrVector; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1[C_X] := x;&lt;br /&gt;
  V1[C_Y] := y;&lt;br /&gt;
  V1[C_Z] := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitScale (var S1: TScale; x, y, z: GLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  S1.x := x;&lt;br /&gt;
  S1.y := y;&lt;br /&gt;
  S1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Multiply (V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
// zwei vektoren miteinander multiplizieren&lt;br /&gt;
  ret.X := V1.X * V2.X;&lt;br /&gt;
  ret.Y := V1.Y * V2.Y;&lt;br /&gt;
  ret.Z := V1.Z * V2.Z;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Divide (V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
// zwei vektoren miteinander multiplizieren&lt;br /&gt;
  ret.X := V1.X / V2.X;&lt;br /&gt;
  ret.Y := V1.Y / V2.Y;&lt;br /&gt;
  ret.Z := V1.Z / V2.Z;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ScalarProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
// die summe der potenzen der einzelnen achsen von zwei vektoren errechnen&lt;br /&gt;
  result := (V1.X*V2.X +&lt;br /&gt;
             V1.Y*V2.Y +&lt;br /&gt;
             V1.Z*V2.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LoadTexture(Filename: String; var Texture: GLuint): Boolean;&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_LoadUnable = 'Unable to load ';&lt;br /&gt;
  Res_LoadingTex = 'Loading Textures';&lt;br /&gt;
var&lt;br /&gt;
  pData: Pointer;&lt;br /&gt;
  Width: Cardinal;&lt;br /&gt;
  Height: Cardinal;&lt;br /&gt;
  newTexture: GLint;&lt;br /&gt;
begin&lt;br /&gt;
  pData :=nil;&lt;br /&gt;
  LoadBitmap(Filename, Width, Height, pData);&lt;br /&gt;
&lt;br /&gt;
  if (Assigned(pData)) then&lt;br /&gt;
    Result := True&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    Result := False;&lt;br /&gt;
    MessageBox(0, PChar(Res_LoadUnable + filename),&lt;br /&gt;
               pchar (Res_LoadingTex), MB_OK);&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  glGenTextures(1, @NewTexture);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, NewTexture);&lt;br /&gt;
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}&lt;br /&gt;
&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }&lt;br /&gt;
&lt;br /&gt;
  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);&lt;br /&gt;
&lt;br /&gt;
  Texture := newTexture;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure LoadBitmap(Filename: String;&lt;br /&gt;
                     out Width: Cardinal;&lt;br /&gt;
                     out Height: Cardinal;&lt;br /&gt;
                     out pData: Pointer);&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_ReadErr = 'Error reading palette';&lt;br /&gt;
  Res_OpenErr = 'Error opening: ';&lt;br /&gt;
  Res_BitmapDataErr = 'Error reading bitmap data';&lt;br /&gt;
  Res_BmpUnit = 'BMP Unit';&lt;br /&gt;
var&lt;br /&gt;
  FileHeader: BITMAPFILEHEADER;&lt;br /&gt;
  InfoHeader: BITMAPINFOHEADER;&lt;br /&gt;
  Palette: array of RGBQUAD;&lt;br /&gt;
  BitmapFile: THandle;&lt;br /&gt;
  BitmapLength: Cardinal;&lt;br /&gt;
  PaletteLength: Cardinal;&lt;br /&gt;
  ReadBytes: Cardinal;&lt;br /&gt;
  Front: ^Byte;&lt;br /&gt;
  Back: ^Byte;&lt;br /&gt;
  Temp: Byte;&lt;br /&gt;
  I : Cardinal;&lt;br /&gt;
begin&lt;br /&gt;
  BitmapFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);&lt;br /&gt;
  if (BitmapFile = INVALID_HANDLE_VALUE) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_OpenErr+Filename), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // Get header information&lt;br /&gt;
  ReadFile(BitmapFile, FileHeader, SizeOf(FileHeader), ReadBytes, nil);&lt;br /&gt;
  ReadFile(BitmapFile, InfoHeader, SizeOf(InfoHeader), ReadBytes, nil);&lt;br /&gt;
&lt;br /&gt;
  // Get palette&lt;br /&gt;
  PaletteLength := InfoHeader.biClrUsed;&lt;br /&gt;
  SetLength(Palette, PaletteLength);&lt;br /&gt;
  ReadFile(BitmapFile, Palette, PaletteLength, ReadBytes, nil);&lt;br /&gt;
  if (ReadBytes &amp;lt;&amp;gt; PaletteLength) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_ReadErr), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    CloseHandle(BitmapFile);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  Width := InfoHeader.biWidth;&lt;br /&gt;
  Height := InfoHeader.biHeight;&lt;br /&gt;
  BitmapLength := InfoHeader.biSizeImage;&lt;br /&gt;
  if BitmapLength = 0 then&lt;br /&gt;
    BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;&lt;br /&gt;
&lt;br /&gt;
  // Get the actual pixel data&lt;br /&gt;
  GetMem(pData, BitmapLength);&lt;br /&gt;
  ReadFile(BitmapFile, pData^, BitmapLength, ReadBytes, nil);&lt;br /&gt;
  if (ReadBytes &amp;lt;&amp;gt; BitmapLength) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_BitmapDataErr), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    CloseHandle(BitmapFile);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
  CloseHandle(BitmapFile);&lt;br /&gt;
&lt;br /&gt;
  // Bitmaps are stored BGR and not RGB, so swap the R and B bytes.&lt;br /&gt;
  for I :=0 to Width * Height - 1 do&lt;br /&gt;
  begin&lt;br /&gt;
    Front := Pointer(Cardinal(pData) + I*3);&lt;br /&gt;
    Back := Pointer(Cardinal(pData) + I*3 + 2);&lt;br /&gt;
    Temp := Front^;&lt;br /&gt;
    Front^ := Back^;&lt;br /&gt;
    Back^ := Temp;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GK2GLVector (V: TGKVector): TGLVector;&lt;br /&gt;
// ändert Gauss-Krüger Koordinaten in OpenGL Koordinaten um&lt;br /&gt;
begin&lt;br /&gt;
  result.X := V.X;&lt;br /&gt;
  result.Y := V.Z;&lt;br /&gt;
  result.Z := V.Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GL2GKVector (V: TGLVector): TGKVector;&lt;br /&gt;
// ändert OpenGL Koordinaten in Gauss-Krüger Koordinaten um&lt;br /&gt;
begin&lt;br /&gt;
  result.X := V.X;&lt;br /&gt;
  result.Y := V.Z;&lt;br /&gt;
  result.Z := V.Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Win2GLColor (WinCol: TColor): TGLcolor;&lt;br /&gt;
begin&lt;br /&gt;
  result.Red := GetRValue (WinCol) / 255;&lt;br /&gt;
  result.Green := GetGValue (WinCol) / 255;&lt;br /&gt;
  result.Blue := GetBValue (WinCol) / 255;&lt;br /&gt;
  result.Alpha := 0.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GL2WinColor (GLcol: TGLcolor): TColor;&lt;br /&gt;
begin&lt;br /&gt;
  result := Rgb (StrToInt (FloatToStr (int (GLcol.Red * 255))),&lt;br /&gt;
                 StrToInt (FloatToStr (int (GLcol.Green * 255))),&lt;br /&gt;
                 StrToInt (FloatToStr (int (GLcol.Blue * 255))));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure GetRotation (V1, V2: TGLVector;&lt;br /&gt;
                       var Rotation: TRotation);&lt;br /&gt;
var&lt;br /&gt;
  tmpCyl, tmpZiel, nullVec: TGLVector;&lt;br /&gt;
  normale, ResultLen: TGLVector;&lt;br /&gt;
  VectorLength: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // temporäre vektoren initialisieren&lt;br /&gt;
  InitVector (nullVec, 0,0,0);&lt;br /&gt;
  InitVector (tmpCyl, 0,0,0);&lt;br /&gt;
&lt;br /&gt;
  // länge des zu drehenden objekts ermitteln&lt;br /&gt;
  ResultLen := SubtractVector (V2, V1);&lt;br /&gt;
  VectorLength := Magnitude (ResultLen);&lt;br /&gt;
&lt;br /&gt;
  // vektoren zur bildung der dreiecksfläche bilden.&lt;br /&gt;
  // die schenkel schneiden sich im nullpunkt&lt;br /&gt;
  // der Cylinder läuft immer entlang der Z-Achse&lt;br /&gt;
  tmpCyl.Z := VectorLength;&lt;br /&gt;
  tmpZiel := SubtractVector (V2, V1);&lt;br /&gt;
  tmpZiel.Z := tmpZiel.Z + VectorLength;&lt;br /&gt;
&lt;br /&gt;
  // senkrechte zu den beiden vektoren bilden&lt;br /&gt;
  // (um diese achse soll nachher gedreht werden)&lt;br /&gt;
  // drehachse für späteren gebrauch speichern&lt;br /&gt;
  normale := CalcNormale (tmpCyl, tmpZiel, nullVec);&lt;br /&gt;
&lt;br /&gt;
  // um &amp;quot;Angle&amp;quot; Grad soll nachher gedreht werden&lt;br /&gt;
  Rotation.Angle := DotProduct(tmpCyl, tmpZiel);&lt;br /&gt;
  Rotation.X     := normale.X;&lt;br /&gt;
  Rotation.Y     := normale.Y;&lt;br /&gt;
  Rotation.Z     := normale.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeTextureFromBitmap (Bitmap: string;&lt;br /&gt;
                                var BitmapList: TTextureList): GLenum;&lt;br /&gt;
// die funktion lädt die in Bitmap übergebene Grafik und gibt die Textturnummer&lt;br /&gt;
// zurück. ist das bitmap schon im array BitmapList enthalten, wird die bereits&lt;br /&gt;
// vergeben nummer zurückgegeben.&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_TextureNotFound = 'Texturdatei nicht gefunden: ';&lt;br /&gt;
  Res_Error = 'Error';&lt;br /&gt;
var&lt;br /&gt;
  i, Laenge: integer;&lt;br /&gt;
begin&lt;br /&gt;
  result := 0;&lt;br /&gt;
  if length (trim (Bitmap)) = 0 then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  BitMap := uppercase (BitMap);  // wegen dem folgenden vergleich&lt;br /&gt;
&lt;br /&gt;
  // suchen, ob die textur schon geladen wurde&lt;br /&gt;
  Laenge := length (BitmapList);&lt;br /&gt;
  if Laenge &amp;gt; 0 then&lt;br /&gt;
    for i := low (BitMapList) to high (BitMapList) do&lt;br /&gt;
    begin&lt;br /&gt;
      if (BitmapList[i].BitmapName = Bitmap) and&lt;br /&gt;
         //(glIsTexture (BitmapList[i].TextureNum)) then&lt;br /&gt;
         (BitmapList[i].TextureNum &amp;gt; 0) then&lt;br /&gt;
        result := BitmapList[i].TextureNum;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
  if result = 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    if not fileexists (Bitmap) then&lt;br /&gt;
    begin&lt;br /&gt;
      MessageBox (0, PChar (Res_TextureNotFound+Bitmap),&lt;br /&gt;
                  pchar (Res_Error), MB_OK or MB_ICONERROR);&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if (result = 0) then&lt;br /&gt;
  begin&lt;br /&gt;
    setlength (BitmapList, Laenge+1);&lt;br /&gt;
    BitmapList[Laenge].BitmapName := Bitmap;&lt;br /&gt;
    BitmapList[Laenge].TextureNum := 0;&lt;br /&gt;
    {&lt;br /&gt;
    BitMapList[Laenge].theBmp := TglBmp.Create;&lt;br /&gt;
    if BitMapList[Laenge].theBmp.LoadImage (BitMap) then&lt;br /&gt;
    begin&lt;br /&gt;
      BitMapList[Laenge].theBmp.SetTextureWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);&lt;br /&gt;
      BitMapList[Laenge].theBmp.GenTexture (false, false);&lt;br /&gt;
      result := BitmapList[Laenge].theBmp.TextureID;&lt;br /&gt;
      BitmapList[Laenge].TextureNum := BitmapList[Laenge].theBmp.TextureID;&lt;br /&gt;
    end;&lt;br /&gt;
    }&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);&lt;br /&gt;
begin&lt;br /&gt;
  glEnable(GL_TEXTURE_2D);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, Texture);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);&lt;br /&gt;
  if TextureTiled then&lt;br /&gt;
  begin&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure DisableTexture;&lt;br /&gt;
begin&lt;br /&gt;
  glDisable(GL_TEXTURE_2D);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TextToGLVector (VTxt: string): TGLVector;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  posi: integer;&lt;br /&gt;
  V1: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (V1,0,0,0);&lt;br /&gt;
  posi := pos (subdelim, VTxt);&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.X := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
    posi := pos (subdelim, VTxt);&lt;br /&gt;
  end;&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.Y := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
  end;&lt;br /&gt;
  if length (VTxt) &amp;gt; 0 then V1.Z := StrToFloat (VTxt);&lt;br /&gt;
&lt;br /&gt;
  result := V1;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TextToGKVector (VTxt: string): TGKVector;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  posi: integer;&lt;br /&gt;
  V1: TGKVector;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (V1,0,0,0);&lt;br /&gt;
  posi := pos (subdelim, VTxt);&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.X := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
    posi := pos (subdelim, VTxt);&lt;br /&gt;
  end;&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.Y := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
  end;&lt;br /&gt;
  if length (VTxt) &amp;gt; 0 then V1.Z := StrToFloat (VTxt);&lt;br /&gt;
&lt;br /&gt;
  result := V1;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GKVectorToText (V1: TGKVector): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := FloatToStr (V1.X) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Y) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Z);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GKVectorToText (V1: TGKVector; digits, decimals: byte): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt, frmt, sX, sY, sZ: string;&lt;br /&gt;
begin&lt;br /&gt;
  {&lt;br /&gt;
  VTxt := Format('%*.*f', [digits, decimals, V1.X]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Y]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Z]);&lt;br /&gt;
  }&lt;br /&gt;
  frmt := '%'+IntToStr(digits)+'.'+IntToStr(decimals)+'f';&lt;br /&gt;
&lt;br /&gt;
  sX   := Format(frmt, [V1.X]);&lt;br /&gt;
  sY   := Format(frmt, [V1.Y]);&lt;br /&gt;
  sZ   := Format(frmt, [V1.Z]);&lt;br /&gt;
  //sX   := FloatToStrF(V1.X, fffixed, digits, decimals);&lt;br /&gt;
  //sY   := FloatToStrF(V1.Y, fffixed, digits, decimals);&lt;br /&gt;
  //sZ   := FloatToStrF(V1.Z, fffixed, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
  sX   := trim (sX);&lt;br /&gt;
  sY   := trim (sY);&lt;br /&gt;
  sZ   := trim (sZ);&lt;br /&gt;
&lt;br /&gt;
  sX := CheckFormat (sX, digits, decimals);&lt;br /&gt;
  sY := CheckFormat (sY, digits, decimals);&lt;br /&gt;
  sZ := CheckFormat (sZ, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
  VTxt := sX + subdelim + sY + subdelim + sZ;&lt;br /&gt;
&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GLVectorToText (V1: TGLVector): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := FloatToStr (V1.X) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Y) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Z);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GLVectorToText (V1: TGLVector; digits, decimals: byte): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt, frmt, sX, sY, sZ: string;&lt;br /&gt;
begin&lt;br /&gt;
  {&lt;br /&gt;
  VTxt := Format('%*.*f', [digits, decimals, V1.X]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Y]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits, decimals, V1.Z]);&lt;br /&gt;
  }&lt;br /&gt;
  frmt := '%'+IntToStr(digits)+'.'+IntToStr(decimals)+'f';&lt;br /&gt;
&lt;br /&gt;
  sX   := Format(frmt, [V1.X]);&lt;br /&gt;
  sY   := Format(frmt, [V1.Y]);&lt;br /&gt;
  sZ   := Format(frmt, [V1.Z]);&lt;br /&gt;
  //sX   := FloatToStrF(V1.X, fffixed, digits, decimals);&lt;br /&gt;
  //sY   := FloatToStrF(V1.Y, fffixed, digits, decimals);&lt;br /&gt;
  //sZ   := FloatToStrF(V1.Z, fffixed, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  sX   := trim (sX);&lt;br /&gt;
  sY   := trim (sY);&lt;br /&gt;
  sZ   := trim (sZ);&lt;br /&gt;
&lt;br /&gt;
  sX := CheckFormat (sX, digits, decimals);&lt;br /&gt;
  sY := CheckFormat (sY, digits, decimals);&lt;br /&gt;
  sZ := CheckFormat (sZ, digits, decimals);&lt;br /&gt;
&lt;br /&gt;
  VTxt := sX + subdelim + sY + subdelim + sZ;&lt;br /&gt;
&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MatrixToText (M: TArrMatrix): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := '';&lt;br /&gt;
  for i := low (M) to high(M) do&lt;br /&gt;
  begin&lt;br /&gt;
    VTxt := VTxt + Format('%14.6f', [M[i]]);&lt;br /&gt;
    if i &amp;lt; high (M) then&lt;br /&gt;
      VTxt := VTxt + subdelim;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MyCone (Start, Ende: TGLVector;&lt;br /&gt;
                 RadiusStart, RadiusEnde: GLdouble;&lt;br /&gt;
                 Slices: integer; TileX, TileY: GLdouble): boolean;&lt;br /&gt;
var&lt;br /&gt;
  Slice: Integer;&lt;br /&gt;
  Laenge, xdelta, zdelta: GLdouble;&lt;br /&gt;
  V1, V2, V3, V4: TGLvector;&lt;br /&gt;
  A, B: double;&lt;br /&gt;
  //tmpVec: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  result := true;&lt;br /&gt;
&lt;br /&gt;
  // laenge des kegels berechnen&lt;br /&gt;
  // hierbei wird davon ausgegangen, dass der kegel senkrecht steht&lt;br /&gt;
  Laenge := Ende.y - Start.y;&lt;br /&gt;
&lt;br /&gt;
  // die folgende längenberechnung stimmt nicht mit der senkrechten&lt;br /&gt;
  // verbindungslinie der beiden konusebenen überein, wenn die radien&lt;br /&gt;
  // sich unterscheiden, da sich dann ein schiefer vektor ergibt. der&lt;br /&gt;
  // ist natürlich länger als die senkrechte.&lt;br /&gt;
  //tmpVec := SubtractVector (Start, Ende);&lt;br /&gt;
  //Laenge := Magnitude (tmpVec);&lt;br /&gt;
&lt;br /&gt;
  // radiusdifferenz der oberen und unteren ebene des konus berechnen&lt;br /&gt;
  xdelta := Start.x - Ende.x;&lt;br /&gt;
  zdelta := Start.z - Ende.z;&lt;br /&gt;
  xdelta := -xdelta;&lt;br /&gt;
  //zdelta := zdelta;&lt;br /&gt;
&lt;br /&gt;
  glBegin (GL_TRIANGLE_STRIP);&lt;br /&gt;
  // der kegel wird entlang der z-achse gezeichnet&lt;br /&gt;
  V1.z := 0;&lt;br /&gt;
  V2.z := 0;&lt;br /&gt;
  V3.z := Laenge;&lt;br /&gt;
  V4.z := Laenge;&lt;br /&gt;
  // immer ein dreieck an das andere: mit zwei punkten des oberen&lt;br /&gt;
  // radius und einem des unteren bzw. einem des oberen und zwei des&lt;br /&gt;
  // unteren ein dreieck zeichnen. mit dem nächsten neu errechneten punkt&lt;br /&gt;
  // und den zwei vorhergehenden haben wir immer das nächste dreieck.&lt;br /&gt;
  // so viele dreiecke wie pizzastücke (slices) gewünscht.&lt;br /&gt;
  for Slice := 1 to Slices do begin&lt;br /&gt;
    A := 2 * PI * Slice / Slices;&lt;br /&gt;
    B := 2 * PI * (Slice+1) / Slices;&lt;br /&gt;
    V1.x := sin(A)*RadiusStart;&lt;br /&gt;
    V1.y := cos(A)*RadiusStart;&lt;br /&gt;
    V2.x := sin(B)*RadiusStart;&lt;br /&gt;
    V2.y := cos(B)*RadiusStart;&lt;br /&gt;
    // umsetzung von y nach z-achse&lt;br /&gt;
    V3.x := (sin(B)*RadiusEnde)+xdelta;&lt;br /&gt;
    V3.y := (cos(B)*RadiusEnde)+zdelta;&lt;br /&gt;
    V4.x := (sin(A)*RadiusEnde)+xdelta;&lt;br /&gt;
    V4.y := (cos(A)*RadiusEnde)+zdelta;&lt;br /&gt;
    //Normale := CalcNormale (V1, V3, V2);&lt;br /&gt;
    //glNormal3fv(@Normale);&lt;br /&gt;
    if Slice = 1 then&lt;br /&gt;
    begin&lt;br /&gt;
      glTexCoord2d(1*TileX,0); glVertex3dv(@V1);&lt;br /&gt;
      glTexCoord2d(1*TileX,1*TileY); glVertex3dv(@V4);&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,0); glVertex3dv(@V2);&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,1*TileY); glVertex3dv(@V3);&lt;br /&gt;
    end&lt;br /&gt;
    else&lt;br /&gt;
    begin&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,0); glVertex3dv(@V2);&lt;br /&gt;
      glTexCoord2d(1*TileX-Slice/Slices*TileX,1*TileX); glVertex3dv(@V3);&lt;br /&gt;
    end;&lt;br /&gt;
    // so hatte ich mir das zuerst gedacht:&lt;br /&gt;
    // aktuellen und nächsten punkt des kreises (oben und unten)&lt;br /&gt;
    // nehmen und ein rechteck zeichnen. alle rechtecke zusammen sollten&lt;br /&gt;
    // einen geschlossenen kegel ergeben.&lt;br /&gt;
    //glBegin(GL_QUADS);&lt;br /&gt;
    //  glNormal3dv(@Normale);&lt;br /&gt;
    //  glTexCoord2d(0,0); glVertex3dv(@V2);&lt;br /&gt;
    //  glTexCoord2d(1,0); glVertex3dv(@V1);&lt;br /&gt;
    //  glTexCoord2d(1,1); glVertex3dv(@V4);&lt;br /&gt;
    //  glTexCoord2d(0,1); glVertex3dv(@V3);&lt;br /&gt;
    //glEnd;&lt;br /&gt;
  end;&lt;br /&gt;
  glEnd;  // (GL_TRIANGLE_STRIP)&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
{----------------------------- für TRUVCamera --------------------------------}&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
&lt;br /&gt;
function Multiply(M1, M2: TArrMatrix): TArrMatrix;&lt;br /&gt;
// multiplies two 4x4 matrices&lt;br /&gt;
var&lt;br /&gt;
  ret: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadMatrixd(@M1);&lt;br /&gt;
  glMultMatrixd(@M2);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX,@ret);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeVector(X,Y,Z:GLdouble):TArrVector;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=x;&lt;br /&gt;
  result[1]:=y;&lt;br /&gt;
  result[2]:=z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeVector(X,Y,Z,W:GLdouble):TArrVector;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=x;&lt;br /&gt;
  result[1]:=y;&lt;br /&gt;
  result[2]:=z;&lt;br /&gt;
  result[3]:=w;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Normalize(aVector:TArrVector):TArrVector;overload;&lt;br /&gt;
var&lt;br /&gt;
   d:double;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (result,1,1,1);&lt;br /&gt;
  d:=Sqrt(Sqr(aVector[C_X])+Sqr(aVector[C_Y])+Sqr(aVector[C_Z]));&lt;br /&gt;
  if d=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    //raise exception.Create('Zero length vector(Normalize 1)');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  result[C_X]:=aVector[C_X]/d;&lt;br /&gt;
  result[C_Y]:=aVector[C_Y]/d;&lt;br /&gt;
  result[C_Z]:=aVector[C_Z]/d;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Normalize(aVector:TGLVector):TGLVector;overload;&lt;br /&gt;
var&lt;br /&gt;
   d:double;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (result,1,1,1);&lt;br /&gt;
  d:=Sqrt(Sqr(aVector.X)+Sqr(aVector.Y)+Sqr(aVector.Z));&lt;br /&gt;
  if d=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    //raise exception.Create('Zero length vector(Normalize 2)');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  result.X:=aVector.X/d;&lt;br /&gt;
  result.Y:=aVector.Y/d;&lt;br /&gt;
  result.Z:=aVector.Z/d;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetIdentity(Matrix:TMatrix):TMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result[0,0]:=1.0;result[0,1]:=0.0;result[0,2]:=0.0;result[0,3]:=0.0;&lt;br /&gt;
  result[1,0]:=0.0;result[1,1]:=1.0;result[1,2]:=0.0;result[1,3]:=0.0;&lt;br /&gt;
  result[2,0]:=0.0;result[2,1]:=0.0;result[2,2]:=1.0;result[2,3]:=0.0;&lt;br /&gt;
  result[3,0]:=0.0;result[3,1]:=0.0;result[3,2]:=0.0;result[3,3]:=1.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetIdentity(Matrix:TArrMatrix):TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=1.0;result[1]:=0.0;result[2]:=0.0;result[3]:=0.0;&lt;br /&gt;
  result[4]:=0.0;result[5]:=1.0;result[6]:=0.0;result[7]:=0.0;&lt;br /&gt;
  result[8]:=0.0;result[9]:=0.0;result[10]:=1.0;result[11]:=0.0;&lt;br /&gt;
  result[12]:=0.0;result[13]:=0.0;result[14]:=0.0;result[15]:=1.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MatrixTranspose(const M:TMatrix):TMatrix;register;&lt;br /&gt;
var&lt;br /&gt;
   i,j:integer;&lt;br /&gt;
begin&lt;br /&gt;
     for i:=0 to 3 do&lt;br /&gt;
         for j:=0 to 3 do&lt;br /&gt;
             result[i,j]:=M[j,i];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v:TArrVector;a:GLdouble):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
   temp: TArrVector;&lt;br /&gt;
   sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
     temp[C_X] := v[C_x];&lt;br /&gt;
     temp[C_Y] := (v[C_Y] * cosine) + (v[C_Z] * -sine);&lt;br /&gt;
     temp[C_Z] := (v[C_Y] * sine) + (v[C_Z] * cosine);&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v: TArrVector;a:GLdouble):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp[C_x] := (v[C_x] * cosine) + (v[C_z] * sine);&lt;br /&gt;
  temp[C_y] := v[C_y];&lt;br /&gt;
  temp[C_z] := (v[C_x] * -sine) + (v[C_z] * cosine);&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v: TArrVector; a: GLdouble):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
  temp[C_x] := (v[C_x] * cosine) + (v[C_y] * -sine);&lt;br /&gt;
  temp[C_y] := (v[C_x] * sin(a)) + (v[C_y] * cosine);&lt;br /&gt;
  temp[C_z] := v[C_z];&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v:TGLVector;a:GLdouble):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp.X := v.x;&lt;br /&gt;
  temp.Y := (v.Y * cosine) + (v.Z * -sine);&lt;br /&gt;
  temp.Z := (v.Y * sine) + (v.Z * cosine);&lt;br /&gt;
&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v: TGLVector;a:GLdouble):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp.x := (v.x * cosine) + (v.z * sine);&lt;br /&gt;
  temp.y := v.y;&lt;br /&gt;
  temp.z := (v.X * -sine) + (v.z * cosine);&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v: TGLVector; a: GLdouble):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
  sine,cosine:GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  a:=a*C_DEGTORAD;&lt;br /&gt;
  sine:=Sin(a);&lt;br /&gt;
  cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
  temp.x := (v.x * cosine) + (v.y * -sine);&lt;br /&gt;
  temp.y := (v.x * sin(a)) + (v.y * cosine);&lt;br /&gt;
  temp.z := v.z;&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v,c: TGLvector;a: GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// c: zentrum&lt;br /&gt;
// a: winkel&lt;br /&gt;
var&lt;br /&gt;
  temp, temp2: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // das übergebene zentrum in den nullpunkt holen&lt;br /&gt;
  temp2 := SubtractVector (v, c);&lt;br /&gt;
&lt;br /&gt;
  // jetzt so drehen, als ob alles um den nullpunkt angeordnet wäre&lt;br /&gt;
  temp  := VectorRotateX (temp2, a);&lt;br /&gt;
&lt;br /&gt;
  // und das ergebnis wieder in den ausgangspunkt zurück verschieben&lt;br /&gt;
  result := AddVector (temp, c);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v,c: TGLvector;a: GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// c: zentrum&lt;br /&gt;
// a: winkel&lt;br /&gt;
var&lt;br /&gt;
   temp, temp2: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // das übergebene zentrum in den nullpunkt holen&lt;br /&gt;
  temp2 := SubtractVector (v, c);&lt;br /&gt;
&lt;br /&gt;
  // jetzt so drehen, als ob alles um den nullpunkt angeordnet wäre&lt;br /&gt;
  temp  := VectorRotateY (temp2, a);&lt;br /&gt;
&lt;br /&gt;
  // und das ergebnis wieder in den ausgangspunkt zurück verschieben&lt;br /&gt;
  result := AddVector (temp, c);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v,c: TGLvector; a: GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// c: zentrum&lt;br /&gt;
// a: winkel&lt;br /&gt;
var&lt;br /&gt;
  temp, temp2: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  // das übergebene zentrum in den nullpunkt holen&lt;br /&gt;
  temp2 := SubtractVector (v, c);&lt;br /&gt;
&lt;br /&gt;
  // jetzt so drehen, als ob alles um den nullpunkt angeordnet wäre&lt;br /&gt;
  temp  := VectorRotateZ (temp2, a);&lt;br /&gt;
&lt;br /&gt;
  // und das ergebnis wieder in den ausgangspunkt zurück verschieben&lt;br /&gt;
  result := AddVector (temp, c);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v1,v2,v3,v4:TGLVector;a:GLdouble):TGLVector;&lt;br /&gt;
// v1: zu drehender punkt&lt;br /&gt;
// v2, v3, v4: vektoren die zusammen mit v1 eine fläche beschreiben,&lt;br /&gt;
//             durch welche die drehachse läuft.&lt;br /&gt;
// a: drehwinkel&lt;br /&gt;
var&lt;br /&gt;
  PlaneVec, PlaneCenter: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zuerst das zentrum der vektoren herausfinden&lt;br /&gt;
  PlaneCenter.X := (v1.X+v2.X+v3.X+v4.X) / 4;&lt;br /&gt;
  PlaneCenter.Y := (v1.Y+v2.Y+v3.Y+v4.Y) / 4;&lt;br /&gt;
  PlaneCenter.Z := (v1.Z+v2.Z+v3.Z+v4.Z) / 4;&lt;br /&gt;
&lt;br /&gt;
  // den zu drehenden vector in den nullpunkt holen&lt;br /&gt;
  PlaneVec := SubtractVector (v1, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  // jetzt um die gewünschte achse drehen&lt;br /&gt;
  PlaneVec := VectorRotateX (PlaneVec, a);&lt;br /&gt;
&lt;br /&gt;
  // die drehung auf den eigentlichen vector aufaddieren&lt;br /&gt;
  // und zurückgeben&lt;br /&gt;
  result := AddVector (PlaneVec, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  result := VectorRotateX (v1, PlaneCenter, a);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v1,v2,v3,v4:TGLvector;a:GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// v2, v3, v4: vektoren die zusammen mit v1 eine fläche beschreiben,&lt;br /&gt;
//             durch welche die drehachse läuft.&lt;br /&gt;
// a: drehwinkel&lt;br /&gt;
var&lt;br /&gt;
  PlaneVec, PlaneCenter: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zuerst das zentrum der vektoren herausfinden&lt;br /&gt;
  PlaneCenter.X := (v1.X+v2.X+v3.X+v4.X) / 4;&lt;br /&gt;
  PlaneCenter.Y := (v1.Y+v2.Y+v3.Y+v4.Y) / 4;&lt;br /&gt;
  PlaneCenter.Z := (v1.Z+v2.Z+v3.Z+v4.Z) / 4;&lt;br /&gt;
&lt;br /&gt;
  // den zu drehenden vector in den nullpunkt holen&lt;br /&gt;
  PlaneVec := SubtractVector (v1, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  // jetzt um die gewünschte achse drehen&lt;br /&gt;
  PlaneVec := VectorRotateY (PlaneVec, a);&lt;br /&gt;
&lt;br /&gt;
  // die drehung auf den eigentlichen vector aufaddieren&lt;br /&gt;
  // und zurückgeben&lt;br /&gt;
  result := AddVector (PlaneVec, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  result := VectorRotateY (v1, PlaneCenter, a);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v1,v2,v3,v4:TGLvector;a:GLdouble):TGLVector;&lt;br /&gt;
// v: zu drehender punkt&lt;br /&gt;
// v2, v3, v4: vektoren die zusammen mit v1 eine fläche beschreiben,&lt;br /&gt;
//             durch welche die drehachse läuft.&lt;br /&gt;
// a: drehwinkel&lt;br /&gt;
var&lt;br /&gt;
  PlaneVec, PlaneCenter: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // zuerst das zentrum der vektoren herausfinden&lt;br /&gt;
  PlaneCenter.X := (v1.X+v2.X+v3.X+v4.X) / 4;&lt;br /&gt;
  PlaneCenter.Y := (v1.Y+v2.Y+v3.Y+v4.Y) / 4;&lt;br /&gt;
  PlaneCenter.Z := (v1.Z+v2.Z+v3.Z+v4.Z) / 4;&lt;br /&gt;
&lt;br /&gt;
  // den zu drehenden vector in den nullpunkt holen&lt;br /&gt;
  PlaneVec := SubtractVector (v1, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  // jetzt um die gewünschte achse drehen&lt;br /&gt;
  PlaneVec := VectorRotateZ (PlaneVec, a);&lt;br /&gt;
&lt;br /&gt;
  // die drehung auf den eigentlichen vector aufaddieren&lt;br /&gt;
  // und zurückgeben&lt;br /&gt;
  result := AddVector (PlaneVec, PlaneCenter);&lt;br /&gt;
&lt;br /&gt;
  result := VectorRotateZ (v1, PlaneCenter, a);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{ Finds the point on the axis, closest to the&lt;br /&gt;
  source vector }&lt;br /&gt;
function NearestPoint(Axis, Point: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: double;&lt;br /&gt;
begin&lt;br /&gt;
  temp := DotProduct(Axis, Point) / DotProduct(Axis, Axis);&lt;br /&gt;
  Axis.X := Axis.X * temp;&lt;br /&gt;
  Axis.Y := Axis.Y * temp;&lt;br /&gt;
  Axis.Z := Axis.Z * temp;&lt;br /&gt;
  Result := Axis;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
{-------------------------------- allgemein ----------------------------------}&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
&lt;br /&gt;
function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;&lt;br /&gt;
var&lt;br /&gt;
  t: GLdouble;&lt;br /&gt;
  i, j, k, swap: integer;&lt;br /&gt;
  tmp: TMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
  inverse := GetIdentity(inverse);&lt;br /&gt;
&lt;br /&gt;
  for i := 0 to 3 do&lt;br /&gt;
  begin&lt;br /&gt;
    for j := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      tmp[i][j] := src[i*4+j];&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  for i := 0 to 3 do&lt;br /&gt;
  begin&lt;br /&gt;
    // look for largest element in column.&lt;br /&gt;
    swap := i;&lt;br /&gt;
    for j := i+1 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      if abs(tmp[j][i]) &amp;gt; abs(tmp[i][i]) then&lt;br /&gt;
      begin&lt;br /&gt;
        swap := j;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    if not (swap = i) then&lt;br /&gt;
    begin&lt;br /&gt;
      // swap rows.&lt;br /&gt;
      for k := 0 to 3 do&lt;br /&gt;
      begin&lt;br /&gt;
        t := tmp[i][k];&lt;br /&gt;
        tmp[i][k] := tmp[swap][k];&lt;br /&gt;
        tmp[swap][k] := t;&lt;br /&gt;
&lt;br /&gt;
        t := inverse[i*4+k];&lt;br /&gt;
        inverse[i*4+k] := inverse[swap*4+k];&lt;br /&gt;
        inverse[swap*4+k] := t;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    if tmp[i][i] = 0 then&lt;br /&gt;
    begin&lt;br /&gt;
    { no non-zero pivot.  the matrix is singular, which&lt;br /&gt;
      shouldn't happen.  This means the user gave us a bad&lt;br /&gt;
      matrix. }&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    t := tmp[i][i];&lt;br /&gt;
    for k := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      tmp[i][k] := tmp[i][k]/t;&lt;br /&gt;
      inverse[i*4+k] := inverse[i*4+k]/t;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    for j := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      if not (j = i) then&lt;br /&gt;
      begin&lt;br /&gt;
        t := tmp[j][i];&lt;br /&gt;
        for k := 0 to 3 do&lt;br /&gt;
        begin&lt;br /&gt;
          tmp[j][k] := tmp[j][k]-tmp[i][k]*t;&lt;br /&gt;
          inverse[j*4+k] := inverse[j*4+k]-inverse[i*4+k]*t;&lt;br /&gt;
        end;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
  result := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Multiply (Color: TGLcolor; m: GLdouble): TGLcolor;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLcolor;&lt;br /&gt;
begin&lt;br /&gt;
  ret.red := Color.red * m;&lt;br /&gt;
  ret.green := Color.green * m;&lt;br /&gt;
  ret.blue := Color.blue * m;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Divide (V1: TGLvector; d: GLdouble): TGLvector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  ret.x := V1.x / d;&lt;br /&gt;
  ret.y := V1.y / d;&lt;br /&gt;
  ret.z := V1.z / d;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ForceForegroundWindow(hwnd: THandle): Boolean;&lt;br /&gt;
{&lt;br /&gt;
  Manchmal funktioniert die SetForeGroundWindow Funktion&lt;br /&gt;
  nicht so, wie sie sollte; besonders unter Windows 98/2000,&lt;br /&gt;
  wenn ein anderes Fenster den Fokus hat.&lt;br /&gt;
  ForceForegroundWindow ist eine &amp;quot;verbesserte&amp;quot; Version von&lt;br /&gt;
  der SetForeGroundWindow API-Funktion, um ein Fenster in&lt;br /&gt;
  den Vordergrund zu bringen.&lt;br /&gt;
}&lt;br /&gt;
const&lt;br /&gt;
  SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;&lt;br /&gt;
  SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;&lt;br /&gt;
var&lt;br /&gt;
  ForegroundThreadID: DWORD;&lt;br /&gt;
  ThisThreadID: DWORD;&lt;br /&gt;
  timeout: DWORD;&lt;br /&gt;
begin&lt;br /&gt;
  if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);&lt;br /&gt;
&lt;br /&gt;
  if GetForegroundWindow = hwnd then Result := True&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    // Windows 98/2000 doesn't want to foreground a window when some other&lt;br /&gt;
    // window has keyboard focus&lt;br /&gt;
&lt;br /&gt;
    if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion &amp;gt; 4)) or&lt;br /&gt;
      ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and&lt;br /&gt;
      ((Win32MajorVersion &amp;gt; 4) or ((Win32MajorVersion = 4) and&lt;br /&gt;
      (Win32MinorVersion &amp;gt; 0)))) then&lt;br /&gt;
    begin&lt;br /&gt;
      // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm&lt;br /&gt;
      // Converted to Delphi by Ray Lischner&lt;br /&gt;
      // Published in The Delphi Magazine 55, page 16&lt;br /&gt;
&lt;br /&gt;
      Result := False;&lt;br /&gt;
      ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);&lt;br /&gt;
      ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);&lt;br /&gt;
      if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then&lt;br /&gt;
      begin&lt;br /&gt;
        BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
        SetForegroundWindow(hwnd);&lt;br /&gt;
        AttachThreadInput(ThisThreadID, ForegroundThreadID, False);&lt;br /&gt;
        Result := (GetForegroundWindow = hwnd);&lt;br /&gt;
      end;&lt;br /&gt;
      if not Result then&lt;br /&gt;
      begin&lt;br /&gt;
        // Code by Daniel P. Stasinski&lt;br /&gt;
        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);&lt;br /&gt;
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),&lt;br /&gt;
          SPIF_SENDCHANGE);&lt;br /&gt;
        BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
        SetForegroundWindow(hWnd);&lt;br /&gt;
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);&lt;br /&gt;
      end;&lt;br /&gt;
    end&lt;br /&gt;
    else&lt;br /&gt;
    begin&lt;br /&gt;
      BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
      SetForegroundWindow(hwnd);&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    Result := (GetForegroundWindow = hwnd);&lt;br /&gt;
  end;&lt;br /&gt;
end; { ForceForegroundWindow }&lt;br /&gt;
&lt;br /&gt;
procedure InitGLEnv (dc: HDC; rc: HGLRC; hndl: THandle);&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_ChooseFailed = 'ChoosePixelFormat failed with ';&lt;br /&gt;
var&lt;br /&gt;
  pfd: TPixelFormatDescriptor;&lt;br /&gt;
  PixelFormat: TGLUint;&lt;br /&gt;
  pFlags: TPFDFlags;&lt;br /&gt;
  flags: word absolute pFlags;&lt;br /&gt;
  StencilBits,&lt;br /&gt;
  ColorBits,&lt;br /&gt;
  DepthBits: integer;&lt;br /&gt;
begin&lt;br /&gt;
  pflags := [];&lt;br /&gt;
  include (pflags, DoubleBuffer);&lt;br /&gt;
  include (pflags, Stereo);&lt;br /&gt;
  include (pflags, Draw_To_Window);&lt;br /&gt;
  include (pflags, Draw_To_Bitmap);&lt;br /&gt;
  include (pflags, Support_GDI);&lt;br /&gt;
  include (pflags, Support_OpenGL);&lt;br /&gt;
  include (pflags, Generic_Format);&lt;br /&gt;
  include (pflags, Need_Palette);&lt;br /&gt;
  include (pflags, Need_System_Palette);&lt;br /&gt;
  include (pflags, Swap_Exchange);&lt;br /&gt;
  include (pflags, Swap_Copy);&lt;br /&gt;
  include (pflags, Swap_Layer_Buffers);&lt;br /&gt;
  include (pflags, Generic_Accelerated);&lt;br /&gt;
&lt;br /&gt;
  ColorBits := 24;&lt;br /&gt;
  DepthBits := 32;&lt;br /&gt;
  StencilBits := 0;&lt;br /&gt;
&lt;br /&gt;
  with TWinControl(hndl) do&lt;br /&gt;
  begin&lt;br /&gt;
    fillchar(pfd,SizeOf(pfd),0);&lt;br /&gt;
    with pfd do&lt;br /&gt;
    begin&lt;br /&gt;
      nSize           := SizeOf(pfd);&lt;br /&gt;
      nVersion        := 1;&lt;br /&gt;
      dwFlags         := flags or&lt;br /&gt;
                         PFD_DRAW_TO_WINDOW&lt;br /&gt;
                         or PFD_SUPPORT_OPENGL&lt;br /&gt;
                         or PFD_DOUBLEBUFFER;&lt;br /&gt;
      iPixelType      := PFD_TYPE_RGBA;&lt;br /&gt;
      cColorBits      := ColorBits;&lt;br /&gt;
      cDepthBits      := DepthBits;&lt;br /&gt;
      cStencilBits    := StencilBits;&lt;br /&gt;
      iLayerType      := PFD_MAIN_PLANE;&lt;br /&gt;
      cRedBits        := 0;&lt;br /&gt;
      cRedShift       := 0;&lt;br /&gt;
      cGreenBits      := 0;&lt;br /&gt;
      cBlueBits       := 0;&lt;br /&gt;
      cBlueShift      := 0;&lt;br /&gt;
      cAlphaBits      := 0;&lt;br /&gt;
      cAlphaShift     := 0;&lt;br /&gt;
      cAccumBits      := 0;&lt;br /&gt;
      cAccumRedBits   := 0;&lt;br /&gt;
      cAccumGreenBits := 0;&lt;br /&gt;
      cAccumBlueBits  := 0;&lt;br /&gt;
      cAccumAlphaBits := 0;&lt;br /&gt;
      cAuxBuffers     := 0;&lt;br /&gt;
      bReserved       := 0;&lt;br /&gt;
      dwLayerMask     := 0;&lt;br /&gt;
      dwVisibleMask   := 0;&lt;br /&gt;
      dwDamageMask    := 0;&lt;br /&gt;
    end; {with}&lt;br /&gt;
&lt;br /&gt;
    PixelFormat := ChoosePixelFormat(dc, @pfd);&lt;br /&gt;
    if PixelFormat=0 then&lt;br /&gt;
      raise Exception.Create(Res_ChooseFailed+IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
    //if not SetPixelFormat(FglDC, PixelFormat, @pfd) then&lt;br /&gt;
    //  raise Exception.Create('SetPixelFormat failed with '+&lt;br /&gt;
    //    IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function CheckFormat (number: string; digits, decimals: byte): string;&lt;br /&gt;
// wandelt ein mögliches dezimalkomma in einen punkt um&lt;br /&gt;
// beschneidet den übergebenen zahlenstring auf die gewünschten&lt;br /&gt;
// vorkomma- und nachkommastellen&lt;br /&gt;
// der übergebene zahlenstring darf keine tausender-kommas&lt;br /&gt;
// oder punkte enthalten!&lt;br /&gt;
var&lt;br /&gt;
  sdigits, sdecimals, temp: string;&lt;br /&gt;
  posi: integer;&lt;br /&gt;
begin&lt;br /&gt;
  if digits+decimals = 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    temp := '';&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    sdigits := '';&lt;br /&gt;
    sdecimals := '';&lt;br /&gt;
    posi := pos (',', number);&lt;br /&gt;
    if posi = 0 then&lt;br /&gt;
      posi := pos ('.', number);&lt;br /&gt;
    if posi &amp;gt; 0 then&lt;br /&gt;
      sdigits := copy (number, 1, posi-1);&lt;br /&gt;
    if length (number) &amp;gt; posi then&lt;br /&gt;
      sdecimals := copy (number, posi+1);&lt;br /&gt;
    if length (sdigits) &amp;gt; digits then&lt;br /&gt;
      sdigits := copy (sdigits, length (sdigits)-(digits-1));&lt;br /&gt;
    if length (sdecimals) &amp;gt; decimals then&lt;br /&gt;
      sdecimals := copy (sdecimals, 1, decimals);&lt;br /&gt;
    temp := sdigits + '.' + sdecimals;&lt;br /&gt;
  end;&lt;br /&gt;
  result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure ResetGLErrorFlags;&lt;br /&gt;
var&lt;br /&gt;
  err: GLenum;&lt;br /&gt;
begin&lt;br /&gt;
  repeat&lt;br /&gt;
    err := glGetError;&lt;br /&gt;
  until err = GL_NO_ERROR;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ValidTexture (tex: GLUint; ErrStr: string): boolean;&lt;br /&gt;
var&lt;br /&gt;
  error: GLenum;&lt;br /&gt;
begin&lt;br /&gt;
  result := true;&lt;br /&gt;
&lt;br /&gt;
  ResetGLErrorFlags;&lt;br /&gt;
  if not glIsTexture (tex) then&lt;br /&gt;
  begin&lt;br /&gt;
    error := glGetError;&lt;br /&gt;
    Application.MessageBox(pChar ('Textur wurde nicht erkannt!'+chr(13)+chr(10)+&lt;br /&gt;
                           ErrStr+chr(13)+chr(10)+&lt;br /&gt;
                           'Fehler: '+IntToStr (error)),&lt;br /&gt;
                           'Fehler',&lt;br /&gt;
                           0);&lt;br /&gt;
    result := false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AxisXRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  V1.Z := 0;&lt;br /&gt;
  V2.Z := 0;&lt;br /&gt;
  result := DotProduct (V1, V2);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AxisYRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  V1.Z := 0;&lt;br /&gt;
  V2.Z := 0;&lt;br /&gt;
  result := DotProduct (V1, V2);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AxisZRotation (V1, V2: TGLvector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  V1.Y := 0;&lt;br /&gt;
  V2.Y := 0;&lt;br /&gt;
  result := DotProduct (V1, V2);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ExePath: string;&lt;br /&gt;
var&lt;br /&gt;
  pfad: string;&lt;br /&gt;
begin&lt;br /&gt;
  pfad := ExtractFilePath (Application.Exename);&lt;br /&gt;
  if copy (pfad, length (pfad), 1) &amp;lt;&amp;gt; '\' then&lt;br /&gt;
    pfad := pfad + '\';&lt;br /&gt;
  result := pfad;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=19715</id>
		<title>Kamera (2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=19715"/>
				<updated>2006-10-07T05:17:51Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Wie ich selber immer wieder merken muss, ist eine Software anscheinend&lt;br /&gt;
// nie fertig. Immer moechte man etwas verbessern oder neue Features&lt;br /&gt;
// einbauen.&lt;br /&gt;
// Sollte also jemand Änderungs- oder Verbesserungsvorschläge haben oder&lt;br /&gt;
// neue Ideen einbringen wollen, oder sollten Verstaendnisfragen bestehen,&lt;br /&gt;
// so mailt bitte an&lt;br /&gt;
//&lt;br /&gt;
// Andree.Heyroth@t-online.de&lt;br /&gt;
//&lt;br /&gt;
// Danke.&lt;br /&gt;
//&lt;br /&gt;
// Updates:&lt;br /&gt;
//&lt;br /&gt;
// 06.11.2005&lt;br /&gt;
// Die Deklaration der DESTROY Methode war falsch. Das fuehrte dazu,&lt;br /&gt;
// dass in der Methode CREATE erzeugte Objekte nicht richtig frei-&lt;br /&gt;
// gegeben wurden und es zu EAccessViolations kam. Die Methode wird&lt;br /&gt;
// jetzt in der PUBLIC Section mit der Direktive OVERRIDE aufgerufen.&lt;br /&gt;
//&lt;br /&gt;
// 11.11.2005&lt;br /&gt;
// Die Positionierung funktioniert jetzt.&lt;br /&gt;
// Wegen eines Verstaendnisproblems wurden die Positionen immer auf den&lt;br /&gt;
// Kamerapunkt aufaddiert. Das bedeutete, dass die Positionierung aus&lt;br /&gt;
// dem Ruder lief wenn sie nicht im Nullpunkt stattfand. Je groesser die&lt;br /&gt;
// gewuenschte Position war um so groesser war die Abweichung von der&lt;br /&gt;
// Darstellung.&lt;br /&gt;
// Ich habe nicht bedacht, dass bei einer &amp;quot;Kamera&amp;quot;-bewegung und -drehung&lt;br /&gt;
// ja eigentlich die Szene bewegt und gedreht wird. Deswegen wurden nach&lt;br /&gt;
// einer Positionierung die folgenden Projektionen immer basierend auf der&lt;br /&gt;
// danach gueltigen Kameraposition gemacht.&lt;br /&gt;
// Jetzt wird die Position so gesetzt, dass die gewuenschte Kameraposition&lt;br /&gt;
// immer vor dem Betrachter steht.&lt;br /&gt;
//&lt;br /&gt;
// 23.11.2005&lt;br /&gt;
// Neues Flag (FFixedAxis) zur Entscheidung zwischen angepasster und realer&lt;br /&gt;
// Drehung. Dadurch wird das Bewegungsmodell angepasst. Siehe Methode Offset,&lt;br /&gt;
// bzw. UpdateMatrixOffset.&lt;br /&gt;
//&lt;br /&gt;
// 10.12.2005&lt;br /&gt;
// Property PointOfRotation ist jetzt nicht mehr ReadOnly.&lt;br /&gt;
// Der Blickpunkt bzw. Rotationspunkt kann jetzt direkt verändert werden.&lt;br /&gt;
// So kann eine neue Blickrichtung angenommen werden ohne vorher die Kamera-&lt;br /&gt;
// eigenschaften zu sichern und nach einem PositionCamera wieder zu setzen.&lt;br /&gt;
//&lt;br /&gt;
// 19.12.2005&lt;br /&gt;
// Neue Methode PositionCross.&lt;br /&gt;
// Die Methode PositionCross schiebt das Fadenkreuz in den angegebenen Punkt&lt;br /&gt;
// ohne die Lage der Szene zu verändern. Diese Funktionalitaet ist anders als&lt;br /&gt;
// ein neues Setzen der Property FPointOfRotation weil dabei die Szene in das&lt;br /&gt;
// Koordinatenkreuz geschoben wird.&lt;br /&gt;
//&lt;br /&gt;
// 31.01.2006&lt;br /&gt;
// Umstellung auf genaueres Zahlenformat&lt;br /&gt;
// Da die Darstellung von Szenen ausserhalb des Bereichs von FLOAT-Zahlen&lt;br /&gt;
// nicht funktioniert, muss alles auf DOUBLE umgestellt werden. Dazu gehört&lt;br /&gt;
// das Ersetzen von Datentypen und der Aufruf der entsprechenden GL-Funktionen.&lt;br /&gt;
//&lt;br /&gt;
unit Camera;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
  Uses DglOpenGL, Util, Windows, Classes;&lt;br /&gt;
&lt;br /&gt;
  type&lt;br /&gt;
  TCameraMatrix=Class&lt;br /&gt;
    StackMatrix: array [0..9] of TArrMatrix;&lt;br /&gt;
    StackCtr: integer;&lt;br /&gt;
    Matrix: TArrMatrix;&lt;br /&gt;
    InverseMatrix: TArrMatrix;&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    //destructor destroy;&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Push;&lt;br /&gt;
    procedure Pop;&lt;br /&gt;
    procedure Load(M: TArrMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TCamera=Class&lt;br /&gt;
    Enabled: boolean;&lt;br /&gt;
    function UpVector: TGLvector;&lt;br /&gt;
    procedure RestorePosition(pos: integer);&lt;br /&gt;
    procedure SavePosition(pos: integer);&lt;br /&gt;
    function GiveStoredPosition(pos: integer): TGLvector;&lt;br /&gt;
    procedure RotateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
    procedure TranslateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
    procedure CameraHome;&lt;br /&gt;
    procedure PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector);&lt;br /&gt;
    procedure Adjust;&lt;br /&gt;
    procedure Apply;&lt;br /&gt;
    procedure ApplyForTerrain;&lt;br /&gt;
  private&lt;br /&gt;
    FPosition: TGLvector;&lt;br /&gt;
    FViewDirection: TGLvector;&lt;br /&gt;
    FPointOfRotation: TGLvector;&lt;br /&gt;
    HomeMatrix: TCameraMatrix;&lt;br /&gt;
    CameraMatrix: TCameraMatrix;&lt;br /&gt;
    Initiated: boolean;&lt;br /&gt;
    PosArray: array [0..9] of TCameraMatrix;&lt;br /&gt;
    RotArray: array [0..9] of TGLvector;&lt;br /&gt;
    FFixedAxis: boolean;&lt;br /&gt;
    procedure Debug (Text: string);&lt;br /&gt;
    function UpdateMatrixOffset(newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
    function GetViewDirection: TGLvector;&lt;br /&gt;
    procedure SetViewDirection (View: TGLvector);&lt;br /&gt;
    procedure Initiate;&lt;br /&gt;
    function GetPosition: TGLvector;&lt;br /&gt;
    procedure SetPosition (Pos: TGLvector);&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Offset(x, y, z: GLdouble);&lt;br /&gt;
    procedure RotateRoundAxis(rx, ry, rz: GLdouble);&lt;br /&gt;
    procedure SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    destructor Destroy;override;&lt;br /&gt;
    function InverseMatrix: TArrMatrix;&lt;br /&gt;
    procedure ApplyInvers;&lt;br /&gt;
    procedure PositionCross(CrossVec: TGLvector);&lt;br /&gt;
  published&lt;br /&gt;
    property PointOfRotation: TGLvector read FPointOfRotation write SetPointOfRotation;&lt;br /&gt;
    property Position: TGLvector read GetPosition write SetPosition;&lt;br /&gt;
    property ViewDirection: TGLvector read GetViewDirection write SetViewDirection;&lt;br /&gt;
    property FixedAxis: boolean read FFixedAxis write FFixedAxis;&lt;br /&gt;
  end;&lt;br /&gt;
  TPCamera=^TCamera;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FDebugFile: Textfile;&lt;br /&gt;
  FDebugFileName: string;&lt;br /&gt;
  FDebugOn: boolean;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses SysUtils;&lt;br /&gt;
&lt;br /&gt;
constructor TCameraMatrix.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
  StackCtr := 0;&lt;br /&gt;
end;&lt;br /&gt;
{&lt;br /&gt;
destructor TCameraMatrix.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Push;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; -1) and (StackCtr &amp;lt; 10) then&lt;br /&gt;
  begin&lt;br /&gt;
    StackMatrix[StackCtr] := Matrix;&lt;br /&gt;
    inc (StackCtr);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Pop;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; 0) and (StackCtr &amp;lt; 11) then&lt;br /&gt;
  begin&lt;br /&gt;
    dec (StackCtr);&lt;br /&gt;
    Load (StackMatrix[StackCtr]);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Identity;&lt;br /&gt;
// GetIdentity: aus OpenGL.pas&lt;br /&gt;
// initialisiert die CameraMatrix mit der Identitaetsmatrix&lt;br /&gt;
begin&lt;br /&gt;
  Matrix := GetIdentity(Matrix);&lt;br /&gt;
  InverseMatrix := GetIdentity(InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Load(M: TArrMatrix);&lt;br /&gt;
// die Matrix mit den Werten einer beliebigen anderen matrix fuellen&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i:=0 to 15 do&lt;br /&gt;
    Matrix[i]:=M[i];&lt;br /&gt;
  // die invertierte Matrix kann benutzt werden um Objkekte z.B.&lt;br /&gt;
  // immer zum Benutzer auszurichten&lt;br /&gt;
  InvertMatrix (M, InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
constructor TCamera.Create;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
&lt;br /&gt;
  // Initiated wird gebraucht um einmal alle Positionsspeicher&lt;br /&gt;
  // mit der Anfangsposition zu belegen&lt;br /&gt;
  Initiated := false;&lt;br /&gt;
&lt;br /&gt;
  // Kameramatrix anlegen&lt;br /&gt;
  CameraMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Matrix der letzten Position von PositionCamera anlegen&lt;br /&gt;
  HomeMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Positionsspeicher anlegen&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    PosArray[i] := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // standardmaessig immer entlang der bildschirmachsen verschieben&lt;br /&gt;
  FFixedAxis := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCamera.Destroy;&lt;br /&gt;
// alle in create belegten Resourcen wieder freigeben&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FreeAndNil (CameraMatrix);&lt;br /&gt;
  FreeAndNil (HomeMatrix);&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    FreeAndNil (PosArray[i]);&lt;br /&gt;
&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateRoundAxis(rx, ry, rz: GLdouble);&lt;br /&gt;
// hier drehen wir jetzt um die einzelnen Achsen.&lt;br /&gt;
// die Parameter geben die &amp;quot;Drehgeschwindigkeit&amp;quot; vor.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  tempX, tempY, tempZ: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Position und Lage der Kamera herstellen&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
&lt;br /&gt;
  if FFixedAxis then&lt;br /&gt;
  begin&lt;br /&gt;
    // über die bildschirmachsen drehen&lt;br /&gt;
    tempX := GetMatrixX (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempY := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempZ := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rx,tempX.X,tempX.Y,tempX.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(ry,tempY.X,tempY.Y,tempY.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rz,tempZ.X,tempZ.Y,tempZ.Z);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    // über die achsen des koordinatenkreuzes drehen&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rx,1,0,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(ry,0,1,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotated(rz,0,0,1);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // die neu erzeugte Matrix auslesen&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  // und in die Kameramatrix sichern&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Identity;&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Identity;&lt;br /&gt;
  HomeMatrix.Identity;&lt;br /&gt;
&lt;br /&gt;
  Enabled := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Offset(x, y, z: GLdouble);&lt;br /&gt;
// verschieben der Kamera auf einer beliebigen Achse&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  //OldView: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- Offset - Start --------------------------------------------------');&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslated(x,y,z);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  Debug ('Position: '+GLvectorToText (GetMatrixPos (newMatrix)));&lt;br /&gt;
  newMatrix := UpdateMatrixOffset (newMatrix);&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  Debug ('- Offset - Ende- --------------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
			                           ViewVec: TGLvector;&lt;br /&gt;
			                           upVec: TGLvector);&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  i: integer;&lt;br /&gt;
  P, V, U: TGLvector;&lt;br /&gt;
  Laenge: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCamera - Start ------------------------------------------');&lt;br /&gt;
  // die gewuenschte konstruktion immer auf die Z-ebene projizieren.&lt;br /&gt;
  // zuerst die position in den nullpunkt holen&lt;br /&gt;
  InitVector (P, 0, 0, 0);&lt;br /&gt;
  // jetzt den viewpoint um den gleichen betrag reduzieren, damit&lt;br /&gt;
  // die gerade parallel verschoben wird.&lt;br /&gt;
  V := SubtractVector (ViewVec, PositionVec);&lt;br /&gt;
  // U ist halt schneller geschrieben als upVec...&lt;br /&gt;
  U := upVec;&lt;br /&gt;
&lt;br /&gt;
  // den betrag ermitteln, um den die kamera nachher auf der Z-Achse&lt;br /&gt;
  // verschoben werden muss&lt;br /&gt;
  Laenge := Magnitude (SubtractVector (P, V));&lt;br /&gt;
&lt;br /&gt;
  Identity;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  // glulookat wird die matrix parallel zur Z-achse ausrichten&lt;br /&gt;
  gluLookAt (P.X, P.Y, P.Z, V.X, V.Y, V.Z, U.X, U.Y, U.Z);&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  HomeMatrix.Load(newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // da wir uns jetzt am zielpunkt befinden, müssen wir auf der Z-achse&lt;br /&gt;
  // wieder zurueck zur kameraposition&lt;br /&gt;
  Offset (0, 0, -Laenge);&lt;br /&gt;
&lt;br /&gt;
  // alle positionsspeicher mit der Kameraposition, Blickrichtung&lt;br /&gt;
  // und dem upVector belegen. Nur beim ersten Aufruf von&lt;br /&gt;
  // PositionCamera&lt;br /&gt;
  if not Initiated then&lt;br /&gt;
    Initiate;&lt;br /&gt;
&lt;br /&gt;
  FPointOfRotation := ViewVec;&lt;br /&gt;
  Debug ('PointOfRotation: '+GLvectorToText (FPointOfRotation));&lt;br /&gt;
  Debug ('- PositionCamera - Ende -------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCross (CrossVec: TGLvector);&lt;br /&gt;
// diese prozedur verschiebt, im gegensatz zu einem verändern von&lt;br /&gt;
// PointOfRotation, das Koordinatenkreuz und nicht die Szene.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  PosDiff: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCross - Start -------------------------------------------');&lt;br /&gt;
&lt;br /&gt;
  PosDiff := SubtractVector (FPointOfRotation, CrossVec);&lt;br /&gt;
&lt;br /&gt;
  // Szene in das koordinatenkreuz verschieben&lt;br /&gt;
  FPointOfRotation := CrossVec;&lt;br /&gt;
&lt;br /&gt;
  // jetzt die Szene wieder um den gleichen betrag zurückverschieben&lt;br /&gt;
  // das sieht dann so aus, als ob das koordinatenkreuz verschoben&lt;br /&gt;
  // worden wäre&lt;br /&gt;
  // zuerst die aktuelle neue Situation herstellen&lt;br /&gt;
  // (mit neuem FPointOfRotation)&lt;br /&gt;
  Apply;&lt;br /&gt;
&lt;br /&gt;
  // jetzt um den Differenzbetrag des alten und neuen&lt;br /&gt;
  // Rotationspunkts zurück verschieben&lt;br /&gt;
  glTranslated (-PosDiff.X, 0, 0);&lt;br /&gt;
  glTranslated (0, -PosDiff.Y, 0);&lt;br /&gt;
  glTranslated (0, 0, -PosDiff.Z);&lt;br /&gt;
&lt;br /&gt;
  // jetzt vom neuen Rotationspunktes zurück ins Zentrum, damit beim&lt;br /&gt;
  // nächsten Apply das glTranslatef (-FPointOfRotation, ...) klappt&lt;br /&gt;
  glTranslated (CrossVec.X, 0, 0);&lt;br /&gt;
  glTranslated (0, CrossVec.Y, 0);&lt;br /&gt;
  glTranslated (0, 0, CrossVec.Z);&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Matrix holen...&lt;br /&gt;
  glGetDoublev(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // und als Kameramatrix abspeichern&lt;br /&gt;
  CameraMatrix.Load(newmatrix);&lt;br /&gt;
  Debug ('- PositionCross - Ende --------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.CameraHome;&lt;br /&gt;
// Kamera in die beim letzten Aufruf von PositionCamera uebergebene&lt;br /&gt;
// Position/Lage bringen&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Load(HomeMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SavePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  PosArray[pos].Load(CameraMatrix.Matrix);&lt;br /&gt;
  RotArray[pos] := FPointOfRotation;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RestorePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(PosArray[pos].Matrix);&lt;br /&gt;
  FPointOfRotation := RotArray[pos];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GiveStoredPosition (pos: integer): TGLvector;&lt;br /&gt;
// gibt den Inhalt des durch pos bestimmten&lt;br /&gt;
// Positionsspecihers zurueck&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  result := GetMatrixPos (PosArray[pos].Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.TranslateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Verschiebung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  Offset (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateCamera(ix, iy, iz: GLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Drehung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  RotateRoundAxis (-iy, -ix, -iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Apply;&lt;br /&gt;
// hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur&lt;br /&gt;
// sollte die Szene mit allen benoetigten Drehungen, Verschiebungen&lt;br /&gt;
// gezeichnet werden.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
  glTranslated (-FPointOfRotation.X,&lt;br /&gt;
                -FPointOfRotation.y,&lt;br /&gt;
                -FPointOfRotation.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyForTerrain;&lt;br /&gt;
// hier wird wie in Apply die Kamera eingeschaltet. da man um ein terrain&lt;br /&gt;
// (skycube, ...) anzuzeigen aber immer die gleiche entfernung zur welt&lt;br /&gt;
// einhalten muss, wird hier nur gedreht und nicht verschoben.&lt;br /&gt;
var&lt;br /&gt;
  pos: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  // für das Terrain nur die Drehung ausführen&lt;br /&gt;
  glLoadMatrixd(@CameraMatrix.Matrix);&lt;br /&gt;
  // deswegen jetzt die verschiebung zurücknehmen&lt;br /&gt;
  Pos := GetMatrixPos (CameraMatrix.InverseMatrix);&lt;br /&gt;
  glTranslated (Pos.X, Pos.Y, Pos.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetPosition: TGLvector;&lt;br /&gt;
// diese Property-Funktion fragt die aktuelle Position der Kamera ab&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  result := AddVector (GetMatrixPos (CameraMatrix.InverseMatrix), FPointOfRotation);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPosition (Pos: TGLvector);&lt;br /&gt;
// diese Property-Funktion setzt eine neue Position der Kamera&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  m := CameraMatrix.Matrix;&lt;br /&gt;
  SetMatrixPos (m, SubtractVector (Pos, FPointOfRotation));&lt;br /&gt;
  CameraMatrix.Load (m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetViewDirection: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  result := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetViewDirection (View: TGLvector);&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// gesetzt werden&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  SetMatrixZ (CameraMatrix.InverseMatrix, View);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpVector: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Ausrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // upVector: zweite Spalte der Matrix (Y-Achse)&lt;br /&gt;
  result := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Adjust;&lt;br /&gt;
// mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhaengig&lt;br /&gt;
// von Drehung und Position, zur Y-Achse ausgerichtet werden.&lt;br /&gt;
// Die aktuelle Position wird dabei beibehalten.&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
  v: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // position aus der aktuellen cameramatrix holen&lt;br /&gt;
  v := GetMatrixPos (CameraMatrix.Matrix);&lt;br /&gt;
  // m mit identitätsmatrix initialisieren&lt;br /&gt;
  m := GetIdentity(m);&lt;br /&gt;
  // die position aus der aktuellen cameramatrix in m speichern&lt;br /&gt;
  SetMatrixPos (m, v);&lt;br /&gt;
  // m als aktuelle cameramatrix speichern&lt;br /&gt;
  CameraMatrix.Load(m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.InverseMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := CameraMatrix.InverseMatrix;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Initiate;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    SavePosition (i);&lt;br /&gt;
  Initiated := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpdateMatrixOffset (newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // wenn ich mit Multiply (FixedAxis) arbeite, wird die zeichnung immer&lt;br /&gt;
  // entlang der bildschirmachsen verschoben. wenn ich Multiply, version 2&lt;br /&gt;
  // nehme, wird sie auf den errechneten achsen verschoben.&lt;br /&gt;
  if FFixedAxis then&lt;br /&gt;
  begin&lt;br /&gt;
    result := Multiply (newMatrix, CameraMatrix.Matrix);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    result := Multiply (CameraMatrix.Matrix, newMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
// setzt den viewpoint oder rotationpoint  ohne die anderen parameter zu&lt;br /&gt;
// veraendern. so kann man z.B. eine Kamerafahrt in immer der gleichen&lt;br /&gt;
// position simulieren.&lt;br /&gt;
begin&lt;br /&gt;
  FPointOfRotation := NewPoint;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Debug (Text: string);&lt;br /&gt;
begin&lt;br /&gt;
  if not FDebugOn then&lt;br /&gt;
    exit;&lt;br /&gt;
  writeln (FDebugFile, DateToStr (date) + ' | ' +&lt;br /&gt;
                       TimeToStr (time) + ' | ' +&lt;br /&gt;
                       Text);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyInvers;&lt;br /&gt;
var&lt;br /&gt;
  M: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // Um Objekte immer zum benutzer ausrichten, darf nur die drehung angewendet&lt;br /&gt;
  // werden und nicht die verschiebung. Verschiebung wird hier zurückgenommen.&lt;br /&gt;
  // Vorher muss die Kamera angewendet und die nötigen Verschiebungen/&lt;br /&gt;
  // Drehungen ausgeführt werden. &lt;br /&gt;
  M := InverseMatrix;&lt;br /&gt;
  M[12] := 0;&lt;br /&gt;
  M[13] := 0;&lt;br /&gt;
  M[14] := 0;&lt;br /&gt;
  M[15] := 1;&lt;br /&gt;
  glMultMatrixd(@M);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
Initialization&lt;br /&gt;
  FDebugOn := false;&lt;br /&gt;
  FDebugFileName := ExePath + 'SKANAL3D_CAMERA.DBG';&lt;br /&gt;
  if FDebugOn then&lt;br /&gt;
  begin&lt;br /&gt;
    AssignFile (FDebugFile, FDebugFileName);&lt;br /&gt;
    Rewrite (FDebugFile);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
finalization&lt;br /&gt;
  if FDebugOn then&lt;br /&gt;
  begin&lt;br /&gt;
    CloseFile (FDebugFile);&lt;br /&gt;
    FDebugFileName := '';&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19714</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=19714"/>
				<updated>2006-10-07T05:16:29Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Nachdem ich bis jetzt glaubte, dass man mit der von mir erstellten Krzanleitung auskommt, hab eich doch noch ein Beispielprogramm erstellt. Nach mehrmaligem Studium meiner Kurzanleitung bin ich nämlich zu dem Schluss gekommen, dass man mit diesem Programmierbeispiel nicht zu dem von mir beabsichtigten Ergebnis kommen kann. Das Beispielprogramm, welches die Funktionen der Kamera veranschaulicht, wurde mit Delphi 2005 entwickelt. Wenn Ihr über eine ältere Delphiversion verfügt, nehmet einfach die DPR Datei oder erstellt ein neues Projekt mit Euerem Compiler und bindet die benötigten Dateien ein. &lt;br /&gt;
&lt;br /&gt;
Ich habe noch einiges mehr an Code reingepackt als unbedint nötig, um der Sache optisch ein Mindestmaß an Anspruch zu verleihen. Deswegen können aus diesem Beispielprogramm noch die eine oder andere Komponente entnommen werden (wenn nicht schon vorhanden). Dies sind z.B. Komponenten für Licht, Material, eine Skybox und zur Handhabung von Grafikdateien (die ist allerdings nicht auf meinem Mist gewachsen). Zusätlich habe ich noch den memory Manager FastMM4 beigepackt und eingebunden. Mit diesem kann man sehr schön (besser als mit den von Delphi bereitgestellten Möglichkeiten) nicht freigegebene Resourcen aufspüren. Ich war überrascht was ich alles nicht freigegeben hatte, als ich den zume rsten mal eingesetzt habe.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andyh).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17972</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17972"/>
				<updated>2006-05-21T06:33:03Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then&lt;br /&gt;
    Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFExample.Render: wglMakeCurrent failed with ';&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17971</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17971"/>
				<updated>2006-05-21T06:30:51Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFExample.Render: wglMakeCurrent failed with ';&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17970</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17970"/>
				<updated>2006-05-21T06:27:35Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    FCamera: TCamera;&lt;br /&gt;
&lt;br /&gt;
    FglDC: HDC;               // device context der aktuellen komponente&lt;br /&gt;
    FglRC: HGLRC;             // rendering kontext der aktuellen komponente&lt;br /&gt;
&lt;br /&gt;
    ClearAlpha: GLclampd;     // alpha wert der hintergrundfarbe&lt;br /&gt;
    ClearRed: GLclampd;       // rotanteil der hintergrundfarbe&lt;br /&gt;
    ClearGreen: GLclampd;     // grünanteil der hintergrundfarbe&lt;br /&gt;
    ClearBlue: GLclampd;      // blauanteil der hintergrundfarbe&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
resourcestring&lt;br /&gt;
  ResStrRCfailed = 'CreateRenderingContext failed ';&lt;br /&gt;
  ResStrWGLfailed = 'wglMakeCurrent failed ';&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  // wenn das grafiksystem von OpenGL nicht aktiviert werden kann,&lt;br /&gt;
  // müssen wir das programm beenden&lt;br /&gt;
  if not InitOpenGL then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create('InitOpenGL failed '+IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  FglDC := getDC(self.WindowHandle);&lt;br /&gt;
  FglRC := CreateRenderingContext(FglDC,&lt;br /&gt;
                                  [opDoubleBuffered],&lt;br /&gt;
                                  32, 24, 0,0,0,0);&lt;br /&gt;
&lt;br /&gt;
  if FglRC=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(ResStrRCfailed + IntToStr(GetLastError));&lt;br /&gt;
    halt (100);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not wglMakeCurrent(FglDC, FglRC) then&lt;br /&gt;
    raise Exception.Create(ResStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
&lt;br /&gt;
  ClearAlpha := 1;         // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearRed:= 1;            // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearGreen:= 1;          // bildschirm immer mit weiß löschen&lt;br /&gt;
  ClearBlue:= 1;           // bildschirm immer mit weiß löschen&lt;br /&gt;
&lt;br /&gt;
  FCamera := TCamera.Create;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.Render;  // wird aus der Methode Paint aufgerufen&lt;br /&gt;
resourcestring&lt;br /&gt;
  RestStrWGLfailed = 'TFKanal3D.Render: wglMakeCurrent failed with ';&lt;br /&gt;
var&lt;br /&gt;
  pDir: TGKvector;&lt;br /&gt;
begin&lt;br /&gt;
  // da mehrere fenster möglich sind, muss immer der aktuelle&lt;br /&gt;
  // ausgabekontext ausgewählt werden&lt;br /&gt;
  if wglMakeCurrent(FglDC,FglRC) then&lt;br /&gt;
  begin&lt;br /&gt;
    glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
    glClearColor(ClearRed, ClearGreen, ClearBlue, ClearAlpha);&lt;br /&gt;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
    // View setzen&lt;br /&gt;
&lt;br /&gt;
    Camera1.Apply;&lt;br /&gt;
&lt;br /&gt;
    // Szene jetzt zeichnen&lt;br /&gt;
&lt;br /&gt;
    glFlush;              // bearbeitung der GL-befehle beginnen&lt;br /&gt;
    glFinish;             // warten bis alle befehle ausgeführt sind&lt;br /&gt;
&lt;br /&gt;
    SwapBuffers(FglDC);   // flackern verhindern&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    raise Exception.Create(RestStrWGLfailed + IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17964</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17964"/>
				<updated>2006-05-21T06:06:19Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehmen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist vereinfacht dargestellt und es ist sehr wahrscheinlich, dass Ihr daran noch etwas herumspielen müsst. Ich habe noch das Mausrad eingesetzt um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17963</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17963"/>
				<updated>2006-05-21T06:00:06Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  crCursorMove = 1;&lt;br /&gt;
  crCursorRotate = 2;&lt;br /&gt;
  crCursorSelect = 3;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&lt;br /&gt;
{$R *.dfm}&lt;br /&gt;
{$R cursors.res}&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
&lt;br /&gt;
  Screen.Cursors[crCursorMove]   := LoadCursor(HInstance,'MOVE');&lt;br /&gt;
  Screen.Cursors[crCursorRotate] := LoadCursor(HInstance,'ROTATE');&lt;br /&gt;
  Screen.Cursors[crCursorSelect] := LoadCursor(HInstance,'SELECT');&lt;br /&gt;
  Screen.Cursor                  := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das mit den unterschiedlichen Cursordarstellungen habe ich nur als Hinweis gelassen. Diese Anweisungen müsst Ihr rausnehemen es sei denn, dass Ihr eine Resourcendatei mit drei unterschiedlichen Cursorarten erstellt und sie unter &amp;quot;Cursors.res&amp;quot; abspeichert.&lt;br /&gt;
&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17962</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17962"/>
				<updated>2006-05-21T05:52:23Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePosX, FMousePosY,&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxStart,                     // berechnung der mausbewegungen.&lt;br /&gt;
  FxDelta,                     // delta = aktuelle position minus start&lt;br /&gt;
  FyStart,                     // start wird erfasst sobald eine maustaste&lt;br /&gt;
  FyDelta:integer;             // gedrückt wird.&lt;br /&gt;
&lt;br /&gt;
  FxRot,                       // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;                // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,                // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,                  // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
  //mausaktivität überprüfen&lt;br /&gt;
  FRightMousePressed:boolean;  // ist die rechte maustaste gedrückt?&lt;br /&gt;
  FLeftMousePressed:boolean;   // ist die linke maustaste gedrückt?&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  // mausposition merken&lt;br /&gt;
  FMousePosX := X;&lt;br /&gt;
  FMousePosY := Y;&lt;br /&gt;
&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17961</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17961"/>
				<updated>2006-05-21T05:47:55Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit Example;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
  Windows, ...&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TFExample = class(TForm)&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  private&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  public&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
  published&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
    .&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FExample: TFExample;&lt;br /&gt;
&lt;br /&gt;
  FxRot,                    // umrechnung von delta in rotation wenn&lt;br /&gt;
  FyRot:double;             // drehung gewünscht ist (je nach taste)&lt;br /&gt;
&lt;br /&gt;
  FMousePressX,             // aktuelle mausposition, wenn maustaste gedrückt wird&lt;br /&gt;
  FMousePressY: integer;&lt;br /&gt;
  FMousePosX,               // aktuelle mausposition&lt;br /&gt;
  FMousePosY: integer;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses ...&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TFExample.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17960</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17960"/>
				<updated>2006-05-21T05:41:04Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  inherited;&lt;br /&gt;
&lt;br /&gt;
  FxRot:=0;&lt;br /&gt;
  FyRot:=0;&lt;br /&gt;
&lt;br /&gt;
  FRightMousePressed := false;&lt;br /&gt;
  FLeftMousePressed := false;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17959</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17959"/>
				<updated>2006-05-21T05:36:08Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17958</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=17958"/>
				<updated>2006-05-21T05:35:22Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
FMousePressX, FMousePressY,&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot (sind alle als var im aktuellen Modul definiert)&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseDown(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                                 Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FRightMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorRotate;&lt;br /&gt;
  end&lt;br /&gt;
  else if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    //rechte maustaste gedrückt&lt;br /&gt;
    FLeftMousePressed:=true;&lt;br /&gt;
    //Startposition merken&lt;br /&gt;
    FxStart:=X;&lt;br /&gt;
    FyStart:=Y;&lt;br /&gt;
    Screen.Cursor := crCursorMove;&lt;br /&gt;
  end;&lt;br /&gt;
  // aktuelle Mouseposition festhalten. so kann z.B. überprüft werden &lt;br /&gt;
  // welches Objekt an der aktuellen Mausposition liegt&lt;br /&gt;
  FMousePressX := X;&lt;br /&gt;
  FMousePressY := Y;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
                               Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
  if Button = mbRight then&lt;br /&gt;
  begin&lt;br /&gt;
    FRightMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  if Button = mbLeft then&lt;br /&gt;
  begin&lt;br /&gt;
    FLeftMousePressed:=false;&lt;br /&gt;
  end;&lt;br /&gt;
  Screen.Cursor := crCursorSelect;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16229</id>
		<title>Diskussion:Detail Mapping</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16229"/>
				<updated>2006-02-08T07:49:39Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
ich versuche schon seit ein paar Tagen, meine Texturen mit Detailmapping zu verfeinern. Vom Prinzip her ist mir auch schon klar wie es geht, aber es hapert noch an ein paar Kleinigkeiten. Der hier verfügbare Artikel hat mir auch schon weitergeholfen aber einiges ist mir am dargestellten Beispiel nicht ganz klar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Alle Schnittpunkte des Objektes renderm&lt;br /&gt;
for v := 0 to High(VertexData) do  // wo kommt VertexData her? ist das OpenGL?&lt;br /&gt;
begin                              // ----------------------------------------&lt;br /&gt;
  // ...&lt;br /&gt;
 &lt;br /&gt;
  // Texturkoordinate für die Detailtextur&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE1, Vertex[v].s*16, Vertex[v].t*16);  // das gleiche mit Vertex.&lt;br /&gt;
  // Texturkoordinate für die Basistextur                          // woher kommt diese Array?&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE0, Vertex[v].s, Vertex[v].t);        // ------------------------&lt;br /&gt;
 &lt;br /&gt;
  // ...&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine Auflösung meines Knotens wäre ich sehr dankbar,&lt;br /&gt;
&lt;br /&gt;
Andy&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Fragen ins Forum&lt;br /&gt;
&lt;br /&gt;
Ansonsten soviel:&lt;br /&gt;
&lt;br /&gt;
*VertexData = zu rendernde Daten (soweit ich das sehe)&lt;br /&gt;
*Vertex = Texturkoordinaten (wenn ich das richtig interpretiere)&lt;br /&gt;
&lt;br /&gt;
Ansonsten schau doch einfach mal in die Doku der verwendeten Befehle ...&lt;br /&gt;
&lt;br /&gt;
MfG,&lt;br /&gt;
--[[Benutzer:BenBE|BenBE]] 13:54, 5. Feb 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------------&lt;br /&gt;
Sorry, werde ich das nächste mal tun (Fragen in´s Forum).&lt;br /&gt;
&lt;br /&gt;
Vielen Dank für die Antwort,&lt;br /&gt;
&lt;br /&gt;
Andy&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16221</id>
		<title>Diskussion:Detail Mapping</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16221"/>
				<updated>2006-02-03T07:49:16Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
ich versuche schon seit ein paar Tagen, meine Texturen mit Detailmapping zu verfeinern. Vom Prinzip her ist mir auch schon klar wie es geht, aber es hapert noch an ein paar Kleinigkeiten. Der hier verfügbare Artikel hat mir auch schon weitergeholfen aber einiges ist mir am dargestellten Beispiel nicht ganz klar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Alle Schnittpunkte des Objektes renderm&lt;br /&gt;
for v := 0 to High(VertexData) do  // wo kommt VertexData her? ist das OpenGL?&lt;br /&gt;
begin                              // ----------------------------------------&lt;br /&gt;
  // ...&lt;br /&gt;
 &lt;br /&gt;
  // Texturkoordinate für die Detailtextur&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE1, Vertex[v].s*16, Vertex[v].t*16);  // das gleiche mit Vertex.&lt;br /&gt;
  // Texturkoordinate für die Basistextur                          // woher kommt diese Array?&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE0, Vertex[v].s, Vertex[v].t);        // ------------------------&lt;br /&gt;
 &lt;br /&gt;
  // ...&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine Auflösung meines Knotens wäre ich sehr dankbar,&lt;br /&gt;
&lt;br /&gt;
Andy&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16220</id>
		<title>Diskussion:Detail Mapping</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16220"/>
				<updated>2006-02-03T07:48:16Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
ich versuche schon seit ein paar Tagen, meine Texturen mit Detailmapping zu verfeinern. Vom Prinzip her ist mir auch schon klar wie es geht, aber es hapert noch an ein paar Kleinigkeiten. Der hier verfügbare Artikel hat mir auch schon weitergeholfen aber einiges ist mir am dargestellten Beispiel nicht ganz klar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Alle Schnittpunkte des Objektes renderm&lt;br /&gt;
for v := 0 to High(VertexData) do  // wo kommt VertexData her? ist das OpenGL?&lt;br /&gt;
begin                              // ----------------------------------------&lt;br /&gt;
  // ...&lt;br /&gt;
 &lt;br /&gt;
  // Texturkoordinate für die Detailtextur&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE1, Vertex[v].s*16, Vertex[v].t*16);  // das gleiche mit Vertex.&lt;br /&gt;
  // Texturkoordinate für die Basistextur                          // woher kommt diese Array?&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE0, Vertex[v].s, Vertex[v].t);        // ------------------------&lt;br /&gt;
 &lt;br /&gt;
  // ...&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine Auflösung meines Knotens wäre ih sehr dankbar,&lt;br /&gt;
&lt;br /&gt;
Andy&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16219</id>
		<title>Diskussion:Detail Mapping</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Diskussion:Detail_Mapping&amp;diff=16219"/>
				<updated>2006-02-03T07:46:53Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
ich versuche schon seit ein paar Tagen, meine Texturen mit Detailmapping zu verfeinern. Vom Prinzip her ist mir auch schon klar wie es geht, aber es hapert noch an ein paar Kleinigkeiten. Der hier verfügbare Artikel hat mir auch schon weitergeholfen aber einiges ist mir am dargestellten Beispiel nicht ganz klar:&lt;br /&gt;
&lt;br /&gt;
// Alle Schnittpunkte des Objektes renderm&lt;br /&gt;
for v := 0 to High(VertexData) do  // wo kommt VertexData her? ist das OpenGL?&lt;br /&gt;
begin                              // ----------------------------------------&lt;br /&gt;
  // ...&lt;br /&gt;
 &lt;br /&gt;
  // Texturkoordinate für die Detailtextur&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE1, Vertex[v].s*16, Vertex[v].t*16);  // das gleiche mit Vertex.&lt;br /&gt;
  // Texturkoordinate für die Basistextur                          // woher kommt diese Array?&lt;br /&gt;
  glMultiTexCoord2f(GL_TEXTURE0, Vertex[v].s, Vertex[v].t);        // ------------------------&lt;br /&gt;
 &lt;br /&gt;
  // ...&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
Für eine Auflösung meines Knotens wäre ih sehr dankbar,&lt;br /&gt;
&lt;br /&gt;
Andy&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=16155</id>
		<title>Kamera (1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(1)&amp;diff=16155"/>
				<updated>2006-01-19T08:09:27Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Danke==&lt;br /&gt;
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.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot; zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Meine Kamera==&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wiederherstellen. (SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen Position senkrecht zur Welt ausrichten. (Adjust)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben, so stehe ich gerne zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
==Gebrauch der Funktionen:==&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
2.  &lt;br /&gt;
Aufruf der Funktionen RotateCamera und TranslateCamera um die Ausrichtung/Lage der Kamera zu verändern. z.B.:&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed, FLeftMousePressed,&lt;br /&gt;
FxDelta, FyDelta, FxStart, FyStart,&lt;br /&gt;
FxRot und FyRot sind als var im aktuellen Modul definiert.&lt;br /&gt;
&lt;br /&gt;
FRightMousePressed und FLeftMousePressed müssen in der Prozedur MouseDown/MouseUp gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
FxRot und FyRot müssen mit 0 initialisiert werden.&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);&lt;br /&gt;
begin&lt;br /&gt;
   //das Ziehen der Szene kann nur bei gedrückter Maustaste passieren&lt;br /&gt;
  if not (FRightMousePressed or FLeftMousePressed) then exit;&lt;br /&gt;
&lt;br /&gt;
   //ausrechenen um wieviel der Mauszeiger bewegt wurde&lt;br /&gt;
   FxDelta := FxStart-X;&lt;br /&gt;
   FyDelta := FyStart-Y;&lt;br /&gt;
&lt;br /&gt;
   //Rotation anpassen, damit es nicht zu schnell wird&lt;br /&gt;
   FxRot := FxRot - FyDelta/20;&lt;br /&gt;
   Fyrot := FyRot - FxDelta/20;&lt;br /&gt;
&lt;br /&gt;
   //das naechste mal ist das hier unser startpunkt:&lt;br /&gt;
   FxStart := X;&lt;br /&gt;
   FyStart := Y;&lt;br /&gt;
&lt;br /&gt;
   if FRightMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.RotateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   if FLeftMousePressed then&lt;br /&gt;
   begin&lt;br /&gt;
     if FxRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (FxRot, 0, 0);&lt;br /&gt;
     if FyRot &amp;lt;&amp;gt; 0 then FCamera.TranslateCamera (0, FyRot, 0);&lt;br /&gt;
   end;&lt;br /&gt;
   Paint;&lt;br /&gt;
&lt;br /&gt;
   FxRot := 0;&lt;br /&gt;
   FyRot := 0;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
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,?)).&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
3. Szene zeichnen:&lt;br /&gt;
&lt;br /&gt;
Lichteigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
Materialeigenschaften setzen&lt;br /&gt;
&lt;br /&gt;
... (die üblichen Vorbereitungen treffen)&lt;br /&gt;
&lt;br /&gt;
FCamera.Apply&lt;br /&gt;
&lt;br /&gt;
Szene zeichnen&lt;br /&gt;
&lt;br /&gt;
wenn Terrain gewünscht:&lt;br /&gt;
  FCamera.ApplyForTerrain&lt;br /&gt;
  Terrain zeichnen&lt;br /&gt;
ende wenn&lt;br /&gt;
&lt;br /&gt;
Swapbuffers...&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=16154</id>
		<title>Kamera</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera&amp;diff=16154"/>
				<updated>2006-01-19T08:05:47Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Andyh beschreibt in den Aritikeln:&lt;br /&gt;
*[[Kamera (1)]]&lt;br /&gt;
*[[Kamera (2)]]&lt;br /&gt;
*[[Kamera (3)]]&lt;br /&gt;
wie man eine Kamara realisiert.&lt;br /&gt;
&lt;br /&gt;
Andyh:&lt;br /&gt;
{{Zitat|&lt;br /&gt;
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera&lt;br /&gt;
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität&lt;br /&gt;
auch anderen zur Verfügung stellen.&lt;br /&gt;
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner &amp;quot;Schuld&amp;quot;&lt;br /&gt;
zurück zahlen.&lt;br /&gt;
&lt;br /&gt;
Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich&lt;br /&gt;
in allen Ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit&lt;br /&gt;
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Drehpunkt&lt;br /&gt;
benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man auf&lt;br /&gt;
die Property PointOfRotation zugreifen (read only).&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.&lt;br /&gt;
(SavePosition, RestorePosition)&lt;br /&gt;
&lt;br /&gt;
Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen&lt;br /&gt;
Position senkrecht zur Welt ausrichten.&lt;br /&gt;
(Adjust)&lt;br /&gt;
&lt;br /&gt;
Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur &lt;br /&gt;
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung&lt;br /&gt;
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht&lt;br /&gt;
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.&lt;br /&gt;
&lt;br /&gt;
Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne&lt;br /&gt;
zur Verfügung (Andyh).}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(3)&amp;diff=16057</id>
		<title>Kamera (3)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(3)&amp;diff=16057"/>
				<updated>2006-01-08T07:05:44Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Den Kameracode findet ihr unter [[Kamera (2)]].&lt;br /&gt;
&lt;br /&gt;
Ich habe einfach alle Funktionen meiner Toolsammlung hierhin kopiert. Ich wollte jetzt nicht offline etwas weglöschen was vielleicht benötigt wird. Ihr findet also hier einen ganzen Wust von Funktionen, der zum Betrieb der Kamera nicht benötigt wird. Vielleicht könnt Ihr das eine oder andere aber brauchen...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
unit OpenGLUtil;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses DglOpenGL, Math, Windows, Graphics, SysUtils, Dialogs, glBmp;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
  TProjection=(Frustum, Orthographic, Perspective);&lt;br /&gt;
&lt;br /&gt;
  TGLPlace=packed record&lt;br /&gt;
    X,Y,Z: glFloat;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TScale=packed record&lt;br /&gt;
    X,Y,Z: glFloat;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLPosition=packed record&lt;br /&gt;
    X,Y,Z,W: glFloat;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TPosition = packed record&lt;br /&gt;
    X,Y,Z,W: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLVector = packed record&lt;br /&gt;
    X,Y,Z: GLfloat;&lt;br /&gt;
  end;&lt;br /&gt;
  TGLVectorArray = array of TGLvector;&lt;br /&gt;
  TGLfloatArray = array of TGLfloat;&lt;br /&gt;
&lt;br /&gt;
  TGKVector = packed record&lt;br /&gt;
    X,Y,Z: GLfloat;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TAngle = packed record&lt;br /&gt;
    X,Y,Z: GLdouble;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TGLColor=record&lt;br /&gt;
    red,green,blue,alpha: GLclampf;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TRotation = packed record&lt;br /&gt;
    angle, x, y, z: GLfloat;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TTextureInfo = packed record&lt;br /&gt;
    BitmapName: string;&lt;br /&gt;
    TextureNum: GLUint;&lt;br /&gt;
    theBmp: TGLbmp;&lt;br /&gt;
  end;&lt;br /&gt;
  TTextureList = array of TTextureInfo;&lt;br /&gt;
&lt;br /&gt;
  TMatrix = array [0..3,0..3] of TGLFloat;&lt;br /&gt;
  TArrMatrix = array [0..15] of TGLFloat;&lt;br /&gt;
  TFrustum = array [0..5,0..3] of TGLFloat;&lt;br /&gt;
  TArrVector = array [0..3] of TGLFloat;&lt;br /&gt;
&lt;br /&gt;
  function GetMatrixX (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixY (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixZ (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  function GetMatrixPos (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
  procedure SetMatrixX (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixY (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixZ (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  procedure SetMatrixPos (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
  function Multiply (Color: TGLcolor; m: TGLdouble): TGLcolor;overload;&lt;br /&gt;
  function Multiply (V1, V2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function Multiply (M1, M2: TArrMatrix): TArrMatrix;overload;&lt;br /&gt;
  function Divide (V1, V2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function Divide (V1: TGLVector; d: TGLdouble): TGLVector;overload;&lt;br /&gt;
  function MakeVector(X,Y,Z:TGLFloat):TArrVector;overload;&lt;br /&gt;
  function MakeVector(X,Y,Z,W:TGLFloat):TArrVector;overload;&lt;br /&gt;
  procedure Normalize(aVector:TArrVector;var RVec:TArrVector);overload;&lt;br /&gt;
  procedure Normalize(aVector:TGLVector;var RVec:TGLVector);overload;&lt;br /&gt;
  function GetIdentity(Matrix:TMatrix):TMatrix;overload;&lt;br /&gt;
  function GetIdentity(Matrix:TArrMatrix):TArrMatrix;overload;&lt;br /&gt;
  function MatrixTranspose(const M:TMatrix):TMatrix;register;&lt;br /&gt;
  function VectorRotateX(v:TArrVector;a:TGLFloat):TArrVector;overload;&lt;br /&gt;
  function VectorRotateY(v:TArrVector;a:TGLFloat):TArrVector;overload;&lt;br /&gt;
  function VectorRotateZ(v:TArrVector;a:TGLFloat):TArrVector;overload;&lt;br /&gt;
  function VectorRotateX(v:TGLVector;a:TGLFloat):TGLVector;overload;&lt;br /&gt;
  function VectorRotateY(v:TGLVector;a:TGLFloat):TGLVector;overload;&lt;br /&gt;
  function VectorRotateZ(v:TGLVector;a:TGLFloat):TGLVector;overload;&lt;br /&gt;
&lt;br /&gt;
  function GL2GKVector (V: TGLVector): TGKVector;&lt;br /&gt;
  function GK2GLVector (V: TGKVector): TGLVector;&lt;br /&gt;
  function GL2WinColor (GLcol: TGLcolor): TColor;&lt;br /&gt;
  function Win2GLColor (WinCol: Tcolor): TGLcolor;&lt;br /&gt;
  function CalcNormale (V1, V2, V3: TGLVector): TGLVector;&lt;br /&gt;
  function CrossProduct(V1, V2: TGLVector): TGLVector;&lt;br /&gt;
  function DotProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
  function LoadTexture(Filename: String; var Texture: GLuint): Boolean;&lt;br /&gt;
  function Magnitude(V1 : TGLVector) : GLdouble;&lt;br /&gt;
  function ScalarProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
  function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function SubtractVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;overload;&lt;br /&gt;
  function AddVector (Vec1, Vec2: TGLVector): TGLVector;overload;&lt;br /&gt;
  function AddVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;overload;&lt;br /&gt;
  function ForceForegroundWindow(hwnd: THandle): Boolean;&lt;br /&gt;
  procedure InitGLEnv (dc: HDC; rc: HGLRC; hndl: THandle);// pixelformat setzen&lt;br /&gt;
  procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);&lt;br /&gt;
  procedure InitVector (var V1: TGLVector; x, y, z: TGLdouble);overload;&lt;br /&gt;
  procedure InitVector (var V1: TGKVector; x, y, z: TGLdouble);overload;&lt;br /&gt;
  procedure InitVector (var V1: TArrVector; x, y, z: TGLdouble);overload;&lt;br /&gt;
  procedure InitScale (var S1: TScale; x, y, z: TGLdouble);&lt;br /&gt;
  procedure LoadBitmap(Filename: String;&lt;br /&gt;
                       out Width: Cardinal;&lt;br /&gt;
                       out Height: Cardinal;&lt;br /&gt;
                       out pData: Pointer);&lt;br /&gt;
  procedure GetRotation (V1, V2: TGLVector;&lt;br /&gt;
                         var Rotation: TRotation);&lt;br /&gt;
  function MakeTextureFromBitmap (Bitmap: string; var BitmapList: TTextureList): GLenum;&lt;br /&gt;
  procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);&lt;br /&gt;
  procedure DisableTexture;&lt;br /&gt;
  function TextToGLVector (VTxt: string): TGLVector;&lt;br /&gt;
  function TextToGKVector (VTxt: string): TGKVector;&lt;br /&gt;
  function GKVectorToText (V1: TGKVector): string;overload;&lt;br /&gt;
  function GKVectorToText (V1: TGKVector; digits: byte): string;overload;&lt;br /&gt;
  function GLVectorToText (V1: TGLVector): string;overload;&lt;br /&gt;
  function GLVectorToText (V1: TGLVector; digits: byte): string;overload;&lt;br /&gt;
  function MyCone (Start, Ende: TGLVector;&lt;br /&gt;
                   RadiusStart, RadiusEnde: TGLfloat;&lt;br /&gt;
                   Slices: Integer): boolean;&lt;br /&gt;
  function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  C_X = 0;&lt;br /&gt;
  C_Y = 1;&lt;br /&gt;
  C_Z = 2;&lt;br /&gt;
  C_W = 3;&lt;br /&gt;
  C_EPS:TGLFloat=0.01;&lt;br /&gt;
  C_DEGTORAD:TGLFloat=3.1412/180;&lt;br /&gt;
  C_RADTODEG:TGLFloat=180/3.1412;&lt;br /&gt;
  C_LAMBDA_INCREMENT:TGLFloat=0.01;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses Forms, KanalUtil, OGLinclude, Controls;&lt;br /&gt;
&lt;br /&gt;
function MyPower (Base: extended; Exp: integer): extended;&lt;br /&gt;
begin&lt;br /&gt;
  result := Base * Base;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);&lt;br /&gt;
begin&lt;br /&gt;
  ToVektor.X := FromVektor.X;&lt;br /&gt;
  ToVektor.Y := FromVektor.Y;&lt;br /&gt;
  ToVektor.Z := FromVektor.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixX (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den X-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[00];&lt;br /&gt;
  result.Y := matrix[01];&lt;br /&gt;
  result.Z := matrix[02];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixY (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Y-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[04];&lt;br /&gt;
  result.Y := matrix[05];&lt;br /&gt;
  result.Z := matrix[06];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixZ (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Z-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[08];&lt;br /&gt;
  result.Y := matrix[09];&lt;br /&gt;
  result.Z := matrix[10];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetMatrixPos (matrix: TArrMatrix): TGLvector;&lt;br /&gt;
// holt den Position-vektor aus matrix und gibt ihn zurück&lt;br /&gt;
begin&lt;br /&gt;
  result.X := matrix[12];&lt;br /&gt;
  result.Y := matrix[13];&lt;br /&gt;
  result.Z := matrix[14];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixX (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten X-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[00] := v.X;&lt;br /&gt;
  matrix[01] := v.Y;&lt;br /&gt;
  matrix[02] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixY (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Y-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[04] := v.X;&lt;br /&gt;
  matrix[05] := v.Y;&lt;br /&gt;
  matrix[06] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixZ (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Z-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[08] := v.X;&lt;br /&gt;
  matrix[09] := v.Y;&lt;br /&gt;
  matrix[10] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure SetMatrixPos (var matrix: TArrMatrix; v: TGLvector);&lt;br /&gt;
// setzt den durch v bestimmten Position-vektor in matrix&lt;br /&gt;
begin&lt;br /&gt;
  matrix[12] := v.X;&lt;br /&gt;
  matrix[13] := v.Y;&lt;br /&gt;
  matrix[14] := v.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;&lt;br /&gt;
// subtrahiert Vec2 von vec1 und gibt das ergebnis in vec3 zurück&lt;br /&gt;
var&lt;br /&gt;
  Vec3: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  Vec3 .X := Vec1.X - Vec2.X;&lt;br /&gt;
  Vec3 .Y := Vec1.Y - Vec2.Y;&lt;br /&gt;
  Vec3 .Z := Vec1.Z - Vec2.Z;&lt;br /&gt;
  result := Vec3;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SubtractVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;&lt;br /&gt;
// subtrahiert X, Y, Z von vec.x, vec.y, vec.z  und gibt das&lt;br /&gt;
// ergebnis zurück&lt;br /&gt;
begin&lt;br /&gt;
  Vec .X := Vec.X - X;&lt;br /&gt;
  Vec .Y := Vec.Y - Y;&lt;br /&gt;
  Vec .Z := Vec.Z - Z;&lt;br /&gt;
  result := Vec;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AddVector (Vec1, Vec2: TGLVector): TGLVector;&lt;br /&gt;
// addiert Vec2 auf vec1 und gibt das ergebnis in vec3 zurück&lt;br /&gt;
var&lt;br /&gt;
  Vec3: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  Vec3 .X := Vec1.X + Vec2.X;&lt;br /&gt;
  Vec3 .Y := Vec1.Y + Vec2.Y;&lt;br /&gt;
  Vec3 .Z := Vec1.Z + Vec2.Z;&lt;br /&gt;
  result := Vec3;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function AddVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;&lt;br /&gt;
// addiert X, Y, Z auf vec.x, vec.y, vec.z  und gibt das&lt;br /&gt;
// ergebnis zurück&lt;br /&gt;
begin&lt;br /&gt;
  Vec .X := Vec.X + X;&lt;br /&gt;
  Vec .Y := Vec.Y + Y;&lt;br /&gt;
  Vec .Z := Vec.Z + Z;&lt;br /&gt;
  result := Vec;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Magnitude(V1 : TGLVector) : GLdouble;&lt;br /&gt;
var&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
// gibt die länge des vektors zurück&lt;br /&gt;
  Ergebnis := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);&lt;br /&gt;
  try&lt;br /&gt;
    result := sqrt(Ergebnis);&lt;br /&gt;
  except&lt;br /&gt;
    result := 0;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function DotProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
var&lt;br /&gt;
  len1, len2: GLdouble;&lt;br /&gt;
  Ergebnis: GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  //len1 := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);&lt;br /&gt;
  //len2 := MyPower(V2.X,2)+MyPower(V2.Y,2)+MyPower(V2.Z,2);&lt;br /&gt;
  len1 := Magnitude (V1);&lt;br /&gt;
  len2 := Magnitude (V2);&lt;br /&gt;
  Ergebnis := ScalarProduct (V1, V2);&lt;br /&gt;
  Ergebnis := arccos (Ergebnis / (len1 * len2));&lt;br /&gt;
  result := radtodeg (Ergebnis) * 2.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function CrossProduct(V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  CrossVec: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
	//CrossVec.X := +((V1.Y*V2.Z) - (V1.Z*V2.Y));&lt;br /&gt;
	//CrossVec.Y := -((V1.X*V2.Z) - (V1.Z*V2.X));&lt;br /&gt;
	//CrossVec.Z := +((V1.X*V2.Y) - (V1.Y*V2.X));&lt;br /&gt;
	CrossVec.X := ((V1.Y*V2.Z) - (V1.Z*V2.Y));&lt;br /&gt;
	CrossVec.Y := ((V1.Z*V2.X) - (V1.X*V2.Z));&lt;br /&gt;
	CrossVec.Z := ((V1.X*V2.Y) - (V1.Y*V2.X));&lt;br /&gt;
  result := CrossVec;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
function CalcNormale (V1, V2, V3: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  Kreuz: TGLvector;&lt;br /&gt;
  V1V2, V1V3: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // gibt die normale von 3 vektoren zurück (die senkrechte auf die&lt;br /&gt;
  // durch die drei vektoren gebildete ebene)&lt;br /&gt;
  V1V2 := SubtractVector (V2, V1);&lt;br /&gt;
  V1V3 := SubtractVector (V3, V1);&lt;br /&gt;
&lt;br /&gt;
  Kreuz := CrossProduct (V1V2, V1V3);&lt;br /&gt;
&lt;br /&gt;
  Normalize (Kreuz, result);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TGLVector; x, y, z: TGLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1.x := x;&lt;br /&gt;
  V1.y := y;&lt;br /&gt;
  V1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TGKVector; x, y, z: TGLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1.x := x;&lt;br /&gt;
  V1.y := y;&lt;br /&gt;
  V1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitVector (var V1: TArrVector; x, y, z: TGLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  V1[C_X] := x;&lt;br /&gt;
  V1[C_Y] := y;&lt;br /&gt;
  V1[C_Z] := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure InitScale (var S1: TScale; x, y, z: TGLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  S1.x := x;&lt;br /&gt;
  S1.y := y;&lt;br /&gt;
  S1.z := z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Multiply (V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
// zwei vektoren miteinander multiplizieren&lt;br /&gt;
  ret.X := V1.X * V2.X;&lt;br /&gt;
  ret.Y := V1.Y * V2.Y;&lt;br /&gt;
  ret.Z := V1.Z * V2.Z;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Divide (V1, V2: TGLVector): TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
// zwei vektoren miteinander multiplizieren&lt;br /&gt;
  ret.X := V1.X / V2.X;&lt;br /&gt;
  ret.Y := V1.Y / V2.Y;&lt;br /&gt;
  ret.Z := V1.Z / V2.Z;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ScalarProduct (V1, V2: TGLVector): GLdouble;&lt;br /&gt;
begin&lt;br /&gt;
// die summe der potenzen der einzelnen achsen von zwei vektoren errechnen&lt;br /&gt;
  result := (V1.X*V2.X +&lt;br /&gt;
             V1.Y*V2.Y +&lt;br /&gt;
             V1.Z*V2.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LoadTexture(Filename: String; var Texture: GLuint): Boolean;&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_LoadUnable = 'Unable to load ';&lt;br /&gt;
  Res_LoadingTex = 'Loading Textures';&lt;br /&gt;
var&lt;br /&gt;
  pData: Pointer;&lt;br /&gt;
  Width: Cardinal;&lt;br /&gt;
  Height: Cardinal;&lt;br /&gt;
  newTexture: GLint;&lt;br /&gt;
begin&lt;br /&gt;
  pData :=nil;&lt;br /&gt;
  LoadBitmap(Filename, Width, Height, pData);&lt;br /&gt;
&lt;br /&gt;
  if (Assigned(pData)) then&lt;br /&gt;
    Result := True&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    Result := False;&lt;br /&gt;
    MessageBox(0, PChar(Res_LoadUnable + filename),&lt;br /&gt;
               pchar (Res_LoadingTex), MB_OK);&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  glGenTextures(1, @NewTexture);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, NewTexture);&lt;br /&gt;
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}&lt;br /&gt;
&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }&lt;br /&gt;
&lt;br /&gt;
  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);&lt;br /&gt;
&lt;br /&gt;
  Texture := newTexture;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure LoadBitmap(Filename: String;&lt;br /&gt;
                     out Width: Cardinal;&lt;br /&gt;
                     out Height: Cardinal;&lt;br /&gt;
                     out pData: Pointer);&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_ReadErr = 'Error reading palette';&lt;br /&gt;
  Res_OpenErr = 'Error opening: ';&lt;br /&gt;
  Res_BitmapDataErr = 'Error reading bitmap data';&lt;br /&gt;
  Res_BmpUnit = 'BMP Unit';&lt;br /&gt;
var&lt;br /&gt;
  FileHeader: BITMAPFILEHEADER;&lt;br /&gt;
  InfoHeader: BITMAPINFOHEADER;&lt;br /&gt;
  Palette: array of RGBQUAD;&lt;br /&gt;
  BitmapFile: THandle;&lt;br /&gt;
  BitmapLength: Cardinal;&lt;br /&gt;
  PaletteLength: Cardinal;&lt;br /&gt;
  ReadBytes: Cardinal;&lt;br /&gt;
  Front: ^Byte;&lt;br /&gt;
  Back: ^Byte;&lt;br /&gt;
  Temp: Byte;&lt;br /&gt;
  I : Cardinal;&lt;br /&gt;
begin&lt;br /&gt;
  BitmapFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);&lt;br /&gt;
  if (BitmapFile = INVALID_HANDLE_VALUE) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_OpenErr+Filename), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // Get header information&lt;br /&gt;
  ReadFile(BitmapFile, FileHeader, SizeOf(FileHeader), ReadBytes, nil);&lt;br /&gt;
  ReadFile(BitmapFile, InfoHeader, SizeOf(InfoHeader), ReadBytes, nil);&lt;br /&gt;
&lt;br /&gt;
  // Get palette&lt;br /&gt;
  PaletteLength := InfoHeader.biClrUsed;&lt;br /&gt;
  SetLength(Palette, PaletteLength);&lt;br /&gt;
  ReadFile(BitmapFile, Palette, PaletteLength, ReadBytes, nil);&lt;br /&gt;
  if (ReadBytes &amp;lt;&amp;gt; PaletteLength) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_ReadErr), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    CloseHandle(BitmapFile);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  Width := InfoHeader.biWidth;&lt;br /&gt;
  Height := InfoHeader.biHeight;&lt;br /&gt;
  BitmapLength := InfoHeader.biSizeImage;&lt;br /&gt;
  if BitmapLength = 0 then&lt;br /&gt;
    BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;&lt;br /&gt;
&lt;br /&gt;
  // Get the actual pixel data&lt;br /&gt;
  GetMem(pData, BitmapLength);&lt;br /&gt;
  ReadFile(BitmapFile, pData^, BitmapLength, ReadBytes, nil);&lt;br /&gt;
  if (ReadBytes &amp;lt;&amp;gt; BitmapLength) then begin&lt;br /&gt;
    MessageBox(0, PChar(Res_BitmapDataErr), PChar(Res_BmpUnit), MB_OK);&lt;br /&gt;
    CloseHandle(BitmapFile);&lt;br /&gt;
    Exit;&lt;br /&gt;
  end;&lt;br /&gt;
  CloseHandle(BitmapFile);&lt;br /&gt;
&lt;br /&gt;
  // Bitmaps are stored BGR and not RGB, so swap the R and B bytes.&lt;br /&gt;
  for I :=0 to Width * Height - 1 do&lt;br /&gt;
  begin&lt;br /&gt;
    Front := Pointer(Cardinal(pData) + I*3);&lt;br /&gt;
    Back := Pointer(Cardinal(pData) + I*3 + 2);&lt;br /&gt;
    Temp := Front^;&lt;br /&gt;
    Front^ := Back^;&lt;br /&gt;
    Back^ := Temp;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GK2GLVector (V: TGKVector): TGLVector;&lt;br /&gt;
// ändert Gauss-Krüger Koordinaten in OpenGL Koordinaten um&lt;br /&gt;
begin&lt;br /&gt;
  result.X := V.X;&lt;br /&gt;
  result.Y := V.Z;&lt;br /&gt;
  result.Z := V.Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GL2GKVector (V: TGLVector): TGKVector;&lt;br /&gt;
// ändert OpenGL Koordinaten in Gauss-Krüger Koordinaten um&lt;br /&gt;
begin&lt;br /&gt;
  result.X := V.X;&lt;br /&gt;
  result.Y := V.Z;&lt;br /&gt;
  result.Z := V.Y;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Win2GLColor (WinCol: TColor): TGLcolor;&lt;br /&gt;
begin&lt;br /&gt;
  result.Red := GetRValue (WinCol) / 255;&lt;br /&gt;
  result.Green := GetGValue (WinCol) / 255;&lt;br /&gt;
  result.Blue := GetBValue (WinCol) / 255;&lt;br /&gt;
  result.Alpha := 0.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GL2WinColor (GLcol: TGLcolor): TColor;&lt;br /&gt;
begin&lt;br /&gt;
  result := Rgb (StrToInt (FloatToStr (int (GLcol.Red * 255))),&lt;br /&gt;
                 StrToInt (FloatToStr (int (GLcol.Green * 255))),&lt;br /&gt;
                 StrToInt (FloatToStr (int (GLcol.Blue * 255))));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure GetRotation (V1, V2: TGLVector;&lt;br /&gt;
                       var Rotation: TRotation);&lt;br /&gt;
var&lt;br /&gt;
  tmpCyl, tmpZiel, nullVec: TGLVector;&lt;br /&gt;
  normale, ResultLen: TGLVector;&lt;br /&gt;
  VectorLength: GLfloat;&lt;br /&gt;
begin&lt;br /&gt;
  // temporäre vektoren initialisieren&lt;br /&gt;
  InitVector (nullVec, 0,0,0);&lt;br /&gt;
  InitVector (tmpCyl, 0,0,0);&lt;br /&gt;
&lt;br /&gt;
  // länge des zu drehenden objekts ermitteln&lt;br /&gt;
  ResultLen := SubtractVector (V2, V1);&lt;br /&gt;
  VectorLength := Magnitude (ResultLen);&lt;br /&gt;
&lt;br /&gt;
  // vektoren zur bildung der dreiecksfläche bilden.&lt;br /&gt;
  // die schenkel schneiden sich im nullpunkt&lt;br /&gt;
  // der Cylinder läuft immer entlang der Z-Achse&lt;br /&gt;
  tmpCyl.Z := VectorLength;&lt;br /&gt;
  tmpZiel := SubtractVector (V2, V1);&lt;br /&gt;
  tmpZiel.Z := tmpZiel.Z + VectorLength;&lt;br /&gt;
&lt;br /&gt;
  // senkrechte zu den beiden vektoren bilden&lt;br /&gt;
  // (um diese achse soll nachher gedreht werden)&lt;br /&gt;
  // drehachse für späteren gebrauch speichern&lt;br /&gt;
  normale := CalcNormale (tmpCyl, tmpZiel, nullVec);&lt;br /&gt;
&lt;br /&gt;
  // um &amp;quot;Angle&amp;quot; Grad soll nachher gedreht werden&lt;br /&gt;
  Rotation.Angle := DotProduct(tmpCyl, tmpZiel);&lt;br /&gt;
  Rotation.X     := normale.X;&lt;br /&gt;
  Rotation.Y     := normale.Y;&lt;br /&gt;
  Rotation.Z     := normale.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeTextureFromBitmap (Bitmap: string; var BitmapList: TTextureList): GLenum;&lt;br /&gt;
// die funktion lädt die in Bitmap übergebene Grafik und gibt die Textturnummer&lt;br /&gt;
// zurück. ist das bitmap schon im array BitmapList enthalten, wird die bereits&lt;br /&gt;
// vergeben nummer zurückgegeben.&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_TextureNotFound = 'Texturdatei nicht gefunden: ';&lt;br /&gt;
  Res_Error = 'Error';&lt;br /&gt;
var&lt;br /&gt;
  i, Laenge: integer;&lt;br /&gt;
begin&lt;br /&gt;
  result := 0;&lt;br /&gt;
  if length (trim (Bitmap)) = 0 then&lt;br /&gt;
    exit;&lt;br /&gt;
  Bitmap := uppercase (ExePath + trim (Bitmap));&lt;br /&gt;
  // suchen, ob die textur schon geladen wurde&lt;br /&gt;
  Laenge := length (BitmapList);&lt;br /&gt;
  if Laenge &amp;gt; 0 then&lt;br /&gt;
    for i := 0 to Laenge-1 do&lt;br /&gt;
    begin&lt;br /&gt;
      if (BitmapList[i].BitmapName = Bitmap) and&lt;br /&gt;
         (glIsTexture (BitmapList[i].TextureNum)) then&lt;br /&gt;
        result := BitmapList[i].TextureNum;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
  if result = 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    if not fileexists (Bitmap) then&lt;br /&gt;
    begin&lt;br /&gt;
      MessageBox (0, PChar (Res_TextureNotFound+Bitmap),&lt;br /&gt;
                  pchar (Res_Error), MB_OK or MB_ICONERROR);&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if (result = 0) then&lt;br /&gt;
  begin&lt;br /&gt;
    setlength (BitmapList, Laenge+1);&lt;br /&gt;
    BitmapList[Laenge].BitmapName := Bitmap;&lt;br /&gt;
    BitmapList[Laenge].TextureNum := 0;&lt;br /&gt;
    BitMapList[Laenge].theBmp := TglBmp.Create;&lt;br /&gt;
    if BitMapList[Laenge].theBmp.LoadImage (BitMap) then&lt;br /&gt;
    begin&lt;br /&gt;
      BitMapList[Laenge].theBmp.SetTextureWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);&lt;br /&gt;
      BitMapList[Laenge].theBmp.GenTexture (false, false);&lt;br /&gt;
      result := BitmapList[Laenge].theBmp.TextureID;&lt;br /&gt;
      BitmapList[Laenge].TextureNum := BitmapList[Laenge].theBmp.TextureID;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);&lt;br /&gt;
begin&lt;br /&gt;
  glEnable(GL_TEXTURE_2D);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, Texture);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);&lt;br /&gt;
  if TextureTiled then&lt;br /&gt;
  begin&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);&lt;br /&gt;
    glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure DisableTexture;&lt;br /&gt;
begin&lt;br /&gt;
  glDisable(GL_TEXTURE_2D);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TextToGLVector (VTxt: string): TGLVector;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  posi: integer;&lt;br /&gt;
  V1: TGLVector;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (V1,0,0,0);&lt;br /&gt;
  posi := pos (subdelim, VTxt);&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.X := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
    posi := pos (subdelim, VTxt);&lt;br /&gt;
  end;&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.Y := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
  end;&lt;br /&gt;
  if length (VTxt) &amp;gt; 0 then V1.Z := StrToFloat (VTxt);&lt;br /&gt;
&lt;br /&gt;
  result := V1;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TextToGKVector (VTxt: string): TGKVector;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  posi: integer;&lt;br /&gt;
  V1: TGKVector;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (V1,0,0,0);&lt;br /&gt;
  posi := pos (subdelim, VTxt);&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.X := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
    posi := pos (subdelim, VTxt);&lt;br /&gt;
  end;&lt;br /&gt;
  if posi &amp;gt; 0 then&lt;br /&gt;
  begin&lt;br /&gt;
    V1.Y := StrToFloat (copy (VTxt, 1, posi-1));&lt;br /&gt;
    VTxt := copy (VTxt, posi+1, length (VTxt));&lt;br /&gt;
  end;&lt;br /&gt;
  if length (VTxt) &amp;gt; 0 then V1.Z := StrToFloat (VTxt);&lt;br /&gt;
&lt;br /&gt;
  result := V1;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GKVectorToText (V1: TGKVector): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := FloatToStr (V1.X) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Y) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Z);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GKVectorToText (V1: TGKVector; digits: byte): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := Format('%*.*f', [digits+3, digits, V1.X]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits+3, digits, V1.Y]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits+3, digits, V1.Z]);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GLVectorToText (V1: TGLVector): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := FloatToStr (V1.X) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Y) + subdelim;&lt;br /&gt;
  VTxt := VTxt + FloatToStr (V1.Z);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GLVectorToText (V1: TGLVector; digits: byte): string;&lt;br /&gt;
const&lt;br /&gt;
  subdelim: char = '/';&lt;br /&gt;
var&lt;br /&gt;
  VTxt: string;&lt;br /&gt;
begin&lt;br /&gt;
  VTxt := Format('%*.*f', [digits+3, digits, V1.X]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits+3, digits, V1.Y]) + subdelim;&lt;br /&gt;
  VTxt := VTxt + Format('%*.*f', [digits+3, digits, V1.Z]);&lt;br /&gt;
  result := VTxt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MyCone (Start, Ende: TGLVector;&lt;br /&gt;
                 RadiusStart, RadiusEnde: TGLfloat;&lt;br /&gt;
                 Slices: Integer): boolean;&lt;br /&gt;
var&lt;br /&gt;
  Slice: Integer;&lt;br /&gt;
  Laenge, xdelta, zdelta: TGLfloat;&lt;br /&gt;
  V1, V2, V3, V4: TGLvector;&lt;br /&gt;
  A, B: Single;&lt;br /&gt;
  tmpVec: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  result := true;&lt;br /&gt;
  // laenge des kegels berechnen&lt;br /&gt;
  // hierbei wird davon ausgegangen, dass der kegel senkrecht steht&lt;br /&gt;
  // Laenge := Ende.y - Start.y;&lt;br /&gt;
  tmpVec := SubtractVector (Start, Ende);&lt;br /&gt;
  Laenge := Magnitude (tmpVec);&lt;br /&gt;
  // radiusdifferenz berechnen&lt;br /&gt;
  xdelta := Start.x - Ende.x;&lt;br /&gt;
  zdelta := Start.z - Ende.z;&lt;br /&gt;
  xdelta := -xdelta;&lt;br /&gt;
  //zdelta := zdelta;&lt;br /&gt;
  glBegin (GL_TRIANGLE_STRIP);&lt;br /&gt;
  // der kegel wird entlang der z-achse gezeichnet&lt;br /&gt;
  V1.z := 0;&lt;br /&gt;
  V2.z := 0;&lt;br /&gt;
  V3.z := Laenge;&lt;br /&gt;
  V4.z := Laenge;&lt;br /&gt;
  for Slice := 1 to Slices do begin&lt;br /&gt;
    A := 2 * PI * Slice / Slices;&lt;br /&gt;
    B := 2 * PI * (Slice+1) / Slices;&lt;br /&gt;
    V1.x := sin(A)*RadiusStart;&lt;br /&gt;
    V1.y := cos(A)*RadiusStart;&lt;br /&gt;
    V2.x := sin(B)*RadiusStart;&lt;br /&gt;
    V2.y := cos(B)*RadiusStart;&lt;br /&gt;
    // umsetzung von y nach z-achse&lt;br /&gt;
    V3.x := (sin(B)*RadiusEnde)+xdelta;&lt;br /&gt;
    V3.y := (cos(B)*RadiusEnde)+zdelta;&lt;br /&gt;
    V4.x := (sin(A)*RadiusEnde)+xdelta;&lt;br /&gt;
    V4.y := (cos(A)*RadiusEnde)+zdelta;&lt;br /&gt;
    //Normale := CalcNormale (V1, V3, V2);&lt;br /&gt;
    //glNormal3fv(@Normale);&lt;br /&gt;
    if Slice = 1 then&lt;br /&gt;
    begin&lt;br /&gt;
      glTexCoord2f(1,0); glVertex3fv(@V1);&lt;br /&gt;
      glTexCoord2f(1,1); glVertex3fv(@V4);&lt;br /&gt;
      glTexCoord2f(1-Slice/Slices,0); glVertex3fv(@V2);&lt;br /&gt;
      glTexCoord2f(1-Slice/Slices,1); glVertex3fv(@V3);&lt;br /&gt;
    end&lt;br /&gt;
    else&lt;br /&gt;
    begin&lt;br /&gt;
      glTexCoord2f(1-Slice/Slices,0); glVertex3fv(@V2);&lt;br /&gt;
      glTexCoord2f(1-Slice/Slices,1); glVertex3fv(@V3);&lt;br /&gt;
    end;&lt;br /&gt;
    // aktuellen und nächsten punkt des kreises (oben und unten)&lt;br /&gt;
    // nehmen und ein rechteck zeichnen. alle rechtecke zusammen sollten&lt;br /&gt;
    // einen geschlossenen kegel ergeben.&lt;br /&gt;
    //glBegin(GL_QUADS);&lt;br /&gt;
    //  glNormal3fv(@Normale);&lt;br /&gt;
    //  glTexCoord2f(0,0); glVertex3fv(@V2);&lt;br /&gt;
    //  glTexCoord2f(1,0); glVertex3fv(@V1);&lt;br /&gt;
    //  glTexCoord2f(1,1); glVertex3fv(@V4);&lt;br /&gt;
    //  glTexCoord2f(0,1); glVertex3fv(@V3);&lt;br /&gt;
    //glEnd;&lt;br /&gt;
  end;&lt;br /&gt;
  glEnd;  // (GL_TRIANGLE_STRIP)&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
{----------------------------- für TRUVCamera --------------------------------}&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
&lt;br /&gt;
function Multiply(M1, M2: TArrMatrix): TArrMatrix;&lt;br /&gt;
// multiplies two 4x4 matrices&lt;br /&gt;
var&lt;br /&gt;
  ret: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadMatrixf(@M1);&lt;br /&gt;
  glMultMatrixf(@M2);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX,@ret);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeVector(X,Y,Z:TGLFloat):TArrVector;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=x;&lt;br /&gt;
  result[1]:=y;&lt;br /&gt;
  result[2]:=z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MakeVector(X,Y,Z,W:TGLFloat):TArrVector;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=x;&lt;br /&gt;
  result[1]:=y;&lt;br /&gt;
  result[2]:=z;&lt;br /&gt;
  result[3]:=w;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Normalize(aVector:TArrVector;var RVec:TArrVector);&lt;br /&gt;
var&lt;br /&gt;
   d:double;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (RVec,1,1,1);&lt;br /&gt;
  d:=Sqrt(Sqr(aVector[C_X])+Sqr(aVector[C_Y])+Sqr(aVector[C_Z]));&lt;br /&gt;
  if d=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    //raise exception.Create('Zero length vector(Normalize 1)');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  RVec[C_X]:=aVector[C_X]/d;&lt;br /&gt;
  RVec[C_Y]:=aVector[C_Y]/d;&lt;br /&gt;
  RVec[C_Z]:=aVector[C_Z]/d;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Normalize(aVector:TGLVector; var RVec:TGLVector);&lt;br /&gt;
var&lt;br /&gt;
   d:double;&lt;br /&gt;
begin&lt;br /&gt;
  InitVector (RVec,1,1,1);&lt;br /&gt;
  d:=Sqrt(Sqr(aVector.X)+Sqr(aVector.Y)+Sqr(aVector.Z));&lt;br /&gt;
  if d=0 then&lt;br /&gt;
  begin&lt;br /&gt;
    //raise exception.Create('Zero length vector(Normalize 2)');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  RVec.X:=aVector.X/d;&lt;br /&gt;
  RVec.Y:=aVector.Y/d;&lt;br /&gt;
  RVec.Z:=aVector.Z/d;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetIdentity(Matrix:TMatrix):TMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result[0,0]:=1.0;result[0,1]:=0.0;result[0,2]:=0.0;result[0,3]:=0.0;&lt;br /&gt;
  result[1,0]:=0.0;result[1,1]:=1.0;result[1,2]:=0.0;result[1,3]:=0.0;&lt;br /&gt;
  result[2,0]:=0.0;result[2,1]:=0.0;result[2,2]:=1.0;result[2,3]:=0.0;&lt;br /&gt;
  result[3,0]:=0.0;result[3,1]:=0.0;result[3,2]:=0.0;result[3,3]:=1.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function GetIdentity(Matrix:TArrMatrix):TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result[0]:=1.0;result[1]:=0.0;result[2]:=0.0;result[3]:=0.0;&lt;br /&gt;
  result[4]:=0.0;result[5]:=1.0;result[6]:=0.0;result[7]:=0.0;&lt;br /&gt;
  result[8]:=0.0;result[9]:=0.0;result[10]:=1.0;result[11]:=0.0;&lt;br /&gt;
  result[12]:=0.0;result[13]:=0.0;result[14]:=0.0;result[15]:=1.0;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function MatrixTranspose(const M:TMatrix):TMatrix;register;&lt;br /&gt;
var&lt;br /&gt;
   i,j:integer;&lt;br /&gt;
begin&lt;br /&gt;
     for i:=0 to 3 do&lt;br /&gt;
         for j:=0 to 3 do&lt;br /&gt;
             result[i,j]:=M[j,i];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v:TArrVector;a:TGLFloat):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
   temp: TArrVector;&lt;br /&gt;
   sine,cosine:TGLFloat;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
     temp[C_X] := v[C_x];&lt;br /&gt;
     temp[C_Y] := (v[C_Y] * cosine) + (v[C_Z] * -sine);&lt;br /&gt;
     temp[C_Z] := (v[C_Y] * sine) + (v[C_Z] * cosine);&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v: TArrVector;a:TGLFloat):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
   temp: TArrVector;&lt;br /&gt;
   sine,cosine:TGLFloat;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
     temp[C_x] := (v[C_x] * cosine) + (v[C_z] * sine);&lt;br /&gt;
     temp[C_y] := v[C_y];&lt;br /&gt;
     temp[C_z] := (v[C_x] * -sine) + (v[C_z] * cosine);&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v: TArrVector; a: TGLFloat):TArrVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrVector;&lt;br /&gt;
   sine,cosine:TGLFloat;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
     temp[C_x] := (v[C_x] * cosine) + (v[C_y] * -sine);&lt;br /&gt;
     temp[C_y] := (v[C_x] * sin(a)) + (v[C_y] * cosine);&lt;br /&gt;
     temp[C_z] := v[C_z];&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateX(v:TGLVector;a:TGLFloat):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
   temp: TGLVector;&lt;br /&gt;
   sine,cosine:TGLFloat;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
     temp.X := v.x;&lt;br /&gt;
     temp.Y := (v.Y * cosine) + (v.Z * -sine);&lt;br /&gt;
     temp.Z := (v.Y * sine) + (v.Z * cosine);&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateY(v: TGLVector;a:TGLFloat):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
   temp: TGLVector;&lt;br /&gt;
   sine,cosine:TGLFloat;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
&lt;br /&gt;
     temp.x := (v.x * cosine) + (v.z * sine);&lt;br /&gt;
     temp.y := v.y;&lt;br /&gt;
     temp.z := (v.X * -sine) + (v.z * cosine);&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function VectorRotateZ(v: TGLVector; a: TGLFloat):TGLVector;&lt;br /&gt;
var&lt;br /&gt;
  temp: TGLVector;&lt;br /&gt;
   sine,cosine:TGLFloat;&lt;br /&gt;
begin&lt;br /&gt;
     a:=a*C_DEGTORAD;&lt;br /&gt;
     sine:=Sin(a);&lt;br /&gt;
     cosine:=Cos(a);&lt;br /&gt;
     temp.x := (v.x * cosine) + (v.y * -sine);&lt;br /&gt;
     temp.y := (v.x * sin(a)) + (v.y * cosine);&lt;br /&gt;
     temp.z := v.z;&lt;br /&gt;
     result := temp;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
{-------------------------------- allgemein ----------------------------------}&lt;br /&gt;
{-----------------------------------------------------------------------------}&lt;br /&gt;
&lt;br /&gt;
function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;&lt;br /&gt;
var&lt;br /&gt;
  t: TGLdouble;&lt;br /&gt;
  i, j, k, swap: integer;&lt;br /&gt;
  tmp: TMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := false;&lt;br /&gt;
  inverse := GetIdentity(inverse);&lt;br /&gt;
&lt;br /&gt;
  for i := 0 to 3 do&lt;br /&gt;
  begin&lt;br /&gt;
    for j := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      tmp[i][j] := src[i*4+j];&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  for i := 0 to 3 do&lt;br /&gt;
  begin&lt;br /&gt;
    // look for largest element in column.&lt;br /&gt;
    swap := i;&lt;br /&gt;
    for j := i+1 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      if abs(tmp[j][i]) &amp;gt; abs(tmp[i][i]) then&lt;br /&gt;
      begin&lt;br /&gt;
        swap := j;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    if not (swap = i) then&lt;br /&gt;
    begin&lt;br /&gt;
      // swap rows.&lt;br /&gt;
      for k := 0 to 3 do&lt;br /&gt;
      begin&lt;br /&gt;
        t := tmp[i][k];&lt;br /&gt;
        tmp[i][k] := tmp[swap][k];&lt;br /&gt;
        tmp[swap][k] := t;&lt;br /&gt;
&lt;br /&gt;
        t := inverse[i*4+k];&lt;br /&gt;
        inverse[i*4+k] := inverse[swap*4+k];&lt;br /&gt;
        inverse[swap*4+k] := t;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    if tmp[i][i] = 0 then&lt;br /&gt;
    begin&lt;br /&gt;
    { no non-zero pivot.  the matrix is singular, which&lt;br /&gt;
      shouldn't happen.  This means the user gave us a bad&lt;br /&gt;
      matrix. }&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    t := tmp[i][i];&lt;br /&gt;
    for k := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      tmp[i][k] := tmp[i][k]/t;&lt;br /&gt;
      inverse[i*4+k] := inverse[i*4+k]/t;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    for j := 0 to 3 do&lt;br /&gt;
    begin&lt;br /&gt;
      if not (j = i) then&lt;br /&gt;
      begin&lt;br /&gt;
        t := tmp[j][i];&lt;br /&gt;
        for k := 0 to 3 do&lt;br /&gt;
        begin&lt;br /&gt;
          tmp[j][k] := tmp[j][k]-tmp[i][k]*t;&lt;br /&gt;
          inverse[j*4+k] := inverse[j*4+k]-inverse[i*4+k]*t;&lt;br /&gt;
        end;&lt;br /&gt;
      end;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
  result := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Multiply (Color: TGLcolor; m: TGLdouble): TGLcolor;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLcolor;&lt;br /&gt;
begin&lt;br /&gt;
  ret.red := Color.red * m;&lt;br /&gt;
  ret.green := Color.green * m;&lt;br /&gt;
  ret.blue := Color.blue * m;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function Divide (V1: TGLvector; d: TGLdouble): TGLvector;&lt;br /&gt;
var&lt;br /&gt;
  ret: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  ret.x := V1.x / d;&lt;br /&gt;
  ret.y := V1.y / d;&lt;br /&gt;
  ret.z := V1.z / d;&lt;br /&gt;
  result := ret;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function ForceForegroundWindow(hwnd: THandle): Boolean;&lt;br /&gt;
{&lt;br /&gt;
  Manchmal funktioniert die SetForeGroundWindow Funktion&lt;br /&gt;
  nicht so, wie sie sollte; besonders unter Windows 98/2000,&lt;br /&gt;
  wenn ein anderes Fenster den Fokus hat.&lt;br /&gt;
  ForceForegroundWindow ist eine &amp;quot;verbesserte&amp;quot; Version von&lt;br /&gt;
  der SetForeGroundWindow API-Funktion, um ein Fenster in&lt;br /&gt;
  den Vordergrund zu bringen.&lt;br /&gt;
}&lt;br /&gt;
const&lt;br /&gt;
  SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;&lt;br /&gt;
  SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;&lt;br /&gt;
var&lt;br /&gt;
  ForegroundThreadID: DWORD;&lt;br /&gt;
  ThisThreadID: DWORD;&lt;br /&gt;
  timeout: DWORD;&lt;br /&gt;
begin&lt;br /&gt;
  if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);&lt;br /&gt;
&lt;br /&gt;
  if GetForegroundWindow = hwnd then Result := True&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    // Windows 98/2000 doesn't want to foreground a window when some other&lt;br /&gt;
    // window has keyboard focus&lt;br /&gt;
&lt;br /&gt;
    if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion &amp;gt; 4)) or&lt;br /&gt;
      ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and&lt;br /&gt;
      ((Win32MajorVersion &amp;gt; 4) or ((Win32MajorVersion = 4) and&lt;br /&gt;
      (Win32MinorVersion &amp;gt; 0)))) then&lt;br /&gt;
    begin&lt;br /&gt;
      // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm&lt;br /&gt;
      // Converted to Delphi by Ray Lischner&lt;br /&gt;
      // Published in The Delphi Magazine 55, page 16&lt;br /&gt;
&lt;br /&gt;
      Result := False;&lt;br /&gt;
      ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);&lt;br /&gt;
      ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);&lt;br /&gt;
      if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then&lt;br /&gt;
      begin&lt;br /&gt;
        BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
        SetForegroundWindow(hwnd);&lt;br /&gt;
        AttachThreadInput(ThisThreadID, ForegroundThreadID, False);&lt;br /&gt;
        Result := (GetForegroundWindow = hwnd);&lt;br /&gt;
      end;&lt;br /&gt;
      if not Result then&lt;br /&gt;
      begin&lt;br /&gt;
        // Code by Daniel P. Stasinski&lt;br /&gt;
        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);&lt;br /&gt;
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),&lt;br /&gt;
          SPIF_SENDCHANGE);&lt;br /&gt;
        BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
        SetForegroundWindow(hWnd);&lt;br /&gt;
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);&lt;br /&gt;
      end;&lt;br /&gt;
    end&lt;br /&gt;
    else&lt;br /&gt;
    begin&lt;br /&gt;
      BringWindowToTop(hwnd); // IE 5.5 related hack&lt;br /&gt;
      SetForegroundWindow(hwnd);&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    Result := (GetForegroundWindow = hwnd);&lt;br /&gt;
  end;&lt;br /&gt;
end; { ForceForegroundWindow }&lt;br /&gt;
&lt;br /&gt;
procedure InitGLEnv (dc: HDC; rc: HGLRC; hndl: THandle);&lt;br /&gt;
resourcestring&lt;br /&gt;
  Res_ChooseFailed = 'ChoosePixelFormat failed with ';&lt;br /&gt;
var&lt;br /&gt;
  pfd: TPixelFormatDescriptor;&lt;br /&gt;
  PixelFormat: TGLUint;&lt;br /&gt;
  pFlags: TPFDFlags;&lt;br /&gt;
  flags: word absolute pFlags;&lt;br /&gt;
  StencilBits,&lt;br /&gt;
  ColorBits,&lt;br /&gt;
  DepthBits: integer;&lt;br /&gt;
begin&lt;br /&gt;
  pflags := [];&lt;br /&gt;
  include (pflags, DoubleBuffer);&lt;br /&gt;
  include (pflags, Stereo);&lt;br /&gt;
  include (pflags, Draw_To_Window);&lt;br /&gt;
  include (pflags, Draw_To_Bitmap);&lt;br /&gt;
  include (pflags, Support_GDI);&lt;br /&gt;
  include (pflags, Support_OpenGL);&lt;br /&gt;
  include (pflags, Generic_Format);&lt;br /&gt;
  include (pflags, Need_Palette);&lt;br /&gt;
  include (pflags, Need_System_Palette);&lt;br /&gt;
  include (pflags, Swap_Exchange);&lt;br /&gt;
  include (pflags, Swap_Copy);&lt;br /&gt;
  include (pflags, Swap_Layer_Buffers);&lt;br /&gt;
  include (pflags, Generic_Accelerated);&lt;br /&gt;
&lt;br /&gt;
  ColorBits := 24;&lt;br /&gt;
  DepthBits := 32;&lt;br /&gt;
  StencilBits := 0;&lt;br /&gt;
&lt;br /&gt;
  with TWinControl(hndl) do&lt;br /&gt;
  begin&lt;br /&gt;
    fillchar(pfd,SizeOf(pfd),0);&lt;br /&gt;
    with pfd do&lt;br /&gt;
    begin&lt;br /&gt;
      nSize           := SizeOf(pfd);&lt;br /&gt;
      nVersion        := 1;&lt;br /&gt;
      dwFlags         := flags or&lt;br /&gt;
                         PFD_DRAW_TO_WINDOW&lt;br /&gt;
                         or PFD_SUPPORT_OPENGL&lt;br /&gt;
                         or PFD_DOUBLEBUFFER;&lt;br /&gt;
      iPixelType      := PFD_TYPE_RGBA;&lt;br /&gt;
      cColorBits      := ColorBits;&lt;br /&gt;
      cDepthBits      := DepthBits;&lt;br /&gt;
      cStencilBits    := StencilBits;&lt;br /&gt;
      iLayerType      := PFD_MAIN_PLANE;&lt;br /&gt;
      cRedBits        := 0;&lt;br /&gt;
      cRedShift       := 0;&lt;br /&gt;
      cGreenBits      := 0;&lt;br /&gt;
      cBlueBits       := 0;&lt;br /&gt;
      cBlueShift      := 0;&lt;br /&gt;
      cAlphaBits      := 0;&lt;br /&gt;
      cAlphaShift     := 0;&lt;br /&gt;
      cAccumBits      := 0;&lt;br /&gt;
      cAccumRedBits   := 0;&lt;br /&gt;
      cAccumGreenBits := 0;&lt;br /&gt;
      cAccumBlueBits  := 0;&lt;br /&gt;
      cAccumAlphaBits := 0;&lt;br /&gt;
      cAuxBuffers     := 0;&lt;br /&gt;
      bReserved       := 0;&lt;br /&gt;
      dwLayerMask     := 0;&lt;br /&gt;
      dwVisibleMask   := 0;&lt;br /&gt;
      dwDamageMask    := 0;&lt;br /&gt;
    end; {with}&lt;br /&gt;
&lt;br /&gt;
    PixelFormat := ChoosePixelFormat(dc, @pfd);&lt;br /&gt;
    if PixelFormat=0 then&lt;br /&gt;
      raise Exception.Create(Res_ChooseFailed+IntToStr(GetLastError));&lt;br /&gt;
&lt;br /&gt;
    //if not SetPixelFormat(FglDC, PixelFormat, @pfd) then&lt;br /&gt;
    //  raise Exception.Create('SetPixelFormat failed with '+&lt;br /&gt;
    //    IntToStr(GetLastError));&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Techniken_und_Algorithmen&amp;diff=16056</id>
		<title>Techniken und Algorithmen</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Techniken_und_Algorithmen&amp;diff=16056"/>
				<updated>2006-01-08T07:04:35Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was hier hinein gehört ==&lt;br /&gt;
Hier kommen, wie der Name vermuten lässt '''Erklärungen''' zu in der 3D-Echtzeitprogrammierung verwendeten '''Techniken''' hin. Z.B. verschiedene Schattentechniken, Bump-Mapping, etc.&lt;br /&gt;
&lt;br /&gt;
[[Hintergrundwissen]] gehört hier nicht rein, also solche Sachen wie ''&amp;quot;was ist ein Tiefenpuffer und wofür ist er gut&amp;quot;'' haben hier nichts zu suchen.&amp;lt;br&amp;gt;&lt;br /&gt;
Sollte es für eine Technik/Thematik (siehe unten für Beispiel) mehrere &amp;quot;Lösungswege&amp;quot; geben, sollte eine kleine Überschrift eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr einen Technik oder Alorithmus Artikel erstellt, so solltet ihr unter den Artikel ein&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[Kategorie:Technik_oder_Algorithmus]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
stellen. Damit wird der Artikel der  [[:Kategorie:Technik_oder_Algorithmus]] zugeordnet.&lt;br /&gt;
Falls dieser Artikel nicht nur erklärt was der Begriff bedeutet, sondern auch noch eine Anleitung ist, wie man die entsprechende Technik realisiert, so könnt ihr den Artikel auch noch der Kategorie [[:Kategorie:Anleitung|Anleitung]] zuweisen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Übersicht ==&lt;br /&gt;
=== Nützliche Helfer ===&lt;br /&gt;
In dieser Rubrik findet sich all das, was ein OpenGL/Graphikprogrammierer immer brauch oder schnell mal zur Hand haben muss:&lt;br /&gt;
* [[Framecounter]] (Wie schnell läuft mein Programm?)&lt;br /&gt;
* [[Texture Loader]] (Laden und verwalten von Texturen)&lt;br /&gt;
* [[Model Loader]] (Laden von Modellen die mit Programmen wie 3D Studio Max, Lightwave, Milkshape usw. erstellt wurden.)&lt;br /&gt;
* Eine Möglichkeit zum [[Text ausgeben]]&lt;br /&gt;
* [[Kamera]]&lt;br /&gt;
** [[Kamera (1)]] (Szene in drei Ebenen verschieben und drehen)&lt;br /&gt;
** [[Kamera (2)]] (Kamera Source, letztes Update 8.1.2006)&lt;br /&gt;
** [[Kamera (3)]] (Für die Kamera benötigte Utilities)&lt;br /&gt;
* [[Extensionausgabe]] (Ausgabe der unterstützten Extensions und sonstiger Eigenschaften)&lt;br /&gt;
&lt;br /&gt;
=== Licht und Schatten ===&lt;br /&gt;
Das Beleuchtungsmodell von OpenGL besitzt von Haus aus keine Möglichkeit zur Darstellung von Schatten (nicht zuletzt weil es dafür immernoch keine einheitliche Methode gibt), allerdings haben sich über die Jahre hinweg einige Techniken mehr oder weniger durchgesetzt :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Lightmaps]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Projezierte Shadowmaps]] / [[Projezierte Textur]]en&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Volumetrische Stencilschatten]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Silhouette]] {{icpIcon}}&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Statische Umgebungen ===&lt;br /&gt;
Besonders in Aussenszenen ist es oft nötig dem Betrachter den Eindruck zu vermitteln, er befinde sich in einer unendlich großen Umgebung. Da man dies jedoch schlecht über speziell dafür erstellte Geometrie lösen kann (weil das schlichtweg zu viel Aufwand und zu leistungsintensiv wäre), haben sich einige Techniken eingebürgert, mit denen man dem Betrachter eine solche unendliche Landschaft mit  wenig Geometrie und einigen Tricks vorgaugeln kann :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skyboxen]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skydome]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skysphere]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Dynamische Effekte ===&lt;br /&gt;
Das Auge ißt bekanntlich mit. Auch bei 3D Anwendungen, vor allem in der Unterhaltungsindustrie, spielen gigantische Effekte, die dem User ein &amp;quot;Ohhh&amp;quot; und &amp;quot;Ahhh&amp;quot; und vor allem &amp;quot;Wow!&amp;quot; entlocken eine immer größere Rolle. Wie man solche Effekte am besten implementiert finden Sie in den Artikeln dieses Abschnitts.&amp;lt;br&amp;gt;&lt;br /&gt;
(Befassen Sie sich zuerst mit den Grundlagen von [[Partikelsysteme|Partikelsystemen]].)&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Explosionen]] (Allseits gern gesehen. Außer in direkter Nachbarschaft)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Lichtsäulen]] (Bekannt für die magischen Momente in diversen Rollenspielen.) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Partikelsysteme]] (Grundlage für viele Effekte) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Natürliche Phänomene ===&lt;br /&gt;
Ziel vieler Echtzeit 3D-Anwendung (auch wenn genau der gegenteilige Trend manchmal interessant sein dürfte) ist eine zumindest optische Annäherung an die Realität, also Szenen möglichst &amp;quot;naturgetreu&amp;quot; (auch urbane Szenen können &amp;quot;naturgetreu&amp;quot; sein, auch wenn diese wenig natürlich sind) darzustellen. Dazu gehören auch natürliche Phänomene, wie z.B. realistisch spiegelndes Wasser, Wetterbedingungen (Regen, Schnee, Nebel), Feuer, etc. Oft gibt es für ein natürliches Phänomen recht fortgeschrittene Umsetzungsmöglichkeiten, manchmal liegt die Lösung aber auch recht nahe :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Bäume|Bäume]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Blitz]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Feuer]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Himmel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Nebel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Staub]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wasser]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wettereffekt]]e (Regen, Schnee)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wolken]] (als Ergänzung zu den statischen Umgebungen)&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raumunterteilungstechniken ===&lt;br /&gt;
Moderne 3D-Anwendungen müssen immer größere und komplexere 3D-Umgebungen darstellen, wobei oft jedoch große Teile eben dieser nicht sichtbar sind, aber ohne entsprechende Optimierungen trotzdem über den Datenbus geschoben (und von der Grafikkarte geclippt) werden müssen. Deshalb finden diverse Raumunterteilungstechniken (die u.a. aus anderen Bereichen stammen) in modernen 3D-Programmen Anwendung :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[BSP-Bäume]] (Binary Space Partitioning = Binäre Raumunterteilung)&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;[[Octree]]s (Dreidimensionale Erweiterung eines Quadtrees)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Portal]]e (Logische Sichtbegrenzung an Durchgängen)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[PVS]] (Potentially Visible Sets = Mögliche sichtbare Sets)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Terrain Darstellung ===&lt;br /&gt;
In vielen 3D Anwendungen, vom Flugsimulator über Egoshooter bis zum Strategiespiel, muss die Umgebung visualisiert werden. Welche Techniken bei der Speicherung (siehe auch '''Raumunterteilungstechniken'''), Bildaufbau und Texturierung zum Einsatz kommen, findet ihr hier:&amp;lt;br&amp;gt;&lt;br /&gt;
:'''[[LOD|Level of Detail]] Algorithmen für Landschaften'''&lt;br /&gt;
&lt;br /&gt;
*[[VDPM]] ('''V'''iew-'''D'''ependent '''P'''rogressive '''M'''eshes)&lt;br /&gt;
*[[ROAM]] ('''R'''eal-time '''O'''ptimally '''A'''dapting '''M'''eshes)&lt;br /&gt;
*[[Geometrical Mipmapping]]&lt;br /&gt;
*[[VIPMs]] ('''V'''iew '''I'''ndependent '''P'''rogressive '''M'''eshe'''s''')&lt;br /&gt;
&lt;br /&gt;
:'''Texturierung'''&lt;br /&gt;
&lt;br /&gt;
*[[Texture Splatting]] (Kombination von Texturen mittels [[Blenden|Blending]] und [[Multitexturing]])&lt;br /&gt;
*[[Texture Backing]] (Dynamisches erstellen von Texturen)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prozeduale Grafiken ===&lt;br /&gt;
Prozeduale Grafiken werden häufig verwendet um&lt;br /&gt;
*eine vielfältige Umgebung zu gewährleisten&lt;br /&gt;
*Speicherplatz auf der Festplatte zu sparen&lt;br /&gt;
*den Grafikern die Arbeit zu erleichtern (und teilweise sogar erst zu ermöglichen)&lt;br /&gt;
Die Algorithmen und Möglichkeiten die sich dabei bieten sind hier aufgelistet:&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Perlin Noise]] (Algorithmus für Texturen, Landschaft und vieles mehr)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[L-Systems]] (aus wenig mach viel, Landschaftsgenerierung, Baumgenerierung, ...)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Midpoint Displacement]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Fault Formation]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Landschaft]] (Spezielle Hinweise und Techniken zur Landschaftsgenerierung&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Bäume]] (Techniken und Algorithmen speziell zur Baumgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Texturen]] (Spezielle Hinweise zu Wasser, Lava und ähnliches)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pathfinding ===&lt;br /&gt;
Pathfinding ist einer der grundlegenden Bereiche der Künstlichen Intelligenz, und aus diesem Grund für Spiele mit Computergegnern meistens unumgänglich.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Tiefensuche]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Breitensuche]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[A-Stern]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Dijkstra]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Floyd Warshall]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Navigation Meshes]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Pathfinding-Level of Detail]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sonstiges ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Screenshot]]s von OpenGL Ausgaben&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Interpolation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Bilder als Ressourcen]] speichern und laden&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Externe Links ==&lt;br /&gt;
Weitere Links zum Thema &amp;quot;Effekte unter OpenGL&amp;quot; findet ihr in der [[Link]]-Sammlung unter [[Link#Effekte_und_Techniken_mit_OpenGL|Effekte und Techniken mit OpenGL]].&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Techniken_und_Algorithmen&amp;diff=16055</id>
		<title>Techniken und Algorithmen</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Techniken_und_Algorithmen&amp;diff=16055"/>
				<updated>2006-01-08T07:04:04Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was hier hinein gehört ==&lt;br /&gt;
Hier kommen, wie der Name vermuten lässt '''Erklärungen''' zu in der 3D-Echtzeitprogrammierung verwendeten '''Techniken''' hin. Z.B. verschiedene Schattentechniken, Bump-Mapping, etc.&lt;br /&gt;
&lt;br /&gt;
[[Hintergrundwissen]] gehört hier nicht rein, also solche Sachen wie ''&amp;quot;was ist ein Tiefenpuffer und wofür ist er gut&amp;quot;'' haben hier nichts zu suchen.&amp;lt;br&amp;gt;&lt;br /&gt;
Sollte es für eine Technik/Thematik (siehe unten für Beispiel) mehrere &amp;quot;Lösungswege&amp;quot; geben, sollte eine kleine Überschrift eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr einen Technik oder Alorithmus Artikel erstellt, so solltet ihr unter den Artikel ein&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[Kategorie:Technik_oder_Algorithmus]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
stellen. Damit wird der Artikel der  [[:Kategorie:Technik_oder_Algorithmus]] zugeordnet.&lt;br /&gt;
Falls dieser Artikel nicht nur erklärt was der Begriff bedeutet, sondern auch noch eine Anleitung ist, wie man die entsprechende Technik realisiert, so könnt ihr den Artikel auch noch der Kategorie [[:Kategorie:Anleitung|Anleitung]] zuweisen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Übersicht ==&lt;br /&gt;
=== Nützliche Helfer ===&lt;br /&gt;
In dieser Rubrik findet sich all das, was ein OpenGL/Graphikprogrammierer immer brauch oder schnell mal zur Hand haben muss:&lt;br /&gt;
* [[Framecounter]] (Wie schnell läuft mein Programm?)&lt;br /&gt;
* [[Texture Loader]] (Laden und verwalten von Texturen)&lt;br /&gt;
* [[Model Loader]] (Laden von Modellen die mit Programmen wie 3D Studio Max, Lightwave, Milkshape usw. erstellt wurden.)&lt;br /&gt;
* Eine Möglichkeit zum [[Text ausgeben]]&lt;br /&gt;
* [[Kamera]]&lt;br /&gt;
** [[Kamera (1)]] (Szene in drei Ebenen verschieben und drehen)&lt;br /&gt;
** [[Kamera (2)]] (Kamera Source, letztes Update 8.1.2005)&lt;br /&gt;
** [[Kamera (3)]] (Für die Kamera benötigte Utilities)&lt;br /&gt;
* [[Extensionausgabe]] (Ausgabe der unterstützten Extensions und sonstiger Eigenschaften)&lt;br /&gt;
&lt;br /&gt;
=== Licht und Schatten ===&lt;br /&gt;
Das Beleuchtungsmodell von OpenGL besitzt von Haus aus keine Möglichkeit zur Darstellung von Schatten (nicht zuletzt weil es dafür immernoch keine einheitliche Methode gibt), allerdings haben sich über die Jahre hinweg einige Techniken mehr oder weniger durchgesetzt :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Lightmaps]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Projezierte Shadowmaps]] / [[Projezierte Textur]]en&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Volumetrische Stencilschatten]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Silhouette]] {{icpIcon}}&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Statische Umgebungen ===&lt;br /&gt;
Besonders in Aussenszenen ist es oft nötig dem Betrachter den Eindruck zu vermitteln, er befinde sich in einer unendlich großen Umgebung. Da man dies jedoch schlecht über speziell dafür erstellte Geometrie lösen kann (weil das schlichtweg zu viel Aufwand und zu leistungsintensiv wäre), haben sich einige Techniken eingebürgert, mit denen man dem Betrachter eine solche unendliche Landschaft mit  wenig Geometrie und einigen Tricks vorgaugeln kann :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skyboxen]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skydome]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Skysphere]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Dynamische Effekte ===&lt;br /&gt;
Das Auge ißt bekanntlich mit. Auch bei 3D Anwendungen, vor allem in der Unterhaltungsindustrie, spielen gigantische Effekte, die dem User ein &amp;quot;Ohhh&amp;quot; und &amp;quot;Ahhh&amp;quot; und vor allem &amp;quot;Wow!&amp;quot; entlocken eine immer größere Rolle. Wie man solche Effekte am besten implementiert finden Sie in den Artikeln dieses Abschnitts.&amp;lt;br&amp;gt;&lt;br /&gt;
(Befassen Sie sich zuerst mit den Grundlagen von [[Partikelsysteme|Partikelsystemen]].)&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Explosionen]] (Allseits gern gesehen. Außer in direkter Nachbarschaft)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Lichtsäulen]] (Bekannt für die magischen Momente in diversen Rollenspielen.) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Partikelsysteme]] (Grundlage für viele Effekte) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Natürliche Phänomene ===&lt;br /&gt;
Ziel vieler Echtzeit 3D-Anwendung (auch wenn genau der gegenteilige Trend manchmal interessant sein dürfte) ist eine zumindest optische Annäherung an die Realität, also Szenen möglichst &amp;quot;naturgetreu&amp;quot; (auch urbane Szenen können &amp;quot;naturgetreu&amp;quot; sein, auch wenn diese wenig natürlich sind) darzustellen. Dazu gehören auch natürliche Phänomene, wie z.B. realistisch spiegelndes Wasser, Wetterbedingungen (Regen, Schnee, Nebel), Feuer, etc. Oft gibt es für ein natürliches Phänomen recht fortgeschrittene Umsetzungsmöglichkeiten, manchmal liegt die Lösung aber auch recht nahe :&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Bäume|Bäume]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Blitz]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Feuer]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Himmel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Nebel]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Staub]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wasser]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wettereffekt]]e (Regen, Schnee)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Wolken]] (als Ergänzung zu den statischen Umgebungen)&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Raumunterteilungstechniken ===&lt;br /&gt;
Moderne 3D-Anwendungen müssen immer größere und komplexere 3D-Umgebungen darstellen, wobei oft jedoch große Teile eben dieser nicht sichtbar sind, aber ohne entsprechende Optimierungen trotzdem über den Datenbus geschoben (und von der Grafikkarte geclippt) werden müssen. Deshalb finden diverse Raumunterteilungstechniken (die u.a. aus anderen Bereichen stammen) in modernen 3D-Programmen Anwendung :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[BSP-Bäume]] (Binary Space Partitioning = Binäre Raumunterteilung)&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;[[Octree]]s (Dreidimensionale Erweiterung eines Quadtrees)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Portal]]e (Logische Sichtbegrenzung an Durchgängen)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[PVS]] (Potentially Visible Sets = Mögliche sichtbare Sets)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Terrain Darstellung ===&lt;br /&gt;
In vielen 3D Anwendungen, vom Flugsimulator über Egoshooter bis zum Strategiespiel, muss die Umgebung visualisiert werden. Welche Techniken bei der Speicherung (siehe auch '''Raumunterteilungstechniken'''), Bildaufbau und Texturierung zum Einsatz kommen, findet ihr hier:&amp;lt;br&amp;gt;&lt;br /&gt;
:'''[[LOD|Level of Detail]] Algorithmen für Landschaften'''&lt;br /&gt;
&lt;br /&gt;
*[[VDPM]] ('''V'''iew-'''D'''ependent '''P'''rogressive '''M'''eshes)&lt;br /&gt;
*[[ROAM]] ('''R'''eal-time '''O'''ptimally '''A'''dapting '''M'''eshes)&lt;br /&gt;
*[[Geometrical Mipmapping]]&lt;br /&gt;
*[[VIPMs]] ('''V'''iew '''I'''ndependent '''P'''rogressive '''M'''eshe'''s''')&lt;br /&gt;
&lt;br /&gt;
:'''Texturierung'''&lt;br /&gt;
&lt;br /&gt;
*[[Texture Splatting]] (Kombination von Texturen mittels [[Blenden|Blending]] und [[Multitexturing]])&lt;br /&gt;
*[[Texture Backing]] (Dynamisches erstellen von Texturen)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prozeduale Grafiken ===&lt;br /&gt;
Prozeduale Grafiken werden häufig verwendet um&lt;br /&gt;
*eine vielfältige Umgebung zu gewährleisten&lt;br /&gt;
*Speicherplatz auf der Festplatte zu sparen&lt;br /&gt;
*den Grafikern die Arbeit zu erleichtern (und teilweise sogar erst zu ermöglichen)&lt;br /&gt;
Die Algorithmen und Möglichkeiten die sich dabei bieten sind hier aufgelistet:&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Perlin Noise]] (Algorithmus für Texturen, Landschaft und vieles mehr)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[L-Systems]] (aus wenig mach viel, Landschaftsgenerierung, Baumgenerierung, ...)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Midpoint Displacement]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Fault Formation]] (primär zur Landschaftsgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Landschaft]] (Spezielle Hinweise und Techniken zur Landschaftsgenerierung&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Bäume]] (Techniken und Algorithmen speziell zur Baumgenerierung)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Prozeduale Texturen]] (Spezielle Hinweise zu Wasser, Lava und ähnliches)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pathfinding ===&lt;br /&gt;
Pathfinding ist einer der grundlegenden Bereiche der Künstlichen Intelligenz, und aus diesem Grund für Spiele mit Computergegnern meistens unumgänglich.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Tiefensuche]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Breitensuche]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[A-Stern]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Dijkstra]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Floyd Warshall]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Navigation Meshes]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Pathfinding-Level of Detail]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sonstiges ===&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Screenshot]]s von OpenGL Ausgaben&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Interpolation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Bilder als Ressourcen]] speichern und laden&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Externe Links ==&lt;br /&gt;
Weitere Links zum Thema &amp;quot;Effekte unter OpenGL&amp;quot; findet ihr in der [[Link]]-Sammlung unter [[Link#Effekte_und_Techniken_mit_OpenGL|Effekte und Techniken mit OpenGL]].&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=16054</id>
		<title>Kamera (2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=16054"/>
				<updated>2006-01-08T07:01:19Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Wie ich selber immer wieder merken muss, ist eine Software anscheinend&lt;br /&gt;
// nie fertig. Immer moechte man etwas verbessern oder neue Features&lt;br /&gt;
// einbauen.&lt;br /&gt;
// Sollte also jemand Änderungs- oder Verbesserungsvorschläge haben oder&lt;br /&gt;
// neue Ideen einbringen wollen, oder sollten Verstaendnisfragen bestehen,&lt;br /&gt;
// so mailt bitte an&lt;br /&gt;
//&lt;br /&gt;
// Andree.Heyroth@t-online.de&lt;br /&gt;
//&lt;br /&gt;
// Danke.&lt;br /&gt;
//&lt;br /&gt;
// Updates:&lt;br /&gt;
//&lt;br /&gt;
// 06.11.2005&lt;br /&gt;
// Die Deklaration der DESTROY Methode war falsch. Das fuehrte dazu,&lt;br /&gt;
// dass in der Methode CREATE erzeugte Objekte nicht richtig frei-&lt;br /&gt;
// gegeben wurden und es zu EAccessViolations kam. Die Methode wird&lt;br /&gt;
// jetzt in der PUBLIC Section mit der Direktive OVERRIDE aufgerufen.&lt;br /&gt;
//&lt;br /&gt;
// 11.11.2005&lt;br /&gt;
// Die Positionierung funktioniert jetzt.&lt;br /&gt;
// Wegen eines Verstaendnisproblems wurden die Positionen immer auf den&lt;br /&gt;
// Kamerapunkt aufaddiert. Das bedeutete, dass die Positionierung aus&lt;br /&gt;
// dem Ruder lief wenn sie nicht im Nullpunkt stattfand. Je groesser die&lt;br /&gt;
// gewuenschte Position war um so groesser war die Abweichung von der&lt;br /&gt;
// Darstellung.&lt;br /&gt;
// Ich habe nicht bedacht, dass bei einer &amp;quot;Kamera&amp;quot;-bewegung und -drehung&lt;br /&gt;
// ja eigentlich die Szene bewegt und gedreht wird. Deswegen wurden nach&lt;br /&gt;
// einer Positionierung die folgenden Projektionen immer basierend auf der&lt;br /&gt;
// danach gueltigen Kameraposition gemacht.&lt;br /&gt;
// Jetzt wird die Position so gesetzt, dass die gewuenschte Kameraposition&lt;br /&gt;
// immer vor dem Betrachter steht.&lt;br /&gt;
//&lt;br /&gt;
// 23.11.2005&lt;br /&gt;
// Neues Flag (FFixedAxis) zur Entscheidung zwischen angepasster und realer&lt;br /&gt;
// Drehung. Dadurch wird das Bewegungsmodell angepasst. Siehe Methode Offset,&lt;br /&gt;
// bzw. UpdateMatrixOffset.&lt;br /&gt;
//&lt;br /&gt;
// 10.12.2005&lt;br /&gt;
// Property PointOfRotation ist jetzt nicht mehr ReadOnly.&lt;br /&gt;
// Der Blickpunkt bzw. Rotationspunkt kann jetzt direkt verändert werden.&lt;br /&gt;
// So kann eine neue Blickrichtung angenommen werden ohne vorher die Kamera-&lt;br /&gt;
// eigenschaften zu sichern und nach einem PositionCamera wieder zu setzen.&lt;br /&gt;
//&lt;br /&gt;
// 19.12.2005&lt;br /&gt;
// Neue Methode PositionCross.&lt;br /&gt;
// Die Methode PositionCross schiebt das Fadenkreuz in den angegebenen Punkt&lt;br /&gt;
// ohne die Lage der Szene zu verändern. Diese Funktionalitaet ist anders als&lt;br /&gt;
// ein neues Setzen der Property FPointOfRotation weil dabei die Szene in das&lt;br /&gt;
// Koordinatenkreuz geschoben wird.&lt;br /&gt;
//&lt;br /&gt;
unit Camera;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
  Uses DglOpenGL, OpenGLUtil, Windows, Classes;&lt;br /&gt;
&lt;br /&gt;
  type&lt;br /&gt;
  TCameraMatrix=Class&lt;br /&gt;
    StackMatrix: array [0..9] of TArrMatrix;&lt;br /&gt;
    StackCtr: integer;&lt;br /&gt;
    Matrix: TArrMatrix;&lt;br /&gt;
    InverseMatrix: TArrMatrix;&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    //destructor destroy;&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Push;&lt;br /&gt;
    procedure Pop;&lt;br /&gt;
    procedure Load(M: TArrMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TCamera=Class&lt;br /&gt;
    Enabled: boolean;&lt;br /&gt;
    function UpVector: TGLvector;&lt;br /&gt;
    procedure RestorePosition(pos: integer);&lt;br /&gt;
    procedure SavePosition(pos: integer);&lt;br /&gt;
    function GiveStoredPosition(pos: integer): TGLvector;&lt;br /&gt;
    procedure RotateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure TranslateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure CameraHome;&lt;br /&gt;
    procedure PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector);&lt;br /&gt;
    procedure Adjust;&lt;br /&gt;
    procedure Apply;&lt;br /&gt;
    procedure ApplyForTerrain;&lt;br /&gt;
  private&lt;br /&gt;
    FPosition: TGLvector;&lt;br /&gt;
    FViewDirection: TGLvector;&lt;br /&gt;
    FPointOfRotation: TGLvector;&lt;br /&gt;
    HomeMatrix: TCameraMatrix;&lt;br /&gt;
    CameraMatrix: TCameraMatrix;&lt;br /&gt;
    Initiated: boolean;&lt;br /&gt;
    PosArray: array [0..9] of TCameraMatrix;&lt;br /&gt;
    RotArray: array [0..9] of TGLvector;&lt;br /&gt;
    FFixedAxis: boolean;&lt;br /&gt;
    procedure Debug (Text: string);&lt;br /&gt;
    function UpdateMatrixOffset(newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
    function GetViewDirection: TGLvector;&lt;br /&gt;
    procedure SetViewDirection (View: TGLvector);&lt;br /&gt;
    procedure Initiate;&lt;br /&gt;
    function GetPosition: TGLvector;&lt;br /&gt;
    procedure SetPosition (Pos: TGLvector);&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Offset(x, y, z: TGLfloat);&lt;br /&gt;
    procedure RotateRoundAxis(rx, ry, rz: TGLfloat);&lt;br /&gt;
    procedure SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    destructor Destroy;override;&lt;br /&gt;
    function InverseMatrix: TArrMatrix;&lt;br /&gt;
    procedure PositionCross(CrossVec: TGLvector);&lt;br /&gt;
  published&lt;br /&gt;
    property PointOfRotation: TGLvector read FPointOfRotation write SetPointOfRotation;&lt;br /&gt;
    property Position: TGLvector read GetPosition write SetPosition;&lt;br /&gt;
    property ViewDirection: TGLvector read GetViewDirection write SetViewDirection;&lt;br /&gt;
    property FixedAxis: boolean read FFixedAxis write FFixedAxis;&lt;br /&gt;
  end;&lt;br /&gt;
  TPCamera=^TCamera;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  FDebugFile: Textfile;&lt;br /&gt;
  FDebugFileName: string;&lt;br /&gt;
  FDebugOn: boolean;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses SysUtils, KanalUtil;&lt;br /&gt;
&lt;br /&gt;
constructor TCameraMatrix.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
  StackCtr := 0;&lt;br /&gt;
end;&lt;br /&gt;
{&lt;br /&gt;
destructor TCameraMatrix.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Push;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; -1) and (StackCtr &amp;lt; 10) then&lt;br /&gt;
  begin&lt;br /&gt;
    StackMatrix[StackCtr] := Matrix;&lt;br /&gt;
    inc (StackCtr);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Pop;&lt;br /&gt;
begin&lt;br /&gt;
  if (StackCtr &amp;gt; 0) and (StackCtr &amp;lt; 11) then&lt;br /&gt;
  begin&lt;br /&gt;
    dec (StackCtr);&lt;br /&gt;
    Load (StackMatrix[StackCtr]);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Identity;&lt;br /&gt;
// GetIdentity: aus OpenGL.pas&lt;br /&gt;
// initialisiert die CameraMatrix mit der Identitaetsmatrix&lt;br /&gt;
begin&lt;br /&gt;
  Matrix := GetIdentity(Matrix);&lt;br /&gt;
  InverseMatrix := GetIdentity(InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Load(M: TArrMatrix);&lt;br /&gt;
// die Matrix mit den Werten einer beliebigen anderen matrix fuellen&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i:=0 to 15 do&lt;br /&gt;
    Matrix[i]:=M[i];&lt;br /&gt;
  // die invertierte Matrix kann benutzt werden um Objkekte z.B.&lt;br /&gt;
  // immer zum Benutzer auszurichten&lt;br /&gt;
  InvertMatrix (M, InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
constructor TCamera.Create;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
&lt;br /&gt;
  // Initiated wird gebraucht um einmal alle Positionsspeicher&lt;br /&gt;
  // mit der Anfangsposition zu belegen&lt;br /&gt;
  Initiated := false;&lt;br /&gt;
&lt;br /&gt;
  // Kameramatrix anlegen&lt;br /&gt;
  CameraMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Matrix der letzten Position von PositionCamera anlegen&lt;br /&gt;
  HomeMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Positionsspeicher anlegen&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    PosArray[i] := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // standardmaessig immer entlang der bildschirmachsen verschieben&lt;br /&gt;
  FFixedAxis := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCamera.Destroy;&lt;br /&gt;
// alle in create belegten Resourcen wieder freigeben&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FreeAndNil (CameraMatrix);&lt;br /&gt;
  FreeAndNil (HomeMatrix);&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    FreeAndNil (PosArray[i]);&lt;br /&gt;
&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat);&lt;br /&gt;
// hier drehen wir jetzt um die einzelnen Achsen.&lt;br /&gt;
// die Parameter geben die &amp;quot;Drehgeschwindigkeit&amp;quot; vor.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  tempX, tempY, tempZ: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Position und Lage der Kamera herstellen&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
&lt;br /&gt;
  if FFixedAxis then&lt;br /&gt;
  begin&lt;br /&gt;
    // über die bildschirmachsen drehen&lt;br /&gt;
    tempX := GetMatrixX (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempY := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
    tempZ := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotatef(rx,tempX.X,tempX.Y,tempX.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotatef(ry,tempY.X,tempY.Y,tempY.Z);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotatef(rz,tempZ.X,tempZ.Y,tempZ.Z);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    // über die achsen des koordinatenkreuzes drehen&lt;br /&gt;
    // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
    if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotatef(rx,1,0,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
    if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotatef(ry,0,1,0);&lt;br /&gt;
&lt;br /&gt;
    // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
    if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
      glRotatef(rz,0,0,1);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  // die neu erzeugte Matrix auslesen&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  // und in die Kameramatrix sichern&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Identity;&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Identity;&lt;br /&gt;
  HomeMatrix.Identity;&lt;br /&gt;
&lt;br /&gt;
  Enabled := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Offset(x, y, z: TGLfloat);&lt;br /&gt;
// verschieben der Kamera auf einer beliebigen Achse&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  //OldView: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- Offset - Start --------------------------------------------------');&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslatef(x,y,z);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
&lt;br /&gt;
  Debug ('Position: '+GLvectorToText (GetMatrixPos (newMatrix)));&lt;br /&gt;
  newMatrix := UpdateMatrixOffset (newMatrix);&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  Debug ('- Offset - Ende- --------------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
			                           ViewVec: TGLvector;&lt;br /&gt;
			                           upVec: TGLvector);&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  i: integer;&lt;br /&gt;
  P, V, U: TGLvector;&lt;br /&gt;
  Laenge: TGLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCamera - Start ------------------------------------------');&lt;br /&gt;
  // die gewuenschte konstruktion immer auf die Z-ebene projizieren.&lt;br /&gt;
  // zuerst die position in den nullpunkt holen&lt;br /&gt;
  InitVector (P, 0, 0, 0);&lt;br /&gt;
  // jetzt den viewpoint um den gleichen betrag reduzieren, damit&lt;br /&gt;
  // die gerade parallel verschoben wird.&lt;br /&gt;
  V := SubtractVector (ViewVec, PositionVec);&lt;br /&gt;
  // U ist halt schneller geschrieben als upVec...&lt;br /&gt;
  U := upVec;&lt;br /&gt;
&lt;br /&gt;
  // den betrag ermitteln, um den die kamera nachher auf der Z-Achse&lt;br /&gt;
  // verschoben werden muss&lt;br /&gt;
  Laenge := Magnitude (SubtractVector (P, V));&lt;br /&gt;
&lt;br /&gt;
  Identity;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  // glulookat wird die matrix parallel zur Z-achse ausrichten&lt;br /&gt;
  gluLookAt (P.X, P.Y, P.Z, V.X, V.Y, V.Z, U.X, U.Y, U.Z);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  HomeMatrix.Load(newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // da wir uns jetzt am zielpunkt befinden, müssen wir auf der Z-achse&lt;br /&gt;
  // wieder zurueck zur kameraposition&lt;br /&gt;
  Offset (0, 0, -Laenge);&lt;br /&gt;
&lt;br /&gt;
  // alle positionsspeicher mit der Kameraposition, Blickrichtung&lt;br /&gt;
  // und dem upVector belegen. Nur beim ersten Aufruf von&lt;br /&gt;
  // PositionCamera&lt;br /&gt;
  if not Initiated then&lt;br /&gt;
    Initiate;&lt;br /&gt;
&lt;br /&gt;
  FPointOfRotation := ViewVec;&lt;br /&gt;
  Debug ('PointOfRotation: '+GLvectorToText (FPointOfRotation));&lt;br /&gt;
  Debug ('- PositionCamera - Ende -------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCross (CrossVec: TGLvector);&lt;br /&gt;
// diese prozedur verschiebt, im gegensatz zu einem verändern von&lt;br /&gt;
// PointOfRotation, das Koordinatenkreuz und nicht die Szene.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  PosDiff: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  Debug ('- PositionCross - Start -------------------------------------------');&lt;br /&gt;
&lt;br /&gt;
  PosDiff := SubtractVector (FPointOfRotation, CrossVec);&lt;br /&gt;
&lt;br /&gt;
  // Szene in das koordinatenkreuz verschieben&lt;br /&gt;
  FPointOfRotation := CrossVec;&lt;br /&gt;
&lt;br /&gt;
  // jetzt die Szene wieder um den gleichen betrag zurückverschieben&lt;br /&gt;
  // das sieht dann so aus, als ob das koordinatenkreuz verschoben&lt;br /&gt;
  // worden wäre&lt;br /&gt;
  // zuerst die aktuelle neue Situation herstellen&lt;br /&gt;
  // (mit neuem FPointOfRotation)&lt;br /&gt;
  Apply;&lt;br /&gt;
&lt;br /&gt;
  // jetzt um den Differenzbetrag des alten und neuen&lt;br /&gt;
  // Rotationspunkts zurück verschieben&lt;br /&gt;
  glTranslatef (-PosDiff.X, 0, 0);&lt;br /&gt;
  glTranslatef (0, -PosDiff.Y, 0);&lt;br /&gt;
  glTranslatef (0, 0, -PosDiff.Z);&lt;br /&gt;
&lt;br /&gt;
  // jetzt vom neuen Rotationspunktes zurück ins Zentrum, damit beim&lt;br /&gt;
  // nächsten Apply das glTranslatef (-FPointOfRotation, ...) klappt&lt;br /&gt;
  glTranslatef (CrossVec.X, 0, 0);&lt;br /&gt;
  glTranslatef (0, CrossVec.Y, 0);&lt;br /&gt;
  glTranslatef (0, 0, CrossVec.Z);&lt;br /&gt;
&lt;br /&gt;
  // aktuelle Matrix holen...&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // und als Kameramatrix abspeichern&lt;br /&gt;
  CameraMatrix.Load(newmatrix);&lt;br /&gt;
  Debug ('- PositionCross - Ende --------------------------------------------');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.CameraHome;&lt;br /&gt;
// Kamera in die beim letzten Aufruf von PositionCamera uebergebene&lt;br /&gt;
// Position/Lage bringen&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Load(HomeMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SavePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  PosArray[pos].Load(CameraMatrix.Matrix);&lt;br /&gt;
  RotArray[pos] := FPointOfRotation;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RestorePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(PosArray[pos].Matrix);&lt;br /&gt;
  FPointOfRotation := RotArray[pos];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GiveStoredPosition (pos: integer): TGLvector;&lt;br /&gt;
// gibt den Inhalt des durch pos bestimmten&lt;br /&gt;
// Positionsspecihers zurueck&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  result := GetMatrixPos (PosArray[pos].Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Verschiebung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  Offset (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Drehung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  RotateRoundAxis (-iy, -ix, -iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Apply;&lt;br /&gt;
// hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur&lt;br /&gt;
// sollte die Szene mit allen benoetigten Drehungen, Verschiebungen&lt;br /&gt;
// gezeichnet werden.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
  glTranslatef (-FPointOfRotation.X,&lt;br /&gt;
                -FPointOfRotation.y,&lt;br /&gt;
                -FPointOfRotation.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyForTerrain;&lt;br /&gt;
// hier wird wie in Apply die Kamera eingeschaltet. da man um ein terrain&lt;br /&gt;
// (skycube, ...) anzuzeigen aber immer die gleiche entfernung zur welt&lt;br /&gt;
// einhalten muss, wird hier nur gedreht und nicht verschoben.&lt;br /&gt;
var&lt;br /&gt;
  pos: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  // für das Terrain nur die Drehung ausführen&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
  // deswegen jetzt die verschiebung zurücknehmen&lt;br /&gt;
  Pos := GetMatrixPos (CameraMatrix.InverseMatrix);&lt;br /&gt;
  glTranslatef (Pos.X, Pos.Y, Pos.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetPosition: TGLvector;&lt;br /&gt;
// diese Property-Funktion fragt die aktuelle Position der Kamera ab&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  result := AddVector (GetMatrixPos (CameraMatrix.InverseMatrix), FPointOfRotation);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPosition (Pos: TGLvector);&lt;br /&gt;
// diese Property-Funktion setzt eine neue Position der Kamera&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  m := CameraMatrix.Matrix;&lt;br /&gt;
  SetMatrixPos (m, SubtractVector (Pos, FPointOfRotation));&lt;br /&gt;
  CameraMatrix.Load (m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetViewDirection: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  result := GetMatrixZ (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetViewDirection (View: TGLvector);&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// gesetzt werden&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  SetMatrixZ (CameraMatrix.InverseMatrix, View);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpVector: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Ausrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // upVector: zweite Spalte der Matrix (Y-Achse)&lt;br /&gt;
  result := GetMatrixY (CameraMatrix.InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Adjust;&lt;br /&gt;
// mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhaengig&lt;br /&gt;
// von Drehung und Position, zur Y-Achse ausgerichtet werden.&lt;br /&gt;
// Die aktuelle Position wird dabei beibehalten.&lt;br /&gt;
var&lt;br /&gt;
  m: TArrMatrix;&lt;br /&gt;
  v: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // position aus der aktuellen cameramatrix holen&lt;br /&gt;
  v := GetMatrixPos (CameraMatrix.Matrix);&lt;br /&gt;
  // m mit identitätsmatrix initialisieren&lt;br /&gt;
  m := GetIdentity(m);&lt;br /&gt;
  // die position aus der aktuellen cameramatrix in m speichern&lt;br /&gt;
  SetMatrixPos (m, v);&lt;br /&gt;
  // m als aktuelle cameramatrix speichern&lt;br /&gt;
  CameraMatrix.Load(m);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.InverseMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  result := CameraMatrix.InverseMatrix;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Initiate;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    SavePosition (i);&lt;br /&gt;
  Initiated := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpdateMatrixOffset (newMatrix: TArrMatrix): TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  // wenn ich mit Multiply (FixedAxis) arbeite, wird die zeichnung immer&lt;br /&gt;
  // entlang der bildschirmachsen verschoben. wenn ich Multiply, version 2&lt;br /&gt;
  // nehme, wird sie auf den errechneten achsen verschoben.&lt;br /&gt;
  if FFixedAxis then&lt;br /&gt;
  begin&lt;br /&gt;
    result := Multiply (newMatrix, CameraMatrix.Matrix);&lt;br /&gt;
  end&lt;br /&gt;
  else&lt;br /&gt;
  begin&lt;br /&gt;
    result := Multiply (CameraMatrix.Matrix, newMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPointOfRotation (NewPoint: TGLvector);&lt;br /&gt;
// setzt den viewpoint oder rotationpoint  ohne die anderen parameter zu&lt;br /&gt;
// veraendern. so kann man z.B. eine Kamerafahrt in immer der gleichen&lt;br /&gt;
// position simulieren.&lt;br /&gt;
begin&lt;br /&gt;
  FPointOfRotation := NewPoint;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Debug (Text: string);&lt;br /&gt;
begin&lt;br /&gt;
  if not FDebugOn then&lt;br /&gt;
    exit;&lt;br /&gt;
  writeln (FDebugFile, DateToStr (date) + ' | ' +&lt;br /&gt;
                       TimeToStr (time) + ' | ' +&lt;br /&gt;
                       Text);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
Initialization&lt;br /&gt;
  FDebugOn := false;&lt;br /&gt;
  FDebugFileName := ExePath + 'APPLICATION.DBG';&lt;br /&gt;
  if FDebugOn then&lt;br /&gt;
  begin&lt;br /&gt;
    AssignFile (FDebugFile, FDebugFileName);&lt;br /&gt;
    Rewrite (FDebugFile);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
finalization&lt;br /&gt;
  if FDebugOn then&lt;br /&gt;
    CloseFile (FDebugFile);&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=14368</id>
		<title>Kamera (2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=14368"/>
				<updated>2005-11-19T12:08:49Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Wie ich selber immer wieder merken muss, ist eine Software anscheinend&lt;br /&gt;
// nie fertig. Immer moechte man etwas verbessern oder neue Features&lt;br /&gt;
// einbauen.&lt;br /&gt;
// Sollte also jemand Aenderungs- oder Verbesserungsvorschlaege haben oder&lt;br /&gt;
// neue Ideen einbringen wollen, oder sollten Verstaendnisfragen bestehen,&lt;br /&gt;
// so mailt bitte an&lt;br /&gt;
//&lt;br /&gt;
// Andree.Heyroth@t-online.de&lt;br /&gt;
//&lt;br /&gt;
// Danke.&lt;br /&gt;
//&lt;br /&gt;
// Updates:&lt;br /&gt;
//&lt;br /&gt;
// 06.11.2005&lt;br /&gt;
// Die Deklaration der DESTROY Methode war falsch. Das fuehrte dazu,&lt;br /&gt;
// dass in der Methode CREATE erzeugte Objekte nicht richtig frei-&lt;br /&gt;
// gegeben wurden und es zu EAccessViolations kam. Die Methode wird&lt;br /&gt;
// jetzt in der PUBLIC Section mit der Direktive OVERRIDE aufgerufen.&lt;br /&gt;
//&lt;br /&gt;
// 11.11.2005&lt;br /&gt;
// Die Positionierung funktioniert jetzt.&lt;br /&gt;
// Wegen eines Verstaendnisproblems wurden die Positionen immer auf den&lt;br /&gt;
// Kamerapunkt aufaddiert. Das bedeutete, dass die Positionierung aus&lt;br /&gt;
// dem Ruder lief wenn sie nicht im Nullpunkt stattfand. Je groesser die&lt;br /&gt;
// gewuenschte Position war um so groesser war die Abweichung von der&lt;br /&gt;
// Darstellung.&lt;br /&gt;
// Ich habe nicht bedacht, dass bei einer &amp;quot;Kamera&amp;quot;-bewegung und -drehung&lt;br /&gt;
// ja eigentlich die Szene bewegt und gedreht wird. Deswegen wurden nach&lt;br /&gt;
// einer Positionierung die folgenden Projektionen immer basierend auf der&lt;br /&gt;
// danach gueltigen Kameraposition gemacht.&lt;br /&gt;
// Jetzt wird die Position so gesetzt, dass die gewuenschte Kameraposition&lt;br /&gt;
// immer vor dem Betrachter steht.&lt;br /&gt;
//&lt;br /&gt;
unit Camera;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
  Uses DglOpenGL, OpenGLUtil, Windows, Classes;&lt;br /&gt;
&lt;br /&gt;
  type&lt;br /&gt;
  TCameraMatrix=Class&lt;br /&gt;
    Matrix: TArrMatrix;&lt;br /&gt;
    InverseMatrix: TArrMatrix;&lt;br /&gt;
    //constructor Create;&lt;br /&gt;
    //destructor destroy;&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Load(M: TArrMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TCamera=Class&lt;br /&gt;
    CameraMatrix: TCameraMatrix;&lt;br /&gt;
    HomeMatrix: TCameraMatrix;&lt;br /&gt;
    Enabled  : boolean;&lt;br /&gt;
    Initiated: boolean;&lt;br /&gt;
    FPosition: TGLvector;&lt;br /&gt;
    FPointOfRotation: TGLvector;&lt;br /&gt;
    FPositionOffset: TGLvector;&lt;br /&gt;
    function UpVector: TGLvector;&lt;br /&gt;
    function ViewDirection: TGLvector;&lt;br /&gt;
    procedure RestorePosition(pos: integer);&lt;br /&gt;
    procedure SavePosition(pos: integer);&lt;br /&gt;
    function GivePosition(pos: integer): TGLvector;&lt;br /&gt;
    procedure RotateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure TranslateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure CameraHome;&lt;br /&gt;
    procedure PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
	                     ViewVec: TGLvector;&lt;br /&gt;
			     upVec: TGLvector);&lt;br /&gt;
    procedure Adjust;&lt;br /&gt;
    procedure Apply;&lt;br /&gt;
    procedure ApplyForTerrain;&lt;br /&gt;
  private&lt;br /&gt;
    PosArray: array [0..9] of TCameraMatrix;&lt;br /&gt;
    function GetPosition: TGLvector;&lt;br /&gt;
    procedure SetPosition (Pos: TGLvector);&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure RotateMatrix(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure Offset(x, y, z: TGLfloat);&lt;br /&gt;
    procedure RotateRoundAxis(rx, ry, rz: TGLfloat);&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    destructor Destroy;override;&lt;br /&gt;
  published&lt;br /&gt;
    property PointOfRotation: TGLvector read FPointOfRotation;&lt;br /&gt;
    property Position: TGLvector read GetPosition write SetPosition;&lt;br /&gt;
  end;&lt;br /&gt;
  TPCamera=^TCamera;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses SysUtils;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
constructor TCameraMatrix.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCameraMatrix.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Identity;&lt;br /&gt;
// GetArrIdentity: aus OpenGL.pas&lt;br /&gt;
// initialisiert die CameraMatrix mit der Identitaetsmatrix&lt;br /&gt;
begin&lt;br /&gt;
  Matrix := GetIdentity(Matrix);&lt;br /&gt;
  InverseMatrix := GetIdentity(InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Load(M: TArrMatrix);&lt;br /&gt;
// die Matrix mit den Werten einer beliebigen anderen matrix fuellen&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i:=0 to 15 do&lt;br /&gt;
    Matrix[i]:=M[i];&lt;br /&gt;
  // die invertierte Matrix kann benutzt werden um Objkekte z.B.&lt;br /&gt;
  // immer zum Benutzer auszurichten&lt;br /&gt;
  InvertMatrix (M, InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
constructor TCamera.Create;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
&lt;br /&gt;
  // Initiated wird gebraucht um einmal alle Positionsspeicher &lt;br /&gt;
  // mit der Anfangsposition zu belegen&lt;br /&gt;
  Initiated := false;&lt;br /&gt;
  &lt;br /&gt;
  // Kameramatrix anlegen&lt;br /&gt;
  CameraMatrix := TCameraMatrix.Create;&lt;br /&gt;
  &lt;br /&gt;
  // Matrix der letzten Position von PositionCamera anlegen&lt;br /&gt;
  HomeMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Positionsspeicher anlegen&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    PosArray[i] := TCameraMatrix.Create;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCamera.Destroy;&lt;br /&gt;
// alle in create belegten Resourcen wieder freigeben&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FreeAndNil (CameraMatrix);&lt;br /&gt;
  FreeAndNil (HomeMatrix);&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    FreeAndNil (PosArray[i]);&lt;br /&gt;
&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat);&lt;br /&gt;
// hier drehen wir jetzt um die einzelnen Achsen.&lt;br /&gt;
// die Parameter geben die &amp;quot;Drehgeschwindigkeit&amp;quot; vor.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  // aktuelle Position und Lage der Kamera herstellen&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
&lt;br /&gt;
  // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
  if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
    glRotatef(rx,1,0,0);&lt;br /&gt;
&lt;br /&gt;
  // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
  if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
    glRotatef(ry,0,1,0);&lt;br /&gt;
&lt;br /&gt;
  // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
  if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
    glRotatef(rz,0,0,1);&lt;br /&gt;
&lt;br /&gt;
  // die neu erzeugte Matrix auslesen&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  // und in die Kameramatrix sichern&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Identity;&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Identity;&lt;br /&gt;
  HomeMatrix.Identity;&lt;br /&gt;
&lt;br /&gt;
  Enabled := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Offset(x, y, z: TGLfloat);&lt;br /&gt;
// verschieben der Kamera auf einer beliebigen Achse&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslatef(x,y,z);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  // wenn ich mit der funktion glMultMatrixf arbeite, wird die zeichnung&lt;br /&gt;
  // immer entlang der richtigen achsen verschoben. wenn ich matrixmultiply&lt;br /&gt;
  // nehme, wird sie auf den bildschirmachsen verschoben. das ist angenehmer&lt;br /&gt;
  // zum arbeiten&lt;br /&gt;
  newMatrix := Multiply (newMatrix, CameraMatrix.Matrix);&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
			                           ViewVec: TGLvector;&lt;br /&gt;
			                           upVec: TGLvector);&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  i: integer;&lt;br /&gt;
  P, V, U: TGLvector;&lt;br /&gt;
  Laenge: TGLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // die gewuenschte konstruktion immer auf die Z-ebene projizieren.&lt;br /&gt;
  // zuerst die position in den nullpunkt holen&lt;br /&gt;
  InitVector (P, 0, 0, 0);&lt;br /&gt;
  // jetzt den viewpoint um den gleichen betrag reduzieren, damit&lt;br /&gt;
  // die gerade parallel verschoben wird.&lt;br /&gt;
  V := SubtractVector (ViewVec, PositionVec);&lt;br /&gt;
  // U ist halt schneller geschrieben als upVec...&lt;br /&gt;
  U := upVec;&lt;br /&gt;
  // den betrag ermitteln, um den die kamera nachher auf der Z-Achse &lt;br /&gt;
  // verschoben werden muss&lt;br /&gt;
  Laenge := Magnitude (SubtractVector (P, V));&lt;br /&gt;
&lt;br /&gt;
  Identity;&lt;br /&gt;
  FPointOfRotation := ViewVec;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  // glulookat wird die matrix parallel zur Z-achse ausrichten&lt;br /&gt;
  gluLookAt (P.X, P.Y, P.Z, V.X, V.Y, V.Z, U.X, U.Y, U.Z);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  HomeMatrix.Load(newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // da wir uns jetzt am zielpunkt befinden, müssen wir auf der Z-achse&lt;br /&gt;
  // wieder zurück zur kameraposition&lt;br /&gt;
  Offset (0, 0, -Laenge);&lt;br /&gt;
&lt;br /&gt;
  // damit GetPosition den Wert zurückgibt den wir mit PositionCamera&lt;br /&gt;
  // eingestellt haben, müssen wir die zu der von gluLookAt errechneten&lt;br /&gt;
  // Position bestehende Differenz errechnen&lt;br /&gt;
  FPositionOffset.X := PositionVec.X - CameraMatrix.Matrix[12];&lt;br /&gt;
  FPositionOffset.Y := PositionVec.Y - CameraMatrix.Matrix[13];&lt;br /&gt;
  FPositionOffset.Z := PositionVec.Z - CameraMatrix.Matrix[14];&lt;br /&gt;
&lt;br /&gt;
  // alle positionsspeicher mit der Kameraposition, Blickrichtung &lt;br /&gt;
  // und dem upVector belegen. Nur beim ersten Aufruf von&lt;br /&gt;
  // PositionCamera&lt;br /&gt;
  if not Initiated then&lt;br /&gt;
  begin&lt;br /&gt;
    for i := 0 to 9 do&lt;br /&gt;
      SavePosition (i);&lt;br /&gt;
    Initiated := true;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.CameraHome;&lt;br /&gt;
// Kamera in die beim letzten Aufruf von PositionCamera Ã¼bergebene&lt;br /&gt;
// Position/Lage bringen&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Load(HomeMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SavePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  PosArray[pos].Load(CameraMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RestorePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(PosArray[pos].Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GivePosition (pos: integer): TGLvector;&lt;br /&gt;
// gibt den Inhalt des durch pos bestimmten &lt;br /&gt;
// Positionsspecihers zurueck&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  result.X := PosArray[pos].Matrix[12];&lt;br /&gt;
  result.Y := PosArray[pos].Matrix[13];&lt;br /&gt;
  result.Z := PosArray[pos].Matrix[14];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Verschiebung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  Offset (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Drehung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  RotateMatrix (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Apply;&lt;br /&gt;
// hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur &lt;br /&gt;
// sollte die Szene mit allen benoetigten Drehungen, Verschiebungen &lt;br /&gt;
// gezeichnet werden.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
  glTranslatef (-PointOfRotation.X,&lt;br /&gt;
                -PointOfRotation.y,&lt;br /&gt;
                -PointOfRotation.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyForTerrain;&lt;br /&gt;
// hier wird wie in Apply die Kamera eingeschaltet. da man um ein terrain &lt;br /&gt;
// (skycube, ...) anzuzeigen aber immer die gleiche entfernung zur welt&lt;br /&gt;
// einhalten muss, wird hier nur gedreht und nicht verschoben.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  // für das Terrain nur die Drehung ausführen&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
  // deswegen jetzt die verschiebung zurücknehmen&lt;br /&gt;
  glTranslatef (CameraMatrix.InverseMatrix[12],&lt;br /&gt;
                CameraMatrix.InverseMatrix[13],&lt;br /&gt;
                CameraMatrix.InverseMatrix[14]);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  // um den austausch von verschiedenen kameramodulen so einfach&lt;br /&gt;
  // wie möglich zu gestalten, kann hier ein bisschen variiert werden...&lt;br /&gt;
  RotateRoundAxis (-iy, -ix, -iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetPosition: TGLvector;&lt;br /&gt;
// diese Property-Funktion fragt die aktuelle Position der Kamera ab&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  InitVector (return,&lt;br /&gt;
              CameraMatrix.Matrix[12],&lt;br /&gt;
              CameraMatrix.Matrix[13],&lt;br /&gt;
              CameraMatrix.Matrix[14]);&lt;br /&gt;
  return := AddVector (return, FPositionOffset);&lt;br /&gt;
  result := return;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPosition (Pos: TGLvector);&lt;br /&gt;
// diese Property-Funktion setzt eine neue Position der Kamera&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  CameraMatrix.Matrix[12] := Pos.X;&lt;br /&gt;
  CameraMatrix.Matrix[13] := Pos.Y;&lt;br /&gt;
  CameraMatrix.Matrix[14] := Pos.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.ViewDirection: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  InitVector (return,&lt;br /&gt;
              CameraMatrix.Matrix[08],&lt;br /&gt;
              CameraMatrix.Matrix[09],&lt;br /&gt;
              CameraMatrix.Matrix[10]);&lt;br /&gt;
  result := return;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpVector: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Ausrichtung der Kamera &lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // upVector: zweite Spalte der Matrix (Y-Achse)&lt;br /&gt;
  InitVector (return,&lt;br /&gt;
              CameraMatrix.Matrix[04],&lt;br /&gt;
              CameraMatrix.Matrix[05],&lt;br /&gt;
              CameraMatrix.Matrix[06]);&lt;br /&gt;
  result := return;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Adjust;&lt;br /&gt;
// mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhaengig &lt;br /&gt;
// von Drehung und Position, senkrecht zur Y-Achse ausgerichtet&lt;br /&gt;
// werden. Die aktuelle Position wird dabei beibehalten.&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  temp := GetIdentity(temp);&lt;br /&gt;
  temp[12] := CameraMatrix.Matrix[12];&lt;br /&gt;
  temp[13] := CameraMatrix.Matrix[13];&lt;br /&gt;
  temp[14] := CameraMatrix.Matrix[14];&lt;br /&gt;
  temp[15] := CameraMatrix.Matrix[15];&lt;br /&gt;
  CameraMatrix.Load(temp);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=14367</id>
		<title>Kamera (2)</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Kamera_(2)&amp;diff=14367"/>
				<updated>2005-11-19T12:08:22Z</updated>
		
		<summary type="html">&lt;p&gt;Andyh: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Beschreibung findet ihr unter [[Kamera (1)]].&amp;lt;br&amp;gt; &lt;br /&gt;
Die verwendete Toolsammlung findet ihr unter [[Kamera (3)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
// Wie ich selber immer wieder merken muss, ist eine Software anscheinend&lt;br /&gt;
// nie fertig. Immer moechte man etwas verbessern oder neue Features&lt;br /&gt;
// einbauen.&lt;br /&gt;
// Sollte also jemand Änderungs- oder Verbesserungsvorschläge haben oder&lt;br /&gt;
// neue Ideen einbringen wollen, oder sollten Verstaendnisfragen bestehen,&lt;br /&gt;
// so mailt bitte an&lt;br /&gt;
//&lt;br /&gt;
// Andree.Heyroth@t-online.de&lt;br /&gt;
//&lt;br /&gt;
// Danke.&lt;br /&gt;
//&lt;br /&gt;
// Updates:&lt;br /&gt;
//&lt;br /&gt;
// 06.11.2005&lt;br /&gt;
// Die Deklaration der DESTROY Methode war falsch. Das fuehrte dazu,&lt;br /&gt;
// dass in der Methode CREATE erzeugte Objekte nicht richtig frei-&lt;br /&gt;
// gegeben wurden und es zu EAccessViolations kam. Die Methode wird&lt;br /&gt;
// jetzt in der PUBLIC Section mit der Direktive OVERRIDE aufgerufen.&lt;br /&gt;
//&lt;br /&gt;
// 11.11.2005&lt;br /&gt;
// Die Positionierung funktioniert jetzt.&lt;br /&gt;
// Wegen eines Verstaendnisproblems wurden die Positionen immer auf den&lt;br /&gt;
// Kamerapunkt aufaddiert. Das bedeutete, dass die Positionierung aus&lt;br /&gt;
// dem Ruder lief wenn sie nicht im Nullpunkt stattfand. Je groesser die&lt;br /&gt;
// gewuenschte Position war um so groesser war die Abweichung von der&lt;br /&gt;
// Darstellung.&lt;br /&gt;
// Ich habe nicht bedacht, dass bei einer &amp;quot;Kamera&amp;quot;-bewegung und -drehung&lt;br /&gt;
// ja eigentlich die Szene bewegt und gedreht wird. Deswegen wurden nach&lt;br /&gt;
// einer Positionierung die folgenden Projektionen immer basierend auf der&lt;br /&gt;
// danach gueltigen Kameraposition gemacht.&lt;br /&gt;
// Jetzt wird die Position so gesetzt, dass die gewuenschte Kameraposition&lt;br /&gt;
// immer vor dem Betrachter steht.&lt;br /&gt;
//&lt;br /&gt;
unit Camera;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
  Uses DglOpenGL, OpenGLUtil, Windows, Classes;&lt;br /&gt;
&lt;br /&gt;
  type&lt;br /&gt;
  TCameraMatrix=Class&lt;br /&gt;
    Matrix: TArrMatrix;&lt;br /&gt;
    InverseMatrix: TArrMatrix;&lt;br /&gt;
    //constructor Create;&lt;br /&gt;
    //destructor destroy;&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure Load(M: TArrMatrix);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TCamera=Class&lt;br /&gt;
    CameraMatrix: TCameraMatrix;&lt;br /&gt;
    HomeMatrix: TCameraMatrix;&lt;br /&gt;
    Enabled  : boolean;&lt;br /&gt;
    Initiated: boolean;&lt;br /&gt;
    FPosition: TGLvector;&lt;br /&gt;
    FPointOfRotation: TGLvector;&lt;br /&gt;
    FPositionOffset: TGLvector;&lt;br /&gt;
    function UpVector: TGLvector;&lt;br /&gt;
    function ViewDirection: TGLvector;&lt;br /&gt;
    procedure RestorePosition(pos: integer);&lt;br /&gt;
    procedure SavePosition(pos: integer);&lt;br /&gt;
    function GivePosition(pos: integer): TGLvector;&lt;br /&gt;
    procedure RotateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure TranslateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure CameraHome;&lt;br /&gt;
    procedure PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
	                     ViewVec: TGLvector;&lt;br /&gt;
			     upVec: TGLvector);&lt;br /&gt;
    procedure Adjust;&lt;br /&gt;
    procedure Apply;&lt;br /&gt;
    procedure ApplyForTerrain;&lt;br /&gt;
  private&lt;br /&gt;
    PosArray: array [0..9] of TCameraMatrix;&lt;br /&gt;
    function GetPosition: TGLvector;&lt;br /&gt;
    procedure SetPosition (Pos: TGLvector);&lt;br /&gt;
    procedure Identity;&lt;br /&gt;
    procedure RotateMatrix(ix, iy, iz: TGLdouble);&lt;br /&gt;
    procedure Offset(x, y, z: TGLfloat);&lt;br /&gt;
    procedure RotateRoundAxis(rx, ry, rz: TGLfloat);&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create;&lt;br /&gt;
    destructor Destroy;override;&lt;br /&gt;
  published&lt;br /&gt;
    property PointOfRotation: TGLvector read FPointOfRotation;&lt;br /&gt;
    property Position: TGLvector read GetPosition write SetPosition;&lt;br /&gt;
  end;&lt;br /&gt;
  TPCamera=^TCamera;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses SysUtils;&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
constructor TCameraMatrix.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCameraMatrix.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Identity;&lt;br /&gt;
// GetArrIdentity: aus OpenGL.pas&lt;br /&gt;
// initialisiert die CameraMatrix mit der Identitaetsmatrix&lt;br /&gt;
begin&lt;br /&gt;
  Matrix := GetIdentity(Matrix);&lt;br /&gt;
  InverseMatrix := GetIdentity(InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCameraMatrix.Load(M: TArrMatrix);&lt;br /&gt;
// die Matrix mit den Werten einer beliebigen anderen matrix fuellen&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  for i:=0 to 15 do&lt;br /&gt;
    Matrix[i]:=M[i];&lt;br /&gt;
  // die invertierte Matrix kann benutzt werden um Objkekte z.B.&lt;br /&gt;
  // immer zum Benutzer auszurichten&lt;br /&gt;
  InvertMatrix (M, InverseMatrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
constructor TCamera.Create;&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  inherited create;&lt;br /&gt;
&lt;br /&gt;
  // Initiated wird gebraucht um einmal alle Positionsspeicher &lt;br /&gt;
  // mit der Anfangsposition zu belegen&lt;br /&gt;
  Initiated := false;&lt;br /&gt;
  &lt;br /&gt;
  // Kameramatrix anlegen&lt;br /&gt;
  CameraMatrix := TCameraMatrix.Create;&lt;br /&gt;
  &lt;br /&gt;
  // Matrix der letzten Position von PositionCamera anlegen&lt;br /&gt;
  HomeMatrix := TCameraMatrix.Create;&lt;br /&gt;
&lt;br /&gt;
  // Positionsspeicher anlegen&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    PosArray[i] := TCameraMatrix.Create;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TCamera.Destroy;&lt;br /&gt;
// alle in create belegten Resourcen wieder freigeben&lt;br /&gt;
var&lt;br /&gt;
  i: integer;&lt;br /&gt;
begin&lt;br /&gt;
  FreeAndNil (CameraMatrix);&lt;br /&gt;
  FreeAndNil (HomeMatrix);&lt;br /&gt;
  for i := 0 to 9 do&lt;br /&gt;
    FreeAndNil (PosArray[i]);&lt;br /&gt;
&lt;br /&gt;
  inherited destroy;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat);&lt;br /&gt;
// hier drehen wir jetzt um die einzelnen Achsen.&lt;br /&gt;
// die Parameter geben die &amp;quot;Drehgeschwindigkeit&amp;quot; vor.&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  // aktuelle Position und Lage der Kamera herstellen&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
&lt;br /&gt;
  // wenn gewuenscht um die X-Achse drehen&lt;br /&gt;
  if(rx &amp;lt;&amp;gt; 0) then&lt;br /&gt;
    glRotatef(rx,1,0,0);&lt;br /&gt;
&lt;br /&gt;
  // wenn gewuenscht um die Y-Achse drehen&lt;br /&gt;
  if(ry &amp;lt;&amp;gt; 0) then&lt;br /&gt;
    glRotatef(ry,0,1,0);&lt;br /&gt;
&lt;br /&gt;
  // wenn gewuenscht um die Z-Achse drehen&lt;br /&gt;
  if(rz &amp;lt;&amp;gt; 0) then&lt;br /&gt;
    glRotatef(rz,0,0,1);&lt;br /&gt;
&lt;br /&gt;
  // die neu erzeugte Matrix auslesen&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  // und in die Kameramatrix sichern&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Identity;&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Identity;&lt;br /&gt;
  HomeMatrix.Identity;&lt;br /&gt;
&lt;br /&gt;
  Enabled := true;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Offset(x, y, z: TGLfloat);&lt;br /&gt;
// verschieben der Kamera auf einer beliebigen Achse&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix();&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslatef(x,y,z);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  // wenn ich mit der funktion glMultMatrixf arbeite, wird die zeichnung&lt;br /&gt;
  // immer entlang der richtigen achsen verschoben. wenn ich matrixmultiply&lt;br /&gt;
  // nehme, wird sie auf den bildschirmachsen verschoben. das ist angenehmer&lt;br /&gt;
  // zum arbeiten&lt;br /&gt;
  newMatrix := Multiply (newMatrix, CameraMatrix.Matrix);&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  glPopMatrix();&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.PositionCamera(PositionVec: TGLvector;&lt;br /&gt;
			                           ViewVec: TGLvector;&lt;br /&gt;
			                           upVec: TGLvector);&lt;br /&gt;
var&lt;br /&gt;
  newMatrix: TArrMatrix;&lt;br /&gt;
  i: integer;&lt;br /&gt;
  P, V, U: TGLvector;&lt;br /&gt;
  Laenge: TGLdouble;&lt;br /&gt;
begin&lt;br /&gt;
  // die gewuenschte konstruktion immer auf die Z-ebene projizieren.&lt;br /&gt;
  // zuerst die position in den nullpunkt holen&lt;br /&gt;
  InitVector (P, 0, 0, 0);&lt;br /&gt;
  // jetzt den viewpoint um den gleichen betrag reduzieren, damit&lt;br /&gt;
  // die gerade parallel verschoben wird.&lt;br /&gt;
  V := SubtractVector (ViewVec, PositionVec);&lt;br /&gt;
  // U ist halt schneller geschrieben als upVec...&lt;br /&gt;
  U := upVec;&lt;br /&gt;
  // den betrag ermitteln, um den die kamera nachher auf der Z-Achse &lt;br /&gt;
  // verschoben werden muss&lt;br /&gt;
  Laenge := Magnitude (SubtractVector (P, V));&lt;br /&gt;
&lt;br /&gt;
  Identity;&lt;br /&gt;
  FPointOfRotation := ViewVec;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  // glulookat wird die matrix parallel zur Z-achse ausrichten&lt;br /&gt;
  gluLookAt (P.X, P.Y, P.Z, V.X, V.Y, V.Z, U.X, U.Y, U.Z);&lt;br /&gt;
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(newMatrix);&lt;br /&gt;
  HomeMatrix.Load(newMatrix);&lt;br /&gt;
&lt;br /&gt;
  // da wir uns jetzt am zielpunkt befinden, müssen wir auf der Z-achse&lt;br /&gt;
  // wieder zurück zur kameraposition&lt;br /&gt;
  Offset (0, 0, -Laenge);&lt;br /&gt;
&lt;br /&gt;
  // damit GetPosition den Wert zurückgibt den wir mit PositionCamera&lt;br /&gt;
  // eingestellt haben, müssen wir die zu der von gluLookAt errechneten&lt;br /&gt;
  // Position bestehende Differenz errechnen&lt;br /&gt;
  FPositionOffset.X := PositionVec.X - CameraMatrix.Matrix[12];&lt;br /&gt;
  FPositionOffset.Y := PositionVec.Y - CameraMatrix.Matrix[13];&lt;br /&gt;
  FPositionOffset.Z := PositionVec.Z - CameraMatrix.Matrix[14];&lt;br /&gt;
&lt;br /&gt;
  // alle positionsspeicher mit der Kameraposition, Blickrichtung &lt;br /&gt;
  // und dem upVector belegen. Nur beim ersten Aufruf von&lt;br /&gt;
  // PositionCamera&lt;br /&gt;
  if not Initiated then&lt;br /&gt;
  begin&lt;br /&gt;
    for i := 0 to 9 do&lt;br /&gt;
      SavePosition (i);&lt;br /&gt;
    Initiated := true;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.CameraHome;&lt;br /&gt;
// Kamera in die beim letzten Aufruf von PositionCamera Ã¼bergebene&lt;br /&gt;
// Position/Lage bringen&lt;br /&gt;
begin&lt;br /&gt;
  CameraMatrix.Load(HomeMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SavePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  PosArray[pos].Load(CameraMatrix.Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RestorePosition (pos: integer);&lt;br /&gt;
// wie der Prozedurname schon sagt...&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  CameraMatrix.Load(PosArray[pos].Matrix);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GivePosition (pos: integer): TGLvector;&lt;br /&gt;
// gibt den Inhalt des durch pos bestimmten &lt;br /&gt;
// Positionsspecihers zurueck&lt;br /&gt;
begin&lt;br /&gt;
  if (pos &amp;lt; 0) or (pos &amp;gt; 9) then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  result.X := PosArray[pos].Matrix[12];&lt;br /&gt;
  result.Y := PosArray[pos].Matrix[13];&lt;br /&gt;
  result.Z := PosArray[pos].Matrix[14];&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Verschiebung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  Offset (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble);&lt;br /&gt;
// vom Benutzer aufzurufende Methode um eine Drehung&lt;br /&gt;
// durchzufuehren&lt;br /&gt;
begin&lt;br /&gt;
  RotateMatrix (ix, iy, iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Apply;&lt;br /&gt;
// hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur &lt;br /&gt;
// sollte die Szene mit allen benoetigten Drehungen, Verschiebungen &lt;br /&gt;
// gezeichnet werden.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
  glTranslatef (-PointOfRotation.X,&lt;br /&gt;
                -PointOfRotation.y,&lt;br /&gt;
                -PointOfRotation.Z);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.ApplyForTerrain;&lt;br /&gt;
// hier wird wie in Apply die Kamera eingeschaltet. da man um ein terrain &lt;br /&gt;
// (skycube, ...) anzuzeigen aber immer die gleiche entfernung zur welt&lt;br /&gt;
// einhalten muss, wird hier nur gedreht und nicht verschoben.&lt;br /&gt;
begin&lt;br /&gt;
  if not Enabled then&lt;br /&gt;
    exit;&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode (GL_MODELVIEW);&lt;br /&gt;
  // für das Terrain nur die Drehung ausführen&lt;br /&gt;
  glLoadMatrixf(@CameraMatrix.Matrix);&lt;br /&gt;
  // deswegen jetzt die verschiebung zurücknehmen&lt;br /&gt;
  glTranslatef (CameraMatrix.InverseMatrix[12],&lt;br /&gt;
                CameraMatrix.InverseMatrix[13],&lt;br /&gt;
                CameraMatrix.InverseMatrix[14]);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble);&lt;br /&gt;
begin&lt;br /&gt;
  // um den austausch von verschiedenen kameramodulen so einfach&lt;br /&gt;
  // wie möglich zu gestalten, kann hier ein bisschen variiert werden...&lt;br /&gt;
  RotateRoundAxis (-iy, -ix, -iz);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.GetPosition: TGLvector;&lt;br /&gt;
// diese Property-Funktion fragt die aktuelle Position der Kamera ab&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  InitVector (return,&lt;br /&gt;
              CameraMatrix.Matrix[12],&lt;br /&gt;
              CameraMatrix.Matrix[13],&lt;br /&gt;
              CameraMatrix.Matrix[14]);&lt;br /&gt;
  return := AddVector (return, FPositionOffset);&lt;br /&gt;
  result := return;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.SetPosition (Pos: TGLvector);&lt;br /&gt;
// diese Property-Funktion setzt eine neue Position der Kamera&lt;br /&gt;
begin&lt;br /&gt;
  // position: letzte Spalte der Matrix&lt;br /&gt;
  CameraMatrix.Matrix[12] := Pos.X;&lt;br /&gt;
  CameraMatrix.Matrix[13] := Pos.Y;&lt;br /&gt;
  CameraMatrix.Matrix[14] := Pos.Z;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.ViewDirection: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Blickrichtung der Kamera&lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // view direction: dritte Spalte der Matrix (Z-Achse)&lt;br /&gt;
  InitVector (return,&lt;br /&gt;
              CameraMatrix.Matrix[08],&lt;br /&gt;
              CameraMatrix.Matrix[09],&lt;br /&gt;
              CameraMatrix.Matrix[10]);&lt;br /&gt;
  result := return;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TCamera.UpVector: TGLvector;&lt;br /&gt;
// mit dieser Funktion kann die aktuelle Ausrichtung der Kamera &lt;br /&gt;
// abgefragt werden&lt;br /&gt;
var&lt;br /&gt;
  return: TGLvector;&lt;br /&gt;
begin&lt;br /&gt;
  // upVector: zweite Spalte der Matrix (Y-Achse)&lt;br /&gt;
  InitVector (return,&lt;br /&gt;
              CameraMatrix.Matrix[04],&lt;br /&gt;
              CameraMatrix.Matrix[05],&lt;br /&gt;
              CameraMatrix.Matrix[06]);&lt;br /&gt;
  result := return;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TCamera.Adjust;&lt;br /&gt;
// mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhaengig &lt;br /&gt;
// von Drehung und Position, senkrecht zur Y-Achse ausgerichtet&lt;br /&gt;
// werden. Die aktuelle Position wird dabei beibehalten.&lt;br /&gt;
var&lt;br /&gt;
  temp: TArrMatrix;&lt;br /&gt;
begin&lt;br /&gt;
  temp := GetIdentity(temp);&lt;br /&gt;
  temp[12] := CameraMatrix.Matrix[12];&lt;br /&gt;
  temp[13] := CameraMatrix.Matrix[13];&lt;br /&gt;
  temp[14] := CameraMatrix.Matrix[14];&lt;br /&gt;
  temp[15] := CameraMatrix.Matrix[15];&lt;br /&gt;
  CameraMatrix.Load(temp);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Andyh</name></author>	</entry>

	</feed>