2

これは、擬似コードでフォントレンダリングを処理する方法です(簡略化):

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
}

そのため、最も使用されているフォントの一部、またはゲーム内で使用されたことのあるすべてのフォントをキャッシュできます。ただし、一部のアプリでは、ユーザーは、アプリがこれまでに見たことのない別のフォント/サイズ/スタイルをその場で選択するだけで、すぐに適用されます。または、たとえば、一部のゲームでは、ユーザーがゲーム フォルダー内の「font.tff」ファイルを置き換えることができ、ゲームは起動時に多くのサイズ/スタイルで、何千もの Unicode 文字ごとに、追加の時間のかかるプリロードなしで使用します。奇跡!

このようなものが必要です-オンザフライのフォント読み込み。

もちろん、必要に応じてグリフを個別にロードし、グリフごとにレンダリングできますが、これは、バッチ処理がなく、フレームごとに数千回の Draw 呼び出しが必要であり、GPU 帯域幅が膨大であることを意味します。OpenGL では問題ないかどうかはわかりませんが、D3D11 では問題ありません。

彼らはゲームスタジオでどのようにそれを行うのですか? 多分あなたは別のアプローチを知っていますか?フォントをジオメトリ、GPU 処理、および複雑な曲線アルゴリズムとしてレンダリングすることについて聞いたことがありますが、Google で役立つ情報を見つけることができません。

どんな助けでも大歓迎です!

4

3 に答える 3

2

ゲームでのフォント レンダリングは、通常、コンパイル/オフライン時に生成されたすべてのグリフを含むビットマップから行われます。GPU 帯域幅に適した DXTx 圧縮ビットマップをサポートしているため、非常に使いやすくゲームに適したAngelCode BMFontのようなビットマップ フォント ジェネレーターを使用できます。

高解像度のフォントの場合、主にデカールをレンダリングする場合、Alpha Texted Magnificationテクニックがゲームで現在好まれているテクニックです。

于 2012-10-22T00:38:05.717 に答える
1

グリフごとに行うのではなく、文字列全体を一度にソフトウェアで 1 つのビットマップとしてレンダリングし、それを 1 つのテクスチャとしてレンダリングしてみませんか? 通常、テキストは最初に表示されるとあまり頻繁に変更されないため、問題の文字列を最初に表示するときにオンデマンドでレンダリングし、画面外になるまで文字列のテクスチャを GPU に保持できます。

于 2012-10-21T12:42:42.023 に答える
1

明らかな改善点は、50.000 以上の Unicode 文字をすべて事前にレンダリングしないことです。中国語って本当に必要?代わりに、FontFace必要に応じてオンザフライで文字をブリットできるようにし、最初はU+0020 - U+007E(ASCII) だけブリットします。

少し賢い解決策は、最初の文字が必要なときにスクリプトからすべての文字をレンダリングすることです。結局のところ、タイ語の文字が 1 つ必要な場合は、おそらくさらに多くの文字が必要になるでしょう。しかし、これには明らかに、Unicode 文字をグループ化するための追加のテーブルが必要です。

于 2012-10-21T12:52:16.097 に答える