[OpenGL 4.5] Text Rendering
Verfasst: 11.06.2017, 10:53
Hey!
Ich bastel ja grade an einer Engine und habe mittlerweile auch Font Rendering via FreeType implementiert.
Da meine Grafikkarte etwas zickig ist, wenn ich mehr als einen Monitor verwende, erhalte ich folgende Renderzeiten:
Mit Font-Rendering:
Wenn ich das Font Rendering ausschalte, steigt die Performance um gute 20%:
Um den Text zu rendern, verwende ich folgenden Code:
Als Vertex-Daten ist ein einzelnes Quad gebunden, als Shader ein einfacher Pixel-Shader, welcher eine Textur entweder direkt kopieren oder aber als Patch9-Struktur rendern kann...
Was kann ich alles verbessern, um die Performance des Text Renderings zu steigern?
Meine aktuellen Ideen sind folgende:
Lohnt sich SDF-Font-Rendering a'la Valve ( http://www.valvesoftware.com/publicatio ... cation.pdf ) oder wäre das für UI eher ein Holzweg?
Grüße
Felix
Ich bastel ja grade an einer Engine und habe mittlerweile auch Font Rendering via FreeType implementiert.
Da meine Grafikkarte etwas zickig ist, wenn ich mehr als einen Monitor verwende, erhalte ich folgende Renderzeiten:
Mit Font-Rendering:
Code: Alles auswählen
Render Frame: 20.8847 ms ( 47 fps) ← was mir mein Framework als letzte Frame Time liefert
Update Frame: 20.8930 ms ( 47 fps)
Render Time: 21.5780 ms ← Mit Stopwatch zwischen "begin(draw) und end(draw)
Update Time: 0.6297 ms
Code: Alles auswählen
Render Frame: 16.9969 ms ( 58 fps)
Update Frame: 16.8458 ms ( 59 fps)
Render Time: 9.2721 ms
Update Time: 3.7226 ms
Code: Alles auswählen
var text = tw.Text;
var font = tw.Font ?? theme.DefaultFont;
font.SetPixelSize(tw.FontSize);
this.glyphTexture.BindTo(TextureUnit.Texture0);
var size = font.MeasureString(text);
var px = x + (float)tw.Padding;
var py = y + (float)tw.Padding;
// Adjust to alignment like a boss!
py += 0.5f * (((int)tw.TextAlignment & 0xF0) >> 4) * (h - size.Y - 2 * (float)tw.Padding);
px += 0.5f * (((int)tw.TextAlignment & 0x0F) >> 0) * (w - size.X - 2 * (float)tw.Padding);
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (c == '\n')
{
py += font.Size;
px = x + (float)tw.Padding;
}
// Ignore all other control characters
if (char.IsControl(c))
continue;
if (char.IsSurrogate(c))
{
font.LoadChar((uint)char.ConvertToUtf32(c, text[++i]));
}
else
{
font.LoadChar(c);
}
var slot = font.GlyphSlot;
var bitmap = slot.Bitmap;
if (bitmap.Width > 0)
{
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, this.glyphTexture.ID);
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
GL.TexImage2D(
TextureTarget.Texture2D,
0,
PixelInternalFormat.Rgba8,
bitmap.Width,
bitmap.Rows,
0,
PixelFormat.Alpha,
PixelType.UnsignedByte,
bitmap.Buffer);
effect["uRectangle"].SetValue(new Vector4(
(int)(px + slot.BitmapLeft),
(int)(py + tw.FontSize - slot.BitmapTop),
bitmap.Width,
bitmap.Rows));
effect["uTextureConfig"].SetValue(new Vector4(
0, bitmap.Width,
0, bitmap.Rows
));
GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
}
px += slot.Advance.X.ToSingle();
py += slot.Advance.Y.ToSingle();
}
Was kann ich alles verbessern, um die Performance des Text Renderings zu steigern?
Meine aktuellen Ideen sind folgende:
- Für jeden verwendeten Glyphen eine prerendered Textur cachen
- Komplette Strings auf eine einzige Textur rendern mit glCopyImageSubData oder glTextureSubImage2D, anschließend rendern
- Komplett gerenderte Strings cachen
Lohnt sich SDF-Font-Rendering a'la Valve ( http://www.valvesoftware.com/publicatio ... cation.pdf ) oder wäre das für UI eher ein Holzweg?
Grüße
Felix