[gelöst] Probleme mit OpenGL Blending

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

[gelöst] Probleme mit OpenGL Blending

Beitrag von BeRsErKeR »

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

Code: Alles auswählen

glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glRect(/*ganze Map*/);
3. Der Bereich um den Spieler wird wieder opaque gemacht (zur Einfachheit ein rechteckiger Bereich)

Code: Alles auswählen

glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFunc(GL_ONE, GL_ONE);
glRect(/*Bereich um Spieler*/);
4. Eine schwarze Fläche wird drüber gemalt in Abhängigkeit vom Alpha-Kanal

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;
Mit der eingestellten Farbe (Source) sollte also daher folgendes entstehen.

Code: Alles auswählen

Rn = Rz * 1;
Gn = Gz * 1;
Bn = Bz * 1;
An = Az * 0;
Was wiederum zu folgendem führt:

Code: Alles auswählen

Rn = Rz;
Gn = Gz;
Bn = Bz;
An = 0;
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):

Code: Alles auswählen

glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFunc(GL_ONE, GL_ONE_MINUS_DST_ALPHA);
glRect(/*ganze Map*/);
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:

Code: Alles auswählen

Rn = Rz * Az + Rq;
Gn = Gz * Az + Gq;
Bn = Bz * Az + Bq;
An = Az * Az + Aq;
Das heißt mit der Farbe 0.0f, 0.0f, 0.0f, 1.0f führt dies zu:

Code: Alles auswählen

Rn = Rz * Az + 0;
Gn = Gz * Az + 0;
Bn = Bz * Az + 0;
An = Az * Az + 1;
Also mit einem Az von 0 (was ich erwarte):

Code: Alles auswählen

Rn = Rz * 0;
Gn = Gz * 0;
Bn = Bz * 0;
An = 0 * 0 + 1;
Erwarten würde ich also am Ende:

Code: Alles auswählen

Rn = 0;
Gn = 0;
Bn = 0;
An = 1;
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]
Ohne Input kein Output.
Antworten