2009-03-27 16 views
3

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

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

私は2048x2048のテクスチャを持っています。キャッシングの目的でアプリケーションから要求されている文字列を配置することができます。私はすぐに、2次元空間で利用可能な自由空間を追跡することは自明ではないことを認識しました。

私はBest FitとNext fitのようなものを見てきましたが、それらは1dスペースに適しているようです。

このキャッシュテクスチャをOpenGLでどのように管理できますか?

編集:これは「2dパッキングの問題」のインスタンスであることがわかっています。

答えて

0

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

2

ビンパッキングの問題があります。

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

フォントのテクスチャキャッシングも同様に行っています。私は言葉全体をキャッシュしませんでしたが、グリフイメージだけをキャッシュしました。すべての画像がおおよそ正方形になっているので、作業が楽になります。テクスチャメモリを追跡するための単純なグリッドベースのアプローチがうまくいきました。

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

これは、最後に最近使用されたキャッシュに保存するよりはるかに簡単で、ほぼ同じように実行されました。

Btw - このようなキャッシュのテクスチャメモリにはいつも無駄があります。 非常にの場合、問題ではないはずです。小さなテクスチャ形式(8ビットアルファはフォントでうまく機能する)を使用する必要があります。

グリッドブロックを8ピクセルの倍数にして、アンチエイリアスを4ビットにすることができます。グリフを圧縮DXTまたはS3TCフォーマットの1つにオンザフライで圧縮できます。無駄なテクスチャ空間はそれほど問題になりません。

1

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

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

+0

ああ、投稿前に日付をチェックしておいたはずです:) –

+0

完全な実装のために、libcinderを見てください。 –

関連する問題