mario::konrad
programming / C++ / sailing / nerd stuff
OpenGL: Tutorial 1 - Einführung / einfache Geometrie
© 2004 / Mario Konrad

Beschreibung

In diesem Tutorial geht es um einfache Initialisierung, öffnen eines Fensters und Zeichen einer einfachen Geometrie. Es soll einen Einstieg in die Basics von OpenGL (inkl. GLU und GLUT) geben ohne grossen Schnick-Schnack.

Platformen:

Download

Die auf dieser Seite aufgeführten Sourcecodes dürfen uneingeschränkt verwendet, kopiert, verändert und publiziert werden. Jegliche Haftung wird abgelehnt, die Verwendung des hier publizierten Materials geschieht auf eigenes Risiko.

Source: tutorial01.cpp

Paket: tutorial01.tgz

Build und Start

Linux:

$ tar -xzf tutorial01.tgz
$ cd tutorial01
$ make -f Makefile.linux
$ ./tutorial01

Windows/Cygwin:

$ tar -xzf tutorial01.tgz
$ cd tutorial01
$ make -f Makefile.cygwin
$ ./tutorial01

Das Demo

Dieses sehr rudimentäre Demo zeigt wie ein einfaches Fentster geöffnet und einfache Objekte (Primitive wie auch komplexere Objekte) gezeichnet werden können. Dieses Demo hat nicht zum Ziel eine fertige Animation oder höhere Funktionen der OpenGL zu zeigen. Es soll lediglich ein erster Einstieg gezeigt werden.

Das Demo beinhaltet im Wesentlichen ein kleines Fenster, in dem zwei Striche, zwei Dreiecke und eine Kugel gezeichnet werden. Eine perspektivische Projektion und die Platzierung des Beobachters (Kamera) im dreidimensionalen Raum sind auch enthalten.

Das Programm

Zuerst brauchen wir ein paar header files: gl.h (OpenGL), glu.h (OpenGL Utility) und glut.h (OpenGL Utility Toolkit).

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

Die Funktion display (bitte die Signatur beachten) ist zuständig für das Zeichnen.

void display(void)
{

Als Erstes müssen wir die Farbinfromationen löschen. Dazu benutzen wir die Funktion glClear. Als Parameter können wir spezifizieren, welcher Buffer gelöscht werden soll. In unserm Fall: GL_COLOR_BUFFER_BIT:

    glClear(GL_COLOR_BUFFER_BIT);

Da wir vorhaben Polygone zu zeichnen, definieren wir die Art wie und ob sie gefüllt werden. Flächen die wir von vorne sehen werden gefüllt, Flächen, die wie von hinten sehen werden als Striche gezeichnet:

    glPolygonMode(GL_FRONT, GL_FILL);
    glPolygonMode(GL_BACK, GL_LINE);

Nun müssen wir den Beobachter setzen. Einfachheitshalber verwenden wir die Funktion gluLookAt. Natürlich könnten wir diese Transformation auch selbst Durchfüren, so ist es jedoch anschaulicher.

gluLookAt erwartet als Parameter drei Vektoren:

    glLoadIdentity();
    gluLookAt(
            0.0, 10.0, 10.0,
            0.0,  0.0,  0.0,
            0.0,  1.0,  0.0);

Definieren wir nun die Farbe. Wir wollen weisse Striche, also einen Farbvektor von (1.0, 1.0, 1.0, 1.0), dieser ist definiert als RGBA (rot,grün,gelb,alpha), jeweils im abgeschlossenen Interval von [0,1].

    glColor4f(1.0, 1.0, 1.0, 1.0);

Zunächst zeichnen wir zwei Linien. Diese sind definiert durch zwei Vektoren (Geometrieinformation). Damit OpenGL weiss was mit den folgenden Geometrieinformationen zu tun ist, müssen wir ihr es mitteilen. Wir verwenden die Funktion glBegin und dem Parameter GL_LINES. OpenGL wird jetzt Linien zeichenen, immer definiert durch zwei Vektoren. Geben wir vier Vektoren an, so werden zwei Linien gezeichnet:

    glBegin(GL_LINES);
            glVertex3f(0.0, 0.0, 0.0);
            glVertex3f(1.0, 0.0, 0.0);
            glVertex3f(0.0, 0.0, 0.0);
            glVertex3f(0.0, 0.0, 1.0);
    glEnd();

Als nästes wollen wir zwei Dreiecke zeichnen. Um dessen Koordinaten nicht selbst veschieben zu müssen, verändern wir einfach die Modellmatrix, entsprechend mit einer Translation:

    glTranslatef(0.0, 0.0, 2.0);

Nun können wir analog zu oben Dreiecke zeichnen. Zu beachten ist, dass das erste Dreieck im Gegenuhrzeigersinn gezeichnet ist (Front nach +z), das zweite Dreieck jedoch im Uhrzeigersinn (Front nach -z):

    glBegin(GL_TRIANGLES);
            glVertex3f( 0.0, 0.0, 0.0);
            glVertex3f( 1.0, 1.0, 0.0);
            glVertex3f(-1.0, 1.0, 0.0);
            glVertex3f( 0.0,  0.0, 0.0);
            glVertex3f( 1.0, -1.0, 0.0);
            glVertex3f(-1.0, -1.0, 0.0);
    glEnd();

Wieder verschieben wir die Modellmatrix und machen uns das Toolkit zu Nutze, indem wir eine Kugel zeichnen.

    glTranslatef(0.0, 0.0, -7.0);
    glutWireSphere(1.0, 16, 16);

Jetzt veranlassen wir OpenGL wirklich alles auszuführen und sind dann schon fertig mit dem Zeichnen.

    glFlush();
}

Was bis jetzt elegant verschwiegen blieb ist die ganze Initialisierung. Diese führen wir in der Hauptfunktion main durch:

int main(int argc, char ** argv)
{

Zuerst die Initialisierung überhaupt:

    glutInit(&argc, argv);

Der nächste Schritt ist ein Fenter zu öffnen mit einem definierten Titel, Grösse und Position:

    glutInitWindowSize(300, 300);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("OpenGL Demo 1");

Damit überhaupt was gezeichnet wird müssen wir der GLUT unsere obige Funktion dispaly bekanntmachen:

    glutDisplayFunc(display);

Sobald der Inhalt des Fensters gelöscht wird, soll er mit der folgenden Farbe (schwarz) gefüllt werden:

    glClearColor(0.0, 0.0, 0.0, 0.0);

Weit entfernte Objekte sollen kleiner dargestellt werden als näher liegende. Um dies zu erreichen müssen wir die Projektionsmatrix entsprechend definieren. Dazu wählen wir folgende Daten:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, 1.0, 1.0, 100.0);

Alle weiteren Transformationen sollen in die Modellmatrix einfliessen:

    glMatrixMode(GL_MODELVIEW);

Es werde Licht, bzw. gezeichnet:

    glutMainLoop();

Schon ist das Demo zu Ende.

    return 0;
}

Dies ist natürlich nur ein ganz rudimentäres Demo der möglichkeiten von OpenGL. Um weitere Möglichkeiten zu zeigen sind die andern Demos, bzw. entsprechende Quellen auf dem Netz zuständig.