3

OpenGL アプリケーション用のテキスト レンダラーを作成しています。サイズ、色、フォント フェイス、およびアンチエイリアスは、実行時に調整できます (そのため、複数のフォント フェイスを一度に画面に表示できます)。文字列と属性の各組み合わせに 1 つのテクスチャを割り当てるには、組み合わせが多すぎます。ただし、文字列のデータベース全体の小さなサブセットのみが常に画面に表示されます。

これにより、フレームごとに印刷される文字列のキャッシュを作成する機会が得られます。操作全体で 1 つのテクスチャのみを使用することが義務付けられています。これは、多くのテクスチャのキャッシュを作成すると、キャッシュから出力される異なる文字列ごとにテクスチャ スワップ ペナルティが発生するためです。

そのため、目の前に 2048x2048 のテクスチャがあり、キャッシュの目的でアプリケーションから要求されたときに、適合する文字列を配置できます。2 次元空間で利用可能な自由空間を追跡することは簡単ではないことにすぐに気付きました。

ベスト フィットやネクスト フィットなどを見てきましたが、これらは 1 次元空間に適しているようです。

このキャッシュ テクスチャを OpenGL で管理するにはどうすればよいですか?

編集:これが「2次元パッキングの問題」のインスタンスであることを知りました。

4

3 に答える 3

2

あなたが持っているのはビンパッキング問題です。

最初の悪いニュース:それはNP困難なので、最適な解決策を見つける価値があります。

フォントについても、このようなテクスチャキャッシュを実行しました。単語全体をキャッシュするのではなく、グリフ画像だけをキャッシュしました。すべての画像がほぼ正方形であるため、これにより作業が非常に簡単になります。テクスチャメモリを追跡するための単純なグリッドベースのアプローチは、かなりうまく機能しました。

グリッドボックスの1つよりも大きいグリフを取得した場合は、ブルートフォース検索を使用して2つ以上のボックスを割り当てました(それほど頻繁には発生しませんでした)。適切なブロックが見つからなかった場合は、キャッシュからいくつかのグリフをランダムに削除して、空き領域を確保しました。

これは、最近使用したキャッシュに物事を保持するよりもはるかに簡単で、ほぼ同じように機能しました。

ところで-そのようなキャッシュのテクスチャメモリには常にいくらかの無駄があります。あなたがメモリに非常にタイトでない限り、それは問題ではないはずです。小さなテクスチャ形式を使用する必要があります(8ビットアルファはフォントに適しています)。

また、グリッドブロックを8ピクセルの倍数にし、アンチエイリアスを4ビットにドロップできる場合は、グリフを圧縮されたDXTまたはS3TC形式のいずれかにオンザフライで圧縮できます。無駄なテクスチャスペースは、そのように問題になりません。

于 2009-03-27T03:39:49.253 に答える
1

テクスチャメモリが不足している場合は、「距離フィールド」または「符号付き距離フィールド」のフォントレンダリング手法を確認できます。フォントファミリごとに512x512のテクスチャを使用でき、任意のサイズの完全にアンチエイリアス処理されたテキストをレンダリングできます。

そのアルゴリズムでは、テクセルからテクスチャのエッジまでの距離を含む特別なテクスチャを生成する必要があります。Valveの人による元の論文を見てください:http ://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf 。これを利用するフレームワークがいくつかあります。たとえば、最新バージョンのQtは、テキストレンダリングに符号付き距離フィールドを使用します。

于 2012-07-15T16:15:29.500 に答える
0

私は単純なアプローチを使用することを選択しました。テクスチャを可変高さの行に分割します。行に配置される最初のテクスチャによって、行の高さが決まります。テクスチャが高さによって既存の行に収まる場合は、十分な幅が残っているかどうかを確認し、そこに配置します。それ以外の場合は、新しい行を開始します。新しい行を開始できない場合は、文字列をキャッシュしないでください。

于 2009-03-31T17:47:03.300 に答える