GLSL font rendering OpenGL 3.x

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

GLSL font rendering OpenGL 3.x

Beitrag von snoob741 »

Aktuell habe ich meinen FreeType basierten Font-Renderer von OpenGL 2.x auf OpenGL 3.x+ umgestellt.
Klappt nun nach einigem hin und her auch, dennoch habe ich eine Frage bzgl. dem Fragment shader:

Bisher habe ich unter OpenGL 2.x im GLSL fragment shader folgenden Befehl verwendet um meine Fonts
zu rendern:

Code: Alles auswählen

uniform sampler2D DiffuseMap;  // Reference to sprite texture sampler

varying vec4 vColor;      //This is the color from the vertex shader interpolated across the geometry per fragment.	
varying vec2 vTexCoord0;  //This is the texture coordinate from vertex shader 

gl_FragColor = vec4(vColor.rgb, texture2D(DiffuseMap, vTexCoord0).a);
Damit habe ich das beste Ergebnis erziehlt. Die Schrift sieht gestochen scharf aus, auch beim Blending, wenn die
Schrift 3D-Objekte überlagert. Hier einmal ein Screenshot:

Bild

Mit diesem Befehl bekomme ich jedoch das Font Rendering nicht unter OpenGL 3.x lauffähig. Anstelle der Schrift,
werden hier nur die Sprites für die einzelnen Zeichen gerendert. Meine Vermutung geht daher, dass hier etwas mit
dem Alpha-Mapping nicht funktioniert.

Stelle ich den Befehl auf folgenden Befehl um:

Code: Alles auswählen

   vec4 vTexColor = texture2D(DiffuseMap, vTexCoord0.st);
	 gl_FragColor = (vTexColor.r, vTexColor.r, vTexColor.r, vTexColor.r)*vColor;
Dann bekomme ich das Font-Rendering unter OpenGL 2.x und OpenGL 3.x lauffähig. Allerdings mit Einbußen in der
Qualität, die Schrift wirkt nun beim Blending nicht mehr so scharf:

Bild

Dieses Ergebnis habe sowohl unter OpenGL 2.x als auch 3.x. Als Blending Values verwende ich:
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_FUNC_ADD.

Kann mir jemand erklären warum der "alte" Befehl nicht mehr funktioniert und sieht jemand evtl. eine Möglichkeit, die
Qualität hoch zu schrauben?
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: GLSL font rendering OpenGL 3.x

Beitrag von Artificial Mind »

Gibt bei OpenGL leider viel zu viele mögliche Probleme.

Ok was mir erstmal direkt ins Auge springt: texture2D ist veraltet, nimm einfach texture(...), der kann das anhand des Samplers rausfinden.

Ich würde das so machen:
glBlend(GL_ENABLE);
glBlendFunc(<dein setup>);
<shader, texturen, uniforms binden>
<vao zeichnen>

Einige häufig gemachte Fehler die potentiell deinen Fehler erklären könnten:
Sampler2D aber TEXTURE_RECTANGLE bzw. SamplerRect aber TEXTURE_2D
TEXTURE_2D mit Filtering das Miplevels hat (also zB. GL_LINEAR_MIPMAP_LINEAR) aber nur die unterste Stufe hat Daten (=> wird meist alles schwarz gerendert)
Falsche/keine Textur gebunden
Falsches internal format (das kein Alpha hat)
Texturkoordinaten negativ aber kein GL_REPEAT/MIRROR

Ansonsten sollte dein Code funktionieren. In OGL 3 hätte ich dann also einfach varying -> in/out umbenannt, texture2D -> texture.
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: GLSL font rendering OpenGL 3.x

Beitrag von snoob741 »

Danke ersteinmal für Deine Tipps. Ich habe im Shader texture2D gegen texture ausgetauscht, bringt jedoch keinen Unterschied im Resultat. Reihenfolge Blending und Befehle müsste korrekt sein, auch die Formate, so benutze ich z.B. in GL3 statt GL_LUMINANCE_ALPHA das neue GL_RG. Zum Abgleich habe ich mal die APITrace logs mit den GL Calls angefügt. Ich denke, sie sollten so korrekt sein (mal abgesehen von teilweise redundanten Aufrufen, die ich noch entfernen muss). Zudem sind sie gleich in der Aufruffolge, daher verstehe ich nicht, warum das erste snipped nicht läuft und nur ein rotes Quad gerendert wird.

Ich habe auch mal probiert ob das Blending greift, indem ich den Alphawert der Farbe auf 0.5 gesetzt habe, in dem Fall wird die Font im 2. Snipped noch schwächer/transparenter gerendert (das Quad im Ersten snipped nicht, hier habe ich die volle Farbstärke).
Dateianhänge
gl3_old.log
GL 3.x API Trace zum nicht funktionalen 1. Snipped
(39.95 KiB) 217-mal heruntergeladen
gl3_new.log
GL 2.x API Trace zum 2. Snipped mit der Unschärfe
(42.36 KiB) 235-mal heruntergeladen
gl2_new.log
GL 3.x API Trace zum 2. Snipped mit der Unschärfe
(49.51 KiB) 196-mal heruntergeladen
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: GLSL font rendering OpenGL 3.x

Beitrag von Artificial Mind »

Wenn ich mich nicht ganz täusche, dann bedeutet Internalformat GL_RG8, dass nur R und G gültig sind, nicht aber B und A.

Du solltest also vec4(vColor.rrr, texture2D(DiffuseMap, vTexCoord0).g); schreiben
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: GLSL font rendering OpenGL 3.x

Beitrag von snoob741 »

Das war der richtige Tipp. Ich musste zwar noch eine kleine Modifikation vornehmen, aber mit folgendem Aufruf passt es nun:

Code: Alles auswählen

gl_FragColor = vec4(vColor.xyz, texture2D(DiffuseMap, vTexCoord0).y);
Was mir unklar war ist die Interpretation der Positionsplatzhalter um die Farbwerte anzusprechen. Wenn ich statt rgba, xyzw nutze ist es voll kompatibel und läuft auf beiden Renderern, mit rgba nur auf OpenGL 2.x. In GLSL wird rgba wirklich auf die Farbkanäle gemappt, während xyzw die Position im Vektor definiert. Und somit ist es bei LA bzw. RG dann mit y egal, ich spreche wirklich den 2. Wert an ... Wieder was gelernt ;)
Antworten