13 Tests vor der Ausgabe

Jede Zeichenoperation löst in OpenGL eine ganze Reihe von Operationen aus. Es wird rotiert, verschoben, projiziert, Lichteinfall berechnet, etc.

Schließlich wird jedes ‘Fragment’ noch einigen Tests unterzogen, bevor es tatsächlich als Pixel in den Colorbuffer aus-gegeben wird. Ein sehr üblicher Test ist z.B. der Z-Buffer Test, um die Sichtbarkeit zu überprüfen. Es gibt aber noch eine ganze Reihe anderer Tests die in folgender Reihenfolge durchgeführt werden:

13.1 Scissor Test

Man kann rechteckige Bereiche im Ausgabefenster definieren, in denen nicht gezeichnet werden darf. Liegt ein Fragment innerhalb eines solchen Bereichs, wird es verworfen.

Der Befehl um einen solchen Bereich zu definieren:

void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
Eigentlich ist der Scissor Test (Scissor = Schere) nur eine Abwandlung des Stencil Tests. Es ist aber einfacher Rechtek-kige Bereiche zu Testen, als eine beliebige Bitmaske. Darum ist der Scissor Test wesentlich schneller als die Verwen-dung des Stencil Buffers. Stencil Tests werden oft von Hardware unterstützt.

13.2 Alpha Test

Der Alpha Test dient dazu, ein Fragment in Abhängigkeit von seinem Alphawert zu verwerfen oder nicht. Wenn der Alpha Test eingeschaltet ist, wird der Alpha Wert jedes Fragments mit einem Referenzwert nach einer bestimmten Funktion verglichen. Die Befehle dazu:

glEnable (GL_ALPHA_TEST);			// Test einschalten

glAlphaFunc(GLenum func, GLfloat ref);	// Testfunktion festlegen

func kann folgende Werte annehmen:

Die Vergleichsfunktion bezieht sich auf den in ref übergebenen Wert.

Der Alpha Test wird oft dazu verwendet, um Texturen mit Löchern zu verwenden. (z.B. für Bäume) In diesem Fall muß die Textur vom Typ rgba sein, und an stellen wo die Textur ein Loch haben soll, werden die a Werte auf 0 gesetzt. Dann setzt man glAlphaFunc (GL_GREATER,0.0f); ab.

13.3 Stencil Test / Stencil Buffer

Der Stencil Buffer arbeitet als globale Maske, die das überschreiben von Pixeln im Colorbuffer verhindert. Eine typische Anwendung des Stencil Buffers wäre es für z.B. einen Flugsimulator, einmal am Anfang das Bild des Cockpits auszuge-ben, und dann die Maske des Cockpits in den Stencil buffer zu schreiben.

Nachdem noch die richtige Vergleichsoperation für den Stencil Buffer gesetzt ist, kann das Cockpit nicht mehr über-schrieben werden.

Die Befehle im Zusammenhang mit dem Stencil Buffer:

glEnable(GL_STENCIL_TEST);		// Test einschalten

glClearStencil(Gluint val);	// Löschwert für den Buffer festlegen
glClear(GL_STENCIL_BUFFER_BIT);	// Buffer tatsächlich Löschen

void glStencilFunc(GLenum func, GLint ref, Gluint mask);
                                //Vergleichsfunktion
void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);	//Operation
Beim Stencil Test wird der ref Wert mit dem Wert im Stencil Buffer verglichen, aber nur die Bits, die in mask auf 1 gesetzt sind. Man hat also 32 unabhängige Masken im Stencil Buffer zur Verfügung.

func kann folgende Werte annehmen

glStencilOp legt fest, was im Stencil Buffer passieren soll. Man kann die Operation für drei Fälle getrennt angeben: fail (der Stencil Test hat fehlgeschlagen), zfail (der Stencil Test paßt, der z-Test aber nicht) und zpass (der Stencil Test und der Z-Test gehen durch).

Zulässige Werte für fail, zfail und zpass:

fail, zfail, zpass Bedeutung
GL_KEEPDer Wert im Stencil Buffer wird behalten
GL_ZEROStencil Wert im Buffer auf 0 setzen
GL_REPLACEMit dem Referenzwert ref ersetzen
GL_INCRWert erhöhen
GL_DECRWert verringern
GL_INVERTBitweise negieren

Um also ein Polygon in den Stencil Buffer zu zeichnen, um es als Maske zu verwenden, kann man so vorgehen:

glEnable (GL_STENCIL_TEST);					// Test einschalten
glStencilFunc (GL_ALWAYS, 0x1, 0x1);			// Test immer durchlassen
glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE); 	// Wert im Buffer kopieren
..Maske zeichnen..
glStencilFunc (GL_EQUAL, 0x1, 0x1);			// Vergleichsoperation
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);		// Maske aber unverändert lassen
..ab nun Maskiert zeichnen..