web-dev-qa-db-ja.com

GUIのOpenGLライブテキストレンダリングを行う方法

OpenGL上に構築されたGUIを実装しています。各GUIが持つ問題、つまりテキストレンダリングに遭遇しました。 OpenGLでテキストをレンダリングするいくつかの方法を知っていますが、GUIに最適な方法はどれかと思います。

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

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

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

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

これが役立つ場合は、STL/Boost-heavy C++でコーディングしており、GForce 6以降のグラフィックスカードを目指しています。

41

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

編集:一見の価値がある別のコードgemは Font Stash であり、これはSean Barrettの stb_truetype.h を利用しています。


フォントのすべての文字をレンダリングしたテクスチャを作成できます。次に、正射影と適切なテクスチャ座標でテクスチャ化された四角形を描画します。このアプローチは、テキストが英語のように多くの記号を含まない言語である場合に機能します。フォントテクスチャはアプリケーションの最初に一度作成され、四角形のレンダリングは非常に高速です。

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

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

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

30
Gregory Pakosz

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

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

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

9
luke

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

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

5
Bram

次の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、およびアルファブレンディングを使用したテキストのレンダリングについて説明します。

1
Ned Bingham

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

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

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

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

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

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

1
fa.

特にサブピクセルフォントのレンダリング手法を使用する場合は、注意が必要です。 ClanLib SDK をご覧ください。バッチレンダラを使用して、1つのOpenGL呼び出しでテキストの画面全体をレンダリングします。 zlibベースのライセンスがあるため、SDK自体を使用しない場合は、そのコードを抽出できます

1
rombust