24

私はOpenGLでテキストを描く簡単な方法を見つけようとしています。私の調査では、かなり複雑な作業であることが示されています。これには、フォントアトラステクスチャを作成(または実行時に生成)してから、適切な配置とテクスチャ座標で各文字のクワッドを作成することが含まれます。

FreeTypeについては良いことをいくつか聞いたことがありますが、iPhoneで実行する方法についてはほとんどわかっておらず、かなり複雑に見えます。

では、人々が使用しているiPhone SDKで動作するObjective-CでラップされたOpenGLテキストライブラリはありますか?それとも、私はこれを考えすぎていて、私が見逃しているより簡単なアプローチがありますか?

4

8 に答える 8

22

これを行う 1 つの方法は、UILabel を設定し、そのレイヤーをテクスチャにレンダリングすることです。これへの間接的なルートは、最初に UILabel にテキスト、フォントなどを設定してから、次のコードを使用することです。

UIGraphicsBeginImageContext(yourLabel.frame.size);
[yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UILabel を UIImage にキャプチャします。CrashLanding プロジェクトの Texture2D クラスの initWithImage: コンストラクターを使用して、これをテクスチャに変換できます。

initWithImage のように見えます。この例では、UIImage をビットマップ コンテキストに再レンダリングし、それを使用してテクスチャを作成します。ちょっとした作業で、そのメソッドから関連するコードを抽出し、上記のコードを変更してレイヤーをテクスチャに直接レンダリングすることができます。

このようにして、テクスチャのテキストを作成するときに、UILabel の優れた Unicode とフォントのサポートを取得します。

于 2009-02-04T18:46:00.150 に答える
8

freetype を使用してテクスチャ アトラスを作成し、すべてのグリフ情報を作成するというあなたの説明は、まさに私が現在の iPhone プロジェクトで行っていることです。

前処理ステップでフォントのすべての解析を行います (すべて Windows では C# で行います)。アトラス自体が生成され、必要な文字のみが含まれます。スペースを削減するために、テクスチャ サイズ pow2 と実用的な解像度を維持するために複数のアトラスを生成することもあります。

freetype から簡単にグリフ情報を引き出すことができます。これを実行時にテクスチャと一緒にアプリに渡すと、必要に応じてテクスチャの UV 座標を変更するだけで簡単になります。

参考までに、これは私の小さなエンジン内でグリフ文字を定義する方法です。

struct FontGlyph
{

u32 char_code;

u32 m_x;                // base x position on tpage

u32 m_y;            // base y position on tpage

u32 m_width;            // glyph width

u32 m_height;           // glyph height

i32 m_horiBearingX;     // Distance to X shift

i32 m_horiBearingY;     // Distance to Y shift

u32 m_horiAdvance;      // Total Horizontal advance this character requires

u32 m__tpage_index;     // Which tpage does this glyph use?

};

次に、スプ​​ライトを使用して描画できることを除けば、他の文字列とほとんど同じように動作する「SpriteString」オブジェクトがあります....

これはすべて、かなり些細な問題に対する大きな仕事のように思えるかもしれませんが、それによって十分な柔軟性が得られ、実際に実装するのにそれほど時間がかからなかったことがわかりました。

他に詳細が必要な場合は、お気軽に返信またはコメントしてください。(そして成功を祈る :)


コメント セクションのスペースが足りなくなったので、コメントに返信してください...

freetype のドキュメントを参照してください。基本的には、グリフ データをいじらずに取得できます。フォントから直接取得するだけです。テクスチャ自体については、freetype を取得して各グリフをレンダリングし、それを管理してテクスチャを構築します。これは、メインのアプリとはまったく別の前処理として行います。

これを行うツール コードの抜粋を次に示します: http://pastebin.com/md1c6354

ただし、これは私の目だけを対象としたものであり、公の消費を目的としたものではないことに注意してください.

于 2009-02-04T17:21:32.240 に答える
6

これに対する簡単な解決策を見つけました。ここに私が書いた簡単な関数があります。(Texture2D クラスが必要です。)

- (void) drawText:(NSString*)theString AtX:(float)X Y:(float)Y {
// Use black
glColor4f(0, 0, 0, 1.0);

// Set up texture
Texture2D* statusTexture = [[Texture2D alloc] initWithString:theString dimensions:CGSizeMake(150, 150) alignment:UITextAlignmentLeft fontName:@"Helvetica" fontSize:11];

// Bind texture
glBindTexture(GL_TEXTURE_2D, [statusTexture name]);

// Enable modes needed for drawing
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

// Draw
[statusTexture drawInRect:CGRectMake(X,Y-1,1,1)];   

// Disable modes so they don't interfere with other parts of the program
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);    
}

入力座標はあなたの世界座標にある必要があると思いますが、それが一般的に正しいのか、それとも私にとってはうまくいくのかはわかりません。それを正しくするために、オフセットをいじる必要があるかもしれません。

于 2009-03-24T05:58:00.303 に答える
3

「musings」フォント ライブラリを使用します。

http://www.themusingsofalostprogrammer.com/2010/01/how-to-do-font-rendering-in-opengl-on.html

Font font("Verdena");
font.print("Hello World!", x, y, z);

簡単 :)

ユニコードをサポートし、グリフを「オンデマンド」でロードし、変数を出力する方法さえあります

font.print(x, y, z) << "fps: " << fps;
于 2010-01-20T21:11:31.833 に答える
3

その方法をありがとう。時間を節約できました。

ただし、変更しなければならないことがいくつかありました。glBlendFunc 呼び出しは次のようにする必要があります。

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA)

そして第二に、テキストが一点に引き寄せられているように見えました。CGRectMake 呼び出しは、1x1 の四角形を作成しています。

于 2009-03-28T08:16:47.877 に答える
2

「musings」フォント ライブラリに似た Font クラスを作成しましたが、メモリ リークを差し引いて、すべての文字、すべてのフレームのテクスチャ作成を差し引いています。ただし、文字ごとに異なる glTexture を使用します。注: Texture2D は、テクスチャの削除をコメントアウトするように変更されました。

コンストラクタで初期化: _font = new Font("Helvetica", 40);

redraw() メソッドで使用: _font->draw("Hello, World!", 50, 100, ALIGN_LEFT);

GitHub リンク:

https://github.com/chandl34/public/tree/master/personal/c%2B%2B/フォント

于 2012-12-10T02:46:16.973 に答える
1

はい、私が知っている2つがあります。秘訣は、Quartz(CGContext *関数)を使用してテクスチャにレンダリングしてから、ユーザーが表示できるようにそのテクスチャをレンダリングする必要があることです。

パフォーマンスが心配な場合は、Quartzを使用してテクスチャアトラスを生成することもできます。

フォントのレンダリングの基本を理解すれば、テクスチャ生成ツール(xCode)を作成するのはかなり簡単です。

あなたがしなければならないのは、有効なCGContextを持っていることだけです。このテクスチャローダーには、非常に優れたサンプルコードがいくつかあります。

基本的に、コードは次のようになります。

// Create the cgcontext as shown by links above

// Now to render text into the cg context,
// the drop the raw data behind the cgcontext
// to opengl.  2 ways to do this:
// 1)  CG* way: (advantage: easy to use color)
CGContextSelectFont(cgContext, "Arial", 24, kCGEncodingMacRoman);

// set color to yellow text
CGContextSetRGBFillColor(cgContext, 1, 1, 0, 1) ; // Be sure to use FILL not stroke!

// draw it in there
CGContextShowTextAtPoint(cgContext, 20, 20, "HI THERE", strlen("HI THERE") ) ;

/*
// WAY #2:  this way it's always black and white
// DRAW SOME TEXT IN IT
// that works ok but let's try cg to control color
UIGraphicsPushContext(cgContext);
UIFont *helv = [UIFont fontWithName:@"Helvetica" size:[UIFont systemFontSize]];
NSString* msg = @"Hi hello" ;  
[msg drawInRect:CGRectMake(0,0,pow2Width,pow2Height) withFont:helv] ;
    UIGraphicsPopContext();
*/

// put imData into OpenGL's memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pow2Width, pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imData);
CHECK_GL ;

見栄えがよく、アンチエイリアス処理された状態で表示されます。

texアトラス

iOSフォントのリストはここにあり、プリレンダーはここにあります

于 2012-09-22T19:03:49.630 に答える
1

墜落着陸のデモを確認してください。提供されている Texture2D クラスを使用すると、テキストとフォントを使用してテクスチャを作成できます。(うまくいけば、私はopenglesビューに描画するより簡単な方法が大好きです)

于 2009-02-04T17:04:29.840 に答える