Visual Studio Projekt herunterladen
Unser erstes 3D-Projekt arbeitet mit einer Klasse CCube, die einen Würfel selbständig zeichnet und rotiert. In der Datei main.cpp gibt es einige Veränderungen gegenüber den bisherigen Beispielen, da wir mit einem Tiefenbuffer (z-Buffer) arbeiten und eine perspektivische Projektion verwenden.
Der Tiefenpuffer funktioniert so: Für jeden Bildpunkt (Pixel) unseres Ausgabefensters wird nicht nur die Farbe gespeichert, sondern auch der Abstand von der Kamera. Wird ein Pixel neu gezeichnet, prüft die Hardware, ob der neue Pixel vor, auf oder hinter einem an dieser Stelle davor gezeichneten Pixel liegt. Liegt unser neuer Bildpunkt hinter einem schon gezeichneten, wir er übergangen.
Eine Alternative zum Tiefenpuffer ist der sogenannte Painter's Algorithm. Dabei werden alle Objekte vor dem Zeichnen sortiert. Objekte, die weiter hinten liegen, werden zuerst gezeichnet, Objekte weiter vorne anschließend darüber. Der Painter's Algorithm hat Probleme mit Objekten, die sich durchschneiden, ermöglicht aber das korrekte Darstellen von transparenten Objekten.
main.cpp
In der
Weiter unten schalten wir den Tiefentest an, damit der Tiefenpuffer auch verwendet wird:
Zusätzlich zum display- und idle-Callback verwenden wir in diesem Beispiel auch die Tastatureingaben. Durch die Zeile
wird unsere Funktion
in den Vollbildmodus schalten und kein Button zum Schließen des Fensters mehr angezeigt wird.
Sehen wir uns noch an, wie die perspektivische
Transformation in der
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 4.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble aspect = (GLdouble)width / (GLdouble)height;
gluPerspective(53,
aspect,
0.001, 10.0);
}
Der Funktion wird die aktuelle Breite und Höhe
unseres Fensters in den Parametern
Die Funktion
Danach setzen wir die Kameraposition mit
Für die Kameratransformation arbeiten wir mit Welt- bzw. Objektkoordinaten (also mit der Modelview-Matrix), da sowohl unsere Objekte als auch die Kamera zusammen in diesem Koordinatensystem existieren.
Jetzt fehlt uns noch der Öffnungswinkel der
Kamera, bzw. die Eigenschaften der Kameralinse. Diese setzen wir (in
der Projektionsmatrix) über die Funtkion
Durch nahe und ferne Begrenzungsebenen (near and far plane) wird der minimale und maximale Abstand festgelegt, den zu zeichnende Pixelvon der Kamera haben dürfen. Beide Werte müssen positiv sein. Warum das Ganze?
a) Um die perspektivische Transformation eines Vektors zu erhalten, muss an einer bestimmten Stelle durch seine z-Koordinate geteilt werden. Wäre z Null, läge der Vektor also genau auf oder über der Kamera, müsste der Punkt ins unendliche transformiert werden. Das ist unmöglich. Wäre z kleiner als Null, ergäbe die Transformation einen gespiegelten (x,y)-Wert und Objekte hinter der Kamera würden sichtbar. Aus beiden Gründen besteht die Notwendigkeit für eine nahe, positive Begrenzungsebene.
b) Der Tiefenpuffer hat eine endliche Genauigkeit. Durch die Begrenzung der Gemoetrie auf einen weitesten Abstand von der Kamera kann der Tiefenpuffer in höherer Genauigkeit genutzt werden. Als Faustregel gilt für beide Werte also: Sie sollten so nah wie möglich an den wahren Objektgrenzen unserer Szene liegen.
CCube
Sehen wir uns die Datei cube.h genauer an. Die Klasse für unseren Würfel besitzt drei geschützte Attribute, die nur intern vom Würfel selbst angesprochen werden können:
Von Außen kann durch die öffentliche Funktion
indirekt auf den Rotationsparameter zugegriffen werden.
Die
Die Implementierung der
Die
Viel Spaß bei eigenen Formen...