web-dev-qa-db-ja.com

iPhone SDK用のまともなOpenGLテキスト描画ライブラリはありますか?

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

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

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

24
Alex Wayne

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

ただし、これは私の目だけを対象としており、一般消費を目的としたものではないことに注意してください。地獄のように散らかっていることをお許しください:)

8
Ali Parr

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

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

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

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

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

22
Brad Larson

私はこれに対する簡単な解決策を見つけました。これが私が書いた簡単な関数です。 (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);    
}

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

6
Tony Tonev

「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);

簡単:)

Unicodeをサポートし、「オンデマンド」でグリフをロードし、変数を出力する方法もあります。

font.print(x, y, z) << "fps: " << fps;
3
Dustin

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

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

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA)

そして第二に、テキストは一点に引き込まれているように見えました。間違って読んでいない限り、CGRectMake呼び出しは1x1の長方形を作成しています。

3
user83945

「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/Font

2

愛の不時着のデモを確認してください。提供されているTexture2Dクラスを使用すると、テキストとフォントを使用してテクスチャを作成できます。 (うまくいけば、openglesビューに描画するより簡単な方法が欲しいより良い答えがあるでしょう)

1
Nick Van Brunt

はい、私が知っている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 atlas

IOSフォントのリストは ここで入手可能 であり、 ここでレンダリング

1
bobobobo