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:
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.
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.
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); //OperationBeim 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_KEEP | Der Wert im Stencil Buffer wird behalten |
GL_ZERO | Stencil Wert im Buffer auf 0 setzen |
GL_REPLACE | Mit dem Referenzwert ref ersetzen |
GL_INCR | Wert erhöhen |
GL_DECR | Wert verringern |
GL_INVERT | Bitweise 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..