Drop
Drop

Reputation: 13003

How commercial games handles on-the-fly font loading?

This is how I handle font rendering in pseudocode(simplified):

FontFace* CreateFontFace(fontName, fontSize)
{
    FontFace* fontFace = LoadFromDiskCache(fontName, fontSize);
    if ( fontFace == 0 )
    {
        for(each glyph)
        {
            Load glyph using FreeType;
            Load its size and metric;
        }
        Pack all glyph bitmaps to a single UV-atlas
        {
            Calculate rectangles (RectangleBinPack); // Very slow!
            Blit glyphs to UV-atlas; // Slow!
            Insert rectangles to std::vector; // UV-dictionary;
            Insert metrics to std::vector;
        }
        Wrap it all to a struct FontFace;
        AddToDiskCache(fontName, fontSize); 
        // so on next startup it will be cached on HDD 
    }
    return fontFace;
}


bool OnInit(fontName, fontSize)
{
    for (each fontName)
    {
        for (each fontSize)
        {
            FontFace* fontFace = CreateFontFace(fontName, fontSize));
            Insert fontFace to container based on std::map;
        }
    }
}

void OnSomtimes(FontFace, pDevice)
{
    On demand create texture from FontFace.uvatlas on pDevice;
}

void OnRender(wstring, FontFace)
{
    if(needUpdate)
    {
        // Generate std::vector<Sprite> using given FontFace
        sprites = CreateSprites(wstring, FontFace);
    }

    Draw all vector<Sprite> at once with my SpriteBatch object; 
    // Big dynamic VertexBuffer, Instancing or GeometryShader 
    // depending on hardware caps
}

So I can cache some most used fonts or even all ever used in-game fonts. But in some apps user can just pick another font/size/style that app never seen before on the fly and it applies instantly. Or for example, in some games user can replace "font.tff" file in game folder and game will use it on startup in many sizes/styles and every of thousands of Unicode chars without additional time consuming preloading. Miracle!

I need something like this - an on-the-fly font loading.

Of couse, I can load glyphs separately on demand, and render glyph-by-glyph, but that means no batching, thousants of Draw calls per frame and huge GPU bandwidth. Not sure its ok or not for OpenGL, but its no go for D3D11.

How do they do that in game studios? Maybe you know a different approach? I heard about rendering fonts as geometry, GPU-processing and complicated curves algorithms, but cannot find helpful info in google.

Any help will be appreciated!

Upvotes: 2

Views: 2208

Answers (3)

xoofx
xoofx

Reputation: 3772

Font rendering in games is usually done from a bitmap that contains all glyphs generated at compile/offline time. You can use a bitmap font generator like AngelCode BMFont which is really easy to use and well suited for games, as It is supporting DXTx compressed bitmaps that are more GPU bandwidth friendly.

For high resolution Font, Alpha Texted Magnification technique is currently the preferred technique in games, mostly when rendering decals.

Upvotes: 2

MSalters
MSalters

Reputation: 180145

The obvious improvement is to not render all 50.000+ Unicode characters up front. Do you really need Chinese? Instead, make FontFace capable of blitting characters on the fly as needed, and initially blit just U+0020 - U+007E (ASCII).

A slightly smarter solution may be to render all characters from a script whenever you need the first. After all, if you need one Thai character, you'll probably need more of them. But this obviously requires some extra tables to group Unicode characters.

Upvotes: 1

bdonlan
bdonlan

Reputation: 231373

Instead of doing it glyph-by-glyph, why not render the entire string all at once in software as a single bitmap, then just render it as a single texture? Since text usually doesn't change very frequently once it's initially displayed, you can render the string in question on-demand when it's first displayed, then keep the string's texture in the GPU until it goes offscreen.

Upvotes: 1

Related Questions