Lektion 2
Im ersten Tutorial habe ich Ihnen beigebracht, wie man ein OpenGL-Fenster erzeugt. In diesem Tutorial bringe ich Ihnen bei, wie man Dreiecke und Quadrate zeichnet. Wir werden ein Dreieck mittels GL_TRIANGLES und ein Qudrat mittels GL_QUADS erzeugen.
Wir werden den Code aus dem ersten Tutorial benutzen und die DrawGLScene() Prozedur erweitern. Ich werde die komplette Prozedur neu schreiben. Wenn Sie die letzte Lektion erweitern wollen, können Sie die DrawGLScene() Prozedur mit dem unteren Code ersetzen oder einfach die fehlenden Zeilen einfügen.
int DrawGLScene(GLvoid) // Hier kommt der ganze Zeichnen-Kram hin
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Löscht den Bildschirm und den Depth-Buffer
glLoadIdentity(); // Resettet die Ansicht (View)
Wenn Sie glLoadIdentity() aufrufen, bewegen Sie sich zurück ins Zentrum des Bildschirms mit der X-Achse von links nach rechts und der Y-Achse von oben nach unten und der Z-Achse die in den Bildschirm rein und raus geht.
Das Zentrum eines OpenGL-Bilschirms ist 0.0f auf der X und Y-Achse. Links vom Zentrum ist der negative Zahlrenbereich. Rechts davon der positve. Bewegt man sich am Bildschirm nach oben, befindet man sich im positiven Zahlenbereich und wenn man sich nach unten bewegt im negativen. Bewegt man sich tiefer in den Bildschirm hinein bewegt man sich in den negativen Zahlenbereich und wenn man sich dem Betrachter nähert, in den positiven.
glTranslatef(x, y, z) bewegt sich entlang der X, Y und Z-Achse, in dieser Reihenfolge. Die untere Code-Zeile bewegt sich 1.5 Einheiten auf der X-Achse. Auf der Y-Achse wird sich überhaupt nicht bewegt (0.0) und 6.0 Einheiten in den Bildschirm hinein. Dabei bewegen Sie sich nicht vom Zentrum des Bildschirms aus, sondern von da aus, wo Sie sich gerade befinden.
glTranslatef(-1.5f,0.0f,-6.0f); // 1.5 Einheiten nach Links dann 6.0 Einheiten in den Bildschirm hinein
Nun, da wir uns auf die linke Hälfte des Bildschirms bewegt haben und wir die Ansicht tief genug in den Bildschirm (-6.0) gesetzt haben, so dass wir die gesamte Szene sehen können, erzeugen wir ein Dreieck. glBegin(GL_TRIANGLES) bedeutet, dass wir mit dem Zeichnen eines Dreiecks beginnen wollen und glEnd() teilt OpenGL mit, dass wir fertig mit dem Erzeugen des Dreiecks sind. Normalerweise, wenn Sie 3 Punkte haben, benutzen Sie GL_TRIANGLES. Dreiecke zu zeichnen ist auf den meisten Grafikkarten ziemlich schnell. Wenn Sie 4 Punkte haben, benutzen Sie GL_QUADS, um sich Ihr Leben zu erleichtern. Von dem, was ich gehört habe, rendern die meisten Videokarten Objekte sowieso als Dreiecke. Letztendlich, wenn Sie mehr als 4 Punkte haben, benutzen Sie GL_POLYGON.
In unserem einfachen Programm zeichnen wir nur ein Dreieck. Wenn wir ein zweites Dreieck zeichnen wollten, könnten wir 3 weitere Zeilen Code (3 Punkte) einfügen, direkt nach den ersten drei. Alle sechs Zeilen Code würden zwischen glBegin(GL_TRIANGLES) und glEnd() liegen. Es macht keinen Unterschied, wenn Sie ein glBegin(GL_TRIANGLES) und ein glEnd() um jede Gruppe von 3 Punkten setzen. Das gilt für Quadrate genauso. Wenn Sie wissen, dass Sie nur Quadrate zeichnen, können Sie die zweite Gruppe an 4 Punkten direkt hinter den ersten vier Zeilen einfügen. Ein Polygon (GL_POLYGON) kann allerdings aus vielen Punkten bestehen, so dass es kein Unterschied macht, wieviele Zeilen Sie zwischen glBegin(GL_POLYGON) und glEnd() haben.
Die erste Zeile hinter glBegin, setzt den ersten Punkt unseres Polygons. Die erste Zahl bei glVertex ist für die x-Achse, die zweite für die Y-Achse und die dritte für die Z-Achse. In der ersten Zeile, bewegen wir uns also nicht auf der X-Achse. Wir bewegen uns eine Einheit auf der Y-Achse und wir bewegen uns nicht auf der Z-Achse. Dadurch erhalten wir den obersten Punkt des Dreiecks. Das zweite glVertex bewegt eine Einheit nach links auf der X-Achse und eine Einheit auf der Y-Achse nach unten. Das ergibt den unteren linken Punkt des Dreiecks. Das dritte glVertex bewegt eine Einheit nach rechts und eine runter. Dadurch erhalten wir den unteren rechten Punkt des Dreiecks. glEnd() teilt OpenGL mit, dass keine weiteren Punkte folgen. Das gefüllte Dreieck wird dargestellt.
glBegin(GL_TRIANGLES); // Zeichne Dreiecke
glVertex3f( 0.0f, 1.0f, 0.0f); // Oben
glVertex3f(-1.0f,-1.0f, 0.0f); // Unten Links
glVertex3f( 1.0f,-1.0f, 0.0f); // Unten Rechts
glEnd(); // Fertig gezeichnet
Nun, da wir das Dreieck auf der linken Seite des Bildschirms angezeigt haben, müssen wir uns auf die rechte Seite bewegen, um das Quadrat anzuzeigen. Um das zu machen, benutzen wir erneut glTranslate. Diesmal müssen wir uns nach rechts bewegen, weswegen X ein positiver Wert sein muss. Da wir uns schon 1.5 Einheiten nach links bewegt haben; um ins Zentrum zu gelangen, müssen wir uns nun 1.5 Einheiten nach rechts bewegen. Nachdem wir das Zentrum erreicht haben, bewegen wir uns weitere 1.5 Einheiten nach rechts. Insgesamt bewegen wir uns also 3.0 Einheiten nach rechts.
glTranslatef(3.0f,0.0f,0.0f); // Bewege 3 Einheiten nach rechts
Nun erzeugen wir das Quadrat. Wir machen das, indem wir GL_QUADS benutzen. Ein Quad ist prinzipiell ein 4-seitiges Polygon. Perfekt, um ein Quadrat zu machen. Der Code, um das Quadrat zu machen, ist sehr ähnlich dem Code, den wir für das Dreieck verwendet haben. Der einzige Unterschied ist, dass wir GL_QUADS statt GL_TRIANGLES benutzen und ein extra glVertex3f für den 4ten Punkt des Quadrats. Wir zeichnen das Quadrat oben links, oben rechts, unten rechts, unten links (Uhrzeigersinn). Dadurch, dass wir das Quadrat im Uhrzeigersinn zeichnen, wird das Quadrat als hintere Seite gezeichnet. Das bedeutet, dass die Seite des Quad, die wir sehen, eigentlich die hintere Seite ist. Objekte die gegen den Uhrzeigersinn gezeichnet werden, sind uns zugewendet. Zur Zeit ist das nicht wichtig, aber für später müssen wir das wissen.
glBegin(GL_QUADS); // Zeichne eine Quadrat
glVertex3f(-1.0f, 1.0f, 0.0f); // Oben Links
glVertex3f( 1.0f, 1.0f, 0.0f); // Oben Rechts
glVertex3f( 1.0f,-1.0f, 0.0f); // Unten Rechts
glVertex3f(-1.0f,-1.0f, 0.0f); // Unten Links
glEnd(); // Fertig mit Quadrat zeichnen
return TRUE; // Weiter geht's
}
Zu guter letzt ändern Sie den Code um zwischen Fenster- und Fullscreen-Modus zu wechseln, so dass der Titel des Fensters korrekt ist.
if (keys[VK_F1]) // Wurde F1 gedrückt?
{
keys[VK_F1]=FALSE; // Wenn ja, setze Taste auf FALSE
KillGLWindow(); // Kill unser aktuelles Fenster
fullscreen=!fullscreen; // Wechsel zwischen Fullscreen und Fenster-Modus
// Erzeuge unser OpenGL-Fenster neu ( Modifiziert )
if (!CreateGLWindow("NeHe's First Polygon Tutorial",640,480,16,fullscreen))
{
return 0; // Beenden, wenn das Fenster nicht erzeugt wurde
}
}
Markus Knauer fügt hinzu: In dem Buch ("OpenGL Programming Guide: The Official Guide to Learning OpenGL, Release 1", J. Neider, T. Davis, M. Woo, Addison-Wesley, 1993) erklärt folgender Paragraph genau, was NeHe meint, wenn er die Bewegung von Einheiten in OpenGL anspricht:
"[Ich erwähnte] Inches und Millimeter - haben diese irgend etwas mit OpenGL zu tun? Die Antwort, in einem Wort, ist nein. Die Projektion und andere Transformationen sind Einheitenlos. Wenn Sie wollen, können Sie sich die nahe und ferne Clipping-Ebene in der Entfernung 1.0 und 20.0 Meter, Inches, Kilometers oder Ligen vorstellen, das liegt ganz an Ihnen. Die einzige Regel ist, dass Sie eine konsistente Einheit als Maß nehmen."
In diesem Tutorial habe ich so detailiert wie möglich versucht zu erklären, welche Schritte notwendig sind, um Polygone und Quadrate auf den Bildschirm mittels OpenGL zu zeichnen. Wenn Sie Anmerkungen oder Fragen haben, schreiben Sie mir bitte eine E-Mail. Wenn Sie denken, ich habe etwas nicht korrekt kommentiert oder der Code könnte an einigen Stellen besser gemacht werden, lassen Sie es micht wissen. Ich möchte das beste OpenGL Tutorial machen. Ich bin an Ihrem Feedback interessiert.
Jeff Molofee (NeHe)
* DOWNLOAD Visual C++ Code For This Lesson.
* DOWNLOAD ASM Code für diese Lektion. ( Conversion by Foolman )
* DOWNLOAD Borland C++ Builder 6 Code für diese Lektion. ( Conversion by Christian Kindahl )
* DOWNLOAD BeOS Code für diese Lektion. ( Conversion by Rene Manqueros )
* DOWNLOAD C# Code für diese Lektion. ( Conversion by Joachim Rohde )
* DOWNLOAD VB.Net CsGL Code für diese Lektion. ( Conversion by X )
* DOWNLOAD Code Warrior 5.3 Code für diese Lektion. ( Conversion by Scott Lupton )
* DOWNLOAD Cygwin Code für diese Lektion. ( Conversion by Stephan Ferraro )
* DOWNLOAD D Language Code für diese Lektion. ( Conversion by Familia Pineda Garcia )
* DOWNLOAD Delphi Code für diese Lektion. ( Conversion by Michal Tucek )
* DOWNLOAD Dev C++ Code für diese Lektion. ( Conversion by Dan )
* DOWNLOAD Game GLUT Code für diese Lektion. ( Conversion by Milikas Anastasios )
* DOWNLOAD GLUT Code für diese Lektion. ( Conversion by Andy Restad )
* DOWNLOAD Irix Code für diese Lektion. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Java Code für diese Lektion. ( Conversion by Jeff Kirby )
* DOWNLOAD Java/SWT Code für diese Lektion. ( Conversion by Victor Gonzalez )
* DOWNLOAD Jedi-SDL Code für diese Lektion. ( Conversion by Dominique Louis )
* DOWNLOAD JoGL Code für diese Lektion. ( Conversion by Kevin J. Duling )
* DOWNLOAD LCC Win32 Code für diese Lektion. ( Conversion by Robert Wishlaw )
* DOWNLOAD Linux Code für diese Lektion. ( Conversion by Richard Campbell )
* DOWNLOAD Linux/GLX Code für diese Lektion. ( Conversion by Mihael Vrbanec )
* DOWNLOAD Linux/SDL Code für diese Lektion. ( Conversion by Ti Leggett )
* DOWNLOAD LWJGL Code für diese Lektion. ( Conversion by Mark Bernard )
* DOWNLOAD Mac OS Code für diese Lektion. ( Conversion by Anthony Parker )
* DOWNLOAD Mac OS X/Cocoa Code für diese Lektion. ( Conversion by Bryan Blackburn )
* DOWNLOAD MASM Code für diese Lektion. ( Conversion by Nico (Scalp) )
* DOWNLOAD Power Basic Code für diese Lektion. ( Conversion by Angus Law )
* DOWNLOAD Pelles C Code für diese Lektion. ( Conversion by Pelle Orinius )
* DOWNLOAD Perl Code für diese Lektion. ( Conversion by Cora Hussey )
* DOWNLOAD Python Code für diese Lektion. ( Conversion by Travis Wells )
* DOWNLOAD QT/C++ Code für diese Lektion. ( Conversion by Popeanga Marian )
* DOWNLOAD REALbasic Code für diese Lektion. ( Conversion by Thomas J. Cunningham )
* DOWNLOAD Ruby Code für diese Lektion. ( Conversion by Ben Goodspeed )
* DOWNLOAD Scheme Code für diese Lektion. ( Conversion by Jon DuBois )
* DOWNLOAD Solaris Code für diese Lektion. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Visual Basic Code für diese Lektion. ( Conversion by Ross Dawson )
* DOWNLOAD Visual Fortran Code für diese Lektion. ( Conversion by Jean-Philippe Perois )
* DOWNLOAD Visual Studio .NET Code für diese Lektion. ( Conversion by Grant James )
Deutsche Übersetzung: Joachim Rohde
Der original Text ist hier zu finden.
Die original OpenGL Tutorials stammen von NeHe's Seite.