40

OpenGL上に構築されたGUIを実装しています。各GUIにテキストレンダリングがあるという問題が発生しました。OpenGLでテキストをレンダリングするいくつかの方法を知っていますが、そのうちのどれがGUIに最も適しているのか疑問に思います。

通常、GUIには、静的とライブの2種類のテキストがあります。静的は非常に簡単です。TTFをテクスチャにレンダリングして、それを忘れることができます。私をもっと悩ませているのは「ライブ」テキストです。コンソールやマルチプレイヤーゲームのライブチャットを想像してみてください。

私はいくつかのオプションを考えました:

  • 特別な場合はありません-テキストが変更されるたびにテクスチャをレンダリングしてロードします。実際に新しいテキストが表示されたときにのみ再レンダリングすることを念頭に置き、大きなテキストを小さな部分に分割しようとします(チャットラインごとなど)。ただし、これでも、スコアラインが常に変化する場合や、「キャラクターごと」にレンダリングされるイントロテキスト(一部のSFゲームで見られるタイプライタースタイル)などの場合は、ハングアップしたままになります。
  • 文字ごとのクワッド-これも人気のあるソリューションのようです。ASCIIテーブルを使用してテクスチャを準備し、テクスチャ付きのクワッド文字をレンダリングします。しかし、私はそのようなソリューションの効率について深刻な疑問を持っています。それを速くする方法のヒントも歓迎されます。
  • ハイブリッドソリューション-しかし、それをきれいに実装する方法がわかりません

したがって、問題は、OpenGLでテキストを効率的にレンダリングする方法です。

これが役立つ場合は、STL /Boostを多用するC++でコーディングし、GForce6以降のグラフィックカードを目指しています。

4

7 に答える 7

30

EDIT2:Sean Barrettは、C / C++3Dプログラマー向けのビットマップフォントをリリースしました。

編集:一見の価値がある別のコード宝石は、 SeanBarrettのstb_truetype.hを活用するFontStashです。


フォントのすべての文字をレンダリングするテクスチャを作成できます。次に、正投影と適切なテクスチャ座標を使用してテクスチャクワッドを描画します。このアプローチは、テキストが英語などの記号をあまり含まない言語である場合に機能します。フォントテクスチャは、アプリケーションの開始時に1回作成され、その後、クワッドのレンダリングが非常に高速になります。

これが私が使用しているものであり、OpenGLでテキストをレンダリングするための最速の方法だと思います。最初は、AngelcodeのBitmap Font Generatorツールを使用し、次にFreeTypeを直接統合して、アプリケーションの起動時にすべてのグリフを含む大きなテクスチャを作成しました。クワッドのレンダリング速度を向上させるためのヒントについては、アプリケーションの残りのジオメトリとしてVBOを使用しました。

CPUでテクスチャを生成し、それをアップロードし、それをバインドして最終的に各フレームの長方形をレンダリングするパフォーマンスについて心配していないように見えますが、クワッドレンダリングに疑問があることに驚いています。OpenGLの状態を変更することがボトルネックであり、テキストに使用する500〜1000クワッドではありません。

また、フォント全体をポリゴン(幾何学的フォント)に変換するFTGLライブラリのようなライブラリもご覧ください。

于 2010-01-15T13:20:31.840 に答える
8

これを読んでみてください:http ://dmedia.dprogramming.com/?n=Tutorials.TextRendering1 。

説明されているアプローチは、グラフィックAPIを使用したテキストレンダリングの一般的な方法です。クワッドごとに1文字、および単一のテクスチャ内のテキストのすべての画像データ。文字セット全体を1つのテクスチャに収めることができる場合(実際には、テクスチャのサイズによっては、複数のテクスチャを収めることができる場合があります)、レンダリングは非常に高速です。

重要なのは、テクスチャバインディングが最小化する必要のある操作であるということです。すべてのテキストを単一のテクスチャでレンダリングできる場合は、画面に配置する必要のあるテキストの量は関係ありません。テクスチャを数回切り替える必要がある場合でも(異なるフォント、異なるフォント属性[太字、下線など])、パフォーマンスは良好です。テキストのパフォーマンスはHUDにとってより重要かもしれませんが、GUIではそれほど重要ではありません。

于 2010-01-15T13:47:12.910 に答える
5

テキストを三角形の面としてレンダリングし、テクスチャの使用を避けることができます。このようにして、テキストがズームされたときにエッジが不鮮明になるのを防ぎます。オープンソースでgithubで入手できる低ポリゴンASCIIフォントを作成しました。

テキストにシャープなエッジを持たせるもう1つの方法は、 SDFフォントレンダリングですが、これにはいくつかのアーティファクトがあります。

于 2015-03-07T03:53:11.890 に答える
4

freetype-gl

https://github.com/rougier/freetype-glは、freetypeとOpenGLを統合するライブラリです。

コンソールを想像してください

コンソールを参照してください:https ://github.com/rougier/freetype-gl/blob/a4cfb9abac19a0ab62b625a9b6f856e032fe3732/demos/console.c

ここに画像の説明を入力してください

Ubuntu 15.10で実行する方法:https ://github.com/rougier/freetype-gl/issues/82#issuecomment-216025527

詳細については、OpenGLメソッドのみを使用してテキストを描画する方法をご覧ください。

Urho3DConsoleInput.cpp

https://github.com/urho3d/Urho3D/blob/6b63f20065558cff1842bc8e1e3c6ee11f4bf577/Source/Samples/26_ConsoleInput/ConsoleInput.cpp

ここに画像の説明を入力してください

于 2016-05-01T09:20:35.277 に答える
1

ほとんどの場合、表示リスト(テキストが変更されたときにのみ更新される)で十分だと考えられ、処理されるクワッド文字ごと。

XLoadQueryFont、glGenLists、glXUseXFont、glCallListsを使用して、X11フォントで使用しました。各文字を説明するディスプレイリストの配列があります。

glCallLists関数は、テキストのchar *引数を受け入れ、ディスプレイリスト内に埋め込むことができます。

したがって、ブロックテキストを表示するための1回の呼び出しになります。

G. Pakoszによって提案されたフォントテクスチャは似ていますが、独自の「文字ごと」のディスプレイリストを計算します。

最初のオプションは、テキストが変更されるたびにプロセッサベースのレンダリングが必要になるため、非常に遅くなります。

于 2010-01-15T13:48:46.640 に答える
1

次の2つの関数を使用できます。

void renderstring2d(char string[], float r, float g, float b, float x, float y)
{
    glColor3f(r, g, b);

    glRasterPos2f(x, y);
    for(unsigned int i = 0; i < strlen(string); i++)
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
}

void renderstring3d(char string[], float r, float g, float b, float x, float y, float z)
{
    glDisable(GL_LIGHTING);
    glColor3f(r, g, b);

    glRasterPos3f(x, y, z);
    for(unsigned int i = 0; i < strlen(string); i++)
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
}

次に、2Dテキストをレンダリングするときは、モデルビューと投影行列の両方をリセットすることを忘れないでください。

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

// Render text and quads

glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

これらの関数はフレームバッファに直接レンダリングされるため、これらの関数を使用してクワッドにレンダリングする必要はありません。

それでもうまくいかない場合は、こちらをご覧ください。 http://www.opengl.org/resources/faq/technical/fonts.htm

glBitmap、glDrawPixels、およびアルファブレンディングを使用したテキストのレンダリングについて説明します。

于 2010-01-15T14:15:09.983 に答える
1

特にサブピクセルフォントのレンダリング技術を使用する場合は、これを行うのは難しいです。ClanLibSDKをご覧ください。バッチレンダラーを使用して、1回のOpenGL呼び出しでテキストの画面全体をレンダリングします。zlibベースのライセンスがあるため、SDK自体を使用したくない場合は、コードを抽出できます。

于 2013-09-25T09:49:47.790 に答える