Die freie Kamera
Was ist eine freie Kamera?
Die freie Kamera wird vom Benutzer gesteuert, unabhängig von dem, was sich in der Szenerie abspielt. Der Benutzer kann sich mit der Kamera frei in der gesamten Szenerie bewegen und sich die Objekte aus beliebiger Entfernung und aus beliebigem Blickwinkel betrachten.
Worin besteht die Einstellung der Kamera?
Folgende Vorgänge sollten möglich sein, damit die Kamera ihre Funktion erfüllen kann:
- Bewegung vorwärts oder rückwärts
- Bewegung nach links oder rechts
- Bewegung nach oben oder unten
- Drehung nach links oder rechts
- Drehung nach oben oder unten
Um volle Beweglichkeit zu erreichen, müsste eigentlich noch die Drehung um die optische Achse hinzukommen. Diese Option dient dazu, den Horizont waagerecht zu justieren. Da es im Gegensatz zur Realität keine Probleme mit Unebenheiten des Untergrundes gibt, kann darauf verzichtet werden.
Einstellung mit der Tastatur
Für die oben aufgezählten Steuervorgänge sind 10 Tasten vorzusehen. Welche Tasten man nimmt, ist prinzipiell beliebig; in der Regel werden die Cursortasten einbezogen. Es empfiehlt sich aber, die Tastenaktionen nicht direkt auszuwerten, sondern jeweils in einem boolschen Flag zu speichern. z.B.
static bool camera_forward; static bool camera_turn_left; ...
Wenn die dafür vorgesehene Taste gedrückt wird, wird das Flag auf true gestellt, beim Loslassen auf false. Das hat den enormen Vorteil, dass mehrere Tasten gleichzeitig wirksam werden können. Die Kamera kann z.B. gleichzeitig nach rechts verschoben und nach links gedreht werden. Außerdem können auf diese Weise zusätzliche Beschleunigungstasten vorgesehen werden, die - wenn sie gleichzeitig gedrückt werden - größere Bewegungsschritte zur Folge haben.
Durch systematische Abfrage der Kameraflags (in der Programm-Hauptschleife) werden nun die Kamera-Parameter aktualisiert:
if (camera_forward) ViewMoveZ (-20 * timestep); if (camera_Back) ViewMoveZ (20 * timestep); if (camara_left) ViewMoveX (-1 * timestep); if (camera_right) ViewMoveX (1 * timestep); if (camera_up) ViewMoveY (5 * timestep); if (camera_down) ViewMoveY (-5 * timestep); if (camera_turn_left) ViewRotateY (20.0 * timestep); if (camera_turn_right) ViewRotateY (-20.0 * timestep); if (camera_turn_up) ViewRotateX (20 * timestep); if (camera_turn_down) ViewRotateX (-20 * timestep);
Die seit dem letzten Frame verflossene Zeitspanne (timestep) sollte unbedingt berücksichtigt werden, um schwankende Frameraten auszugleichen und darüber hinaus unabhängig von der Rechnergeschwindigkeit zu sein. Die Funktionen zur Aktualisierung der Parameter:
static GLfloat xview = 0; // x-Position der Kamera static GLfloat yview = 2; // Y-Position der Kamera static GLfloat zview = 0; // z-Position der Kamera static GLfloat vhead = 0; // heading - Rundumsicht (Y) static GLfloat vpitch = -10; // pitch - Drehung nach oben/unten (X) void ViewMoveZ (GLfloat step) { xview += sin (vhead * pi / 180) * step; zview += cos (vhead * pi / 180) * step; } void ViewMoveX (GLfloat step) { zview += sin (-vhead * pi / 180) * step; xview += cos (-vhead * pi / 180) * step; } void ViewMoveY (GLfloat step) {yview += step;} void ViewRotateY (GLfloat step) {vhead += step;} void ViewRotateX (GLfloat step) {vpitch += step;}
Auf der Basis der aktualisierten Kamera-Parameter wird schließlich am Anfang der Renderfunktion die View-Matrix aufgebaut:
void UpdateView () { glLoadIdentity (); glRotatef (-vpitch, 1.0, 0.0 , 0.0); glRotatef (-vhead, 0.0, 1.0 , 0.0); glTranslatef (-xview, -yview, -zview); }
Einstellung mit der Maus
Schick und von einigen Usern als benutzerfreundlich empfunden ist die Einstellung der Kamera mit der Maus. Die Vorwärts- bzw. Rückwärtsbewegung erfolg dabei meisten mit dem Mausrad; bei den anderen Bewegungen wird eine Stelle im Viewport angeklickt und gezogen. Mit etwas Übung kann man auf diese Weise sehr schnell die gewünschte Sicht erreichen.
[Dieser Abschnitt ist noch unvollständig. Es fehlt der Code.]