[gelöst] Probleme mit OpenGL Blending
Verfasst: 06.12.2010, 15:08
Hallo ich versuche gerade einen FOW (Fog of War) zu realisieren. Dabei möchte ich zunächst etwas recht simples realisieren:
Alles ist schwarz und nur ein kleiner Bereich um den Spieler ist sichtbar.
Mein Vorgehen:
1. Die Map wird normal gezeichnet (DestAlpha ist am Ende 1.0)
2. Der Alpha-Kanal wird komplett auf 0 gebracht
3. Der Bereich um den Spieler wird wieder opaque gemacht (zur Einfachheit ein rechteckiger Bereich)
4. Eine schwarze Fläche wird drüber gemalt in Abhängigkeit vom Alpha-Kanal
Ob dieses Vorgehen nun vorteilhaft ist, sei einmal dahin gestellt. Ich frage mich nur warum das ganze nicht funktioniert.
Dazu meine Überlegungen:
zu 2.) glBlendFunc(GL_DST_COLOR, GL_ZERO); produziert ja ein multiplikatives Blending. Also etwa so:
Mit der eingestellten Farbe (Source) sollte also daher folgendes entstehen.
Was wiederum zu folgendem führt:
Demzufolge sollte ich die selbe Farbe wie vorher erhalten, nur dass der Alpha-Kanal auf 0 (transparent) ist.
Doch schon dieser Schritt funktioniert nicht. Wenn ich hier nun z.B. gleich Schritt 4 anwende, bleibt die Map so wie vorher. Sprich nicht-tranparent. Nutze ich aber stattdessen den folgenden Code erhalte ich das gewünschte Ergebnis (einen schwarzen Bereich):
Der Alpha-Kanal scheint also nicht 0 zu sein, sondern 1. Die Frage ist nun, warum ist das so? Habe ich einfach einen Denkfehler drin? Zwischen den Aufrufen passiert nichts anderes und es handelt sich außerdem um ein Single-Threaded-Programm.
Ich wäre für Hinweise dankbar. Manchmal sieht man den Wald vor lauter Bäumen nicht.
Nachtrag: Dazu noch die Überlegung für Schritt 4:
glBlendFunc(GL_ONE, GL_DST_ALPHA); produziert:
Das heißt mit der Farbe 0.0f, 0.0f, 0.0f, 1.0f führt dies zu:
Also mit einem Az von 0 (was ich erwarte):
Erwarten würde ich also am Ende:
Was ja irgendwie schwarz entspricht. Dies kommt aber nur zustande wenn ich glBlendFunc(GL_ONE, GL_ONE_MINUS_DST_ALPHA); verwende, also den invertierten Ziel-Alpha-Wert.
Ok hab den Fehler selbst gefunden. Das Blending war korrekt und somit auch meine Überlegungen. Allerdings war der AlphaTest aktiv, welcher dadurch die Draw-Operationen mit voller Transparenz gar nicht erst an die Pipe geschickt hat. Dummer Fehler ... :| [/b]
Alles ist schwarz und nur ein kleiner Bereich um den Spieler ist sichtbar.
Mein Vorgehen:
1. Die Map wird normal gezeichnet (DestAlpha ist am Ende 1.0)
2. Der Alpha-Kanal wird komplett auf 0 gebracht
Code: Alles auswählen
glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glRect(/*ganze Map*/);
Code: Alles auswählen
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFunc(GL_ONE, GL_ONE);
glRect(/*Bereich um Spieler*/);
Code: Alles auswählen
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFunc(GL_ONE, GL_DST_ALPHA);
glRect(/*ganze Map*/);
Ob dieses Vorgehen nun vorteilhaft ist, sei einmal dahin gestellt. Ich frage mich nur warum das ganze nicht funktioniert.
Dazu meine Überlegungen:
zu 2.) glBlendFunc(GL_DST_COLOR, GL_ZERO); produziert ja ein multiplikatives Blending. Also etwa so:
Code: Alles auswählen
Rn = Rz * Rq;
Gn = Gz * Gq;
Bn = Bz * Bq;
An = Az * Aq;
Code: Alles auswählen
Rn = Rz * 1;
Gn = Gz * 1;
Bn = Bz * 1;
An = Az * 0;
Code: Alles auswählen
Rn = Rz;
Gn = Gz;
Bn = Bz;
An = 0;
Doch schon dieser Schritt funktioniert nicht. Wenn ich hier nun z.B. gleich Schritt 4 anwende, bleibt die Map so wie vorher. Sprich nicht-tranparent. Nutze ich aber stattdessen den folgenden Code erhalte ich das gewünschte Ergebnis (einen schwarzen Bereich):
Code: Alles auswählen
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFunc(GL_ONE, GL_ONE_MINUS_DST_ALPHA);
glRect(/*ganze Map*/);
Ich wäre für Hinweise dankbar. Manchmal sieht man den Wald vor lauter Bäumen nicht.
Nachtrag: Dazu noch die Überlegung für Schritt 4:
glBlendFunc(GL_ONE, GL_DST_ALPHA); produziert:
Code: Alles auswählen
Rn = Rz * Az + Rq;
Gn = Gz * Az + Gq;
Bn = Bz * Az + Bq;
An = Az * Az + Aq;
Code: Alles auswählen
Rn = Rz * Az + 0;
Gn = Gz * Az + 0;
Bn = Bz * Az + 0;
An = Az * Az + 1;
Code: Alles auswählen
Rn = Rz * 0;
Gn = Gz * 0;
Bn = Bz * 0;
An = 0 * 0 + 1;
Code: Alles auswählen
Rn = 0;
Gn = 0;
Bn = 0;
An = 1;
Ok hab den Fehler selbst gefunden. Das Blending war korrekt und somit auch meine Überlegungen. Allerdings war der AlphaTest aktiv, welcher dadurch die Draw-Operationen mit voller Transparenz gar nicht erst an die Pipe geschickt hat. Dummer Fehler ... :| [/b]