Double-Buffering und vor allem die korrekte Darstellung bei überlappenden und einander verdeckenden Objekten.
Platformen:
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: tutorial02.cpp
Paket: tutorial02.tgz
Linux:
Windows/Cygwin:
Dieses Demo zeigt im Weselntlichen drei Dinge: Tiefentests (überlappende Objekte), double-buffering und wie man die Seitenverhältnisse bewahren kann auch wenn die Grösse des Fensters ändert. Obwohl dieses Demo noch keine Animationen enthält kann das double-buffering gezeigt werden und auch Vorteile bringen. So wird bei einer komplexen Szene das gesamte Rendering im Hintergrund erledigt und dann alles auf einmal gezeigt. Würde man hier kein double-buffering verwenden könnte man die Szene förmlich entstehen sehen.
Gezeigt wird ein kleines Fenster das vier übereinanderlappende Dreiecke beinhaltet.
Dieses Program ist im wesentlichen gleich dem Tutorial 1. Die kleinen Unterschiede werden hier jedoch erklärt.
Sobald wir Tiefentests wünschen, müssen wir nicht nur die Farbe löschen, sondern auch die Tiefeninformation. Erreicht wird dies durch die zusätzliche Angabe von GL_DEPTH_BUFFER_BIT
.
Die Polygon-Füll-Definitionen sind gleich, ebenso die Beobachtertransformation.
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
glLoadIdentity();
gluLookAt(
0.0, 0.0, 6.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
An Stelle von Striche und Kugeln, zeichnen wir nun Dreiecke. Eine kleine Zugabe: jede Ecke eines Dreiecks hat eine andere Farbe. Den schon oben gezeigten Farbverlauf übernimmt OpenGL, dazu aber weiter unten.
glBegin(GL_TRIANGLES);
// triangle 1
glColor4f(1.0, 0.0, 0.0, 1.0); glVertex3f(-2.0, -1.0, 0.5);
glColor4f(0.0, 1.0, 0.0, 1.0); glVertex3f( 2.0, -1.5, -0.5);
glColor4f(0.0, 0.0, 1.0, 1.0); glVertex3f( 2.0, -0.5, -0.5);
// triangle 2
glColor4f(1.0, 0.0, 0.0, 1.0); glVertex3f( 1.0, -2.0, 0.5);
glColor4f(0.0, 1.0, 0.0, 1.0); glVertex3f( 1.5, 2.0, -0.5);
glColor4f(0.0, 0.0, 1.0, 1.0); glVertex3f( 0.5, 2.0, -0.5);
// triangle 3
glColor4f(1.0, 0.0, 0.0, 1.0); glVertex3f( 2.0, 1.0, 0.5);
glColor4f(0.0, 1.0, 0.0, 1.0); glVertex3f(-2.0, 1.5, -0.5);
glColor4f(0.0, 0.0, 1.0, 1.0); glVertex3f(-2.0, 0.5, -0.5);
// triangle 4
glColor4f(1.0, 0.0, 0.0, 1.0); glVertex3f(-1.0, 2.0, 0.5);
glColor4f(0.0, 1.0, 0.0, 1.0); glVertex3f(-1.5, -2.0, -0.5);
glColor4f(0.0, 0.0, 1.0, 1.0); glVertex3f(-0.5, -2.0, -0.5);
glEnd();
Der kleine Unterschied zu Tutorial 1 ist das double-buffering. Wir müssen nun nach dem glFlush
die Buffer tauschen mit glutSwapBuffers
. Das ist praktisch schon die ganze Hexerei.
Da wir trotz des sich verändernden Fensters die Seitenverhältnisse behalten wollen, kopieren wir den Code aus der Funktion main in eine eigene Funktion reshape. Ausser dem viewport und der Berechnung des aspect ratio: (GLfloat)w/(GLfloat)h
bleibt sich alles gleich.
void reshape(int w, int h)
{
// define viewport
glViewport(0, 0, w, h);
// configuration of projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
// configuration of model view matrix
glMatrixMode(GL_MODELVIEW);
}
Die Funktion main ist im Wesentlichen gleich geblieben. Bitte die Zeile 57 beachten, in der wir einige Angaben zur Darstellung an GLUT übergeben. Nicht ganz unwichtig ist auch Zeile 62 in der wir unsere reshape
Funktion registrieren.
int main(int argc, char ** argv)
{
// general initialisation
glutInit(&argc, argv);
glutInitWindowSize(300, 300);
glutInitWindowPosition(0, 0);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
glutCreateWindow("OpenGL Demo 2");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
Bei der Konfiguration brauchen wir nur noch ein Bit zu setzen: GL_DEPTH_TEST
und schon ist OpenGL bereit die Objekte richtig darzustellen, ganz gleich in welcher Reihenfolge sie gezeichnet werden. Als kleinen Test könnten Sie die Zeile 66 auskommentieren und dann die Dreiecke vergleichen.