OpenGL ESでTTFを読み込んで使用する

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
フィリップ

OpenGL ESでTTFを読み込んで使用する

#1

投稿記事 by フィリップ » 15年前

OpenGL ES(2.0)を使ってiPhoneで動くゲームを開発しております。
年間登録もしており幾つか作品を公開しております。

今回、新しく作るゲーム画面でttf(フォントファイル)を読み込んで
それを反映させるようなことをしたいです。
色々と調べてみたのですがそれらしい記事が見当たりませんでした。
ttfファイルから文字を表示させるようなことはOpenGLでは出来ないのでしょうか?

チュートリアル等で使うので出来ればフォントを読み込んで使いたいです。
また今まで文字はベタでPNGファイルを用意していたので
ttfを使えないのでしたら搭載されているフォントを使い文字列を描画できないでしょうか?

添付させて頂いたファイルは現在使っているベタ書きしたPNGファイルです。

Justy

Re:OpenGL ESでTTFを読み込んで使用する

#2

投稿記事 by Justy » 15年前

>ttfファイルから文字を表示させるようなこと
 試したことはないですが、FontLabelで出来ると聞いたことがあります。

zynga's FontLabel at master - GitHub
http://github.com/zynga/FontLabel

 NSStringが拡張されて専用の表示メソッドが追加されていますので、あとは通常の OpenGL時の
フォント文字列表示と同じ(ビットマップコンテキストからテクスチャに変換)で
いけるんじゃないかと思います。


>搭載されているフォントを使い文字列を描画できないでしょうか?
 こちらが参考になるかと。

エイバースの中の人 : iPhoneのOpenGLで文字を書く
http://blog.livedoor.jp/abars/archives/51877534.html

フィリップ

Re:OpenGL ESでTTFを読み込んで使用する

#3

投稿記事 by フィリップ » 15年前

連絡が遅くなりすみません。
ご回答ありがとうございます。

>>NSStringが拡張されて専用の表示メソッドが追加されていますので
これは添付して頂いたURLの物を使うのですよね?
添付して頂いたものを使っているのですがエラーが出てしまいます。
多分、インクルードするファイルが間違えていると思うのですが
どれを読み込めばよいのでしょうか?

Justy

Re:OpenGL ESでTTFを読み込んで使用する

#4

投稿記事 by Justy » 15年前

>添付して頂いたものを使っているのですがエラーが出てしまいます
 サンプルのプロジェクトは動かしてみましたか?
 で、どう書いたら、どの段階でどういうエラーが出たのですか?

>どれを読み込めばよいのでしょうか
 ?
 ひょっとして自分のプロジェクトに組み込むソースがどれだかわからない、ということでしょうか?

フィリップ

Re:OpenGL ESでTTFを読み込んで使用する

#5

投稿記事 by フィリップ » 15年前

回答ありがとうございます。

サンプルは動かしました。
3種類の文字がそれぞれの色で出ているやつですよね?
それをもとに実装しております。
自分のプロジェクトにClasses内にあるFontLabelフォルダをすべて追加し
ソースを下記の様に修正しております。

>>エラーについて
記載したほうがわかりやすかったですね・・・。
レンダーをしているソースにFontLabelという型を使うとエラーが出てしまいます。
~ES1Renderer.mm:117: error: 'FontLabel' was not declared in this scope
//  OpenGLAppDelegate.m
//  OpenGL

#import "OpenGLAppDelegate.h"
#import "EAGLView.h"
#import "FontManager.h"

@implementation OpenGLAppDelegate

@synthesize window;
@synthesize glView;


- (void) applicationDidFinishLaunching:(UIApplication *)application{
    [[FontManager sharedManage[/url] loadFont:@"Abduction"];
}

//////////////////////////////////////////////////
// レンダーをしているソース
//////////////////////////////////////////////////
FontLabel *label = [[FontLabel alloc] initWithFrame:CGRectMake(10, 10, 0, 0) fontName:@"Abduction" pointSize:40.0f];
label.textColor = [UIColor magentaColo[/url];
label.text = @"lorem ipsum";
[label sizeToFit];
label.backgroundColor = nil;
label.opaque = NO;
>>エイバースの中の人 : iPhoneのOpenGLで文字を書く
私のソースではGLuint型というのでテクスチャを用意し
GLuint型専用の描画関数を使っております。
(openglで作るiphone sdkゲームプログラミングという本に書いてあったもの)
もしフォント専用のテクスチャを作るとした場合、添付して頂いたURLの様な
構造体を新規に用意して専用の描画関数を作らなければいけないのでしょうか?

出来ればDXライブラリのDrawFormatString関数の様に使えるようにしたいです。
※%d等の可変引数?は実装できなそうなので
DrawString( int 左端X, int 左端Y, NSString* 表示する文字列)のようにして便利に文字を表示したいです。

OpenGLの理解度としてお察しかとは思いますが殆ど無知です。
プログラム能力としましてはDXライブラリ等を使えば一通りの物を作れますが
自分でライブラリの改変等は全くできません。

質問ばかりで申し訳ないのですがどうか教えては頂けないでしょうか?

Justy

Re:OpenGL ESでTTFを読み込んで使用する

#6

投稿記事 by Justy » 15年前

>FontLabelという型を使うとエラー
 FontLabelは FontLabel.hで定義されており、FontManager.hからは importされていないので
FontLabel.hを importして下さい。


>構造体を新規に用意して専用の描画関数を作らなければいけないのでしょうか?
 別に構造体である必要はないですが、専用の描画関数……DXライブラリのDrawFormatString相当の……は
作らないと表示はできません。
 
 一応先のHPの処理を理解すればそれを作ることは可能なはずです。


>OpenGLの理解度としてお察しかとは思いますが殆ど無知です
 それはなかなか厳しいですね。
 OpenGLは DXライブラリのように簡単にはいかないので、そこは勉強あるのみです。

フィリップ

Re:OpenGL ESでTTFを読み込んで使用する

#7

投稿記事 by フィリップ » 15年前

連絡が遅くなってしまいすみません。
インポートしたところエラーが消えました。
ありがとうございます。
フォントの読み込みは出来てそうなのですが
ここから文字列をテクスチャにすることがどうしても出来ません・・・。

OpenGLのサイトをみては見たのですが
エラーがとれません・・・。
以下が現在のソースです。
m_p_font_textureを用意した構造体で宣言する必要があると思うのですが宣言するとエラーが増えてしまいます。
またFONT_TEXTURE_MIPMAP_SIZEやtext等の値が不明なオブジェクトが出て来てしまいました。
これは自分で定数を入れろということなのでしょうか?

質問ばかりで申し訳ないです。

// Init部分 一回のみ読み込み
    FontLabel *label = [[FontLabel alloc] initWithFrame:CGRectMake(10, 10, 0, 0) fontName:@"Abduction" pointSize:40.0f];
    label.textColor = [UIColor magentaColo[/url];
    label.text = @"lorem ipsum";
    [label sizeToFit];
    label.backgroundColor = nil;
    label.opaque = NO;
    
    // 以下ループで描画処理
//    NSString *text = [[NSString alloc] init];
//    struct FontTextureMipmap m_p_font_texture;
    
    //テクスチャサイズを定義する
//    int s=FONT_TEXTURE_MIPMAP_SIZE;
//    m_p_font_texture->texture.width=s;
//    m_p_font_texture->texture.height=s;
    
    // テクスチャを作成する
//    glGenTextures(1, &(m_p_font_texture->texture.id));
    
    // テクスチャをバインドする
//    glBindTexture(GL_TEXTURE_2D, m_p_font_texture->texture.id);
    
    // テクスチャの設定を行う
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    
    //テクスチャのRGBAデータの配列を確保する
//    m_p_font_texture->data = (GLubyte *)malloc(m_p_font_texture->texture.width * m_p_font_texture->texture.height * 4);
    
    //テクスチャデータをVRAM上に転送し領域を確保する
//    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_p_font_texture->texture.width,m_p_font_texture->texture.height,0, GL_BGRA, GL_UNSIGNED_BYTE, m_p_font_texture->data);
    
    //文字描画用のコンテキストを作成する
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//    m_p_font_texture->_context = CGBitmapContextCreate(m_p_font_texture->data, m_p_font_texture->texture.width, m_p_font_texture->texture.height, 8, m_p_font_texture->texture.width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
    
    //フォントを確保する
    m_font = [UIFont systemFontOfSize:14];
    
    //実際の描画サイズを取得
//    CGSize size=[text sizeWithFont:m_font constrainedToSize:CGSizeMake(sx,512) lineBreakMode:UILineBreakModeWordWrap];
//    m_p_font_texture->texture.original_width=size.width;
//    m_p_font_texture->texture.original_height=size.height;
    
    //文字画像は上下反転しているので描画時にUV反転する
    //また、クリッピングエリアも反転するので注意
    
    // 文字を描画する
    memset(m_p_font_texture->data,0,m_p_font_texture->texture.width*m_p_font_texture->texture.height*4);
    UIGraphicsPushContext(m_p_font_texture->_context);
//    UIColor *color=[UIColor colorWithRed:r/255.0f green:g/255.0f blue: b/255.0f alpha:1.0f];
//    [color set];
//    [text drawInRect:CGRectMake(0,m_p_font_texture->texture.height-m_p_font_texture->texture.original_height,sx,m_p_font_texture->texture.original_height) withFont:m_font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
    UIGraphicsPopContext();
    
    // テクスチャをバインドする
//    glBindTexture(GL_TEXTURE_2D, m_p_font_texture->texture.id);
    
    // テクスチャを更新する
//    glTexSubImage2D(GL_TEXTURE_2D, 0, 0,m_p_font_texture->texture.height-m_p_font_texture->texture.original_height, m_p_font_texture->texture.width,m_p_font_texture->texture.original_height, GL_RGBA, GL_UNSIGNED_BYTE, m_p_font_texture->data);

}

Justy

Re:OpenGL ESでTTFを読み込んで使用する

#8

投稿記事 by Justy » 15年前

>これは自分で定数を入れろということなのでしょうか?
 はい。

 基本コピペそのままでうまくいくコードなんてそうそう転がっているものじゃないので、
そのあたりは自前で情報をそろえてあげる必要があります。

 とりあえず FONT_TEXTURE_MIPMAP_SIZEの代入先の sには 256でも入れておけばまずは十分でしょう。

フィリップ

Re:OpenGL ESでTTFを読み込んで使用する

#9

投稿記事 by フィリップ » 15年前

ご回答ありがとうございます。
何とかエラーが出ないで改変することが出来ました。
本当にありがとうございます。
このテクスチャを表示してみたのですが何も表示できませんでした。
m_p_font_texture.texture.idを描画すればよいという訳ではないのでしょうか?

// Init部分 一回のみ読み込み
    FontLabel *label = [[FontLabel alloc] initWithFrame:CGRectMake(10, 10, 0, 0) fontName:@"Abduction" pointSize:40.0f];
    label.textColor = [UIColor magentaColo[/url];
    label.text = @"lorem ipsum";
    [label sizeToFit];
    label.backgroundColor = nil;
    label.opaque = NO;
    
    // 以下ループで描画処理
    
    NSString *text = @"あいうえお";
    int sx = 0;
    
    //テクスチャサイズを定義する
    int s=256;
    m_p_font_texture.texture.width=s;
    m_p_font_texture.texture.height=s;
    
    // テクスチャを作成する
    glGenTextures(1, &(m_p_font_texture.texture.id));
    
    // テクスチャをバインドする
    glBindTexture(GL_TEXTURE_2D, m_p_font_texture.texture.id);
    
    // テクスチャの設定を行う
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    
    //テクスチャのRGBAデータの配列を確保する
    m_p_font_texture.data = (GLubyte *)malloc(m_p_font_texture.texture.width * m_p_font_texture.texture.height * 4);
    
    //テクスチャデータをVRAM上に転送し領域を確保する
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_p_font_texture.texture.width,m_p_font_texture.texture.height,0, GL_BGRA, GL_UNSIGNED_BYTE, m_p_font_texture.data);
    
    //文字描画用のコンテキストを作成する
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    m_p_font_texture._context = CGBitmapContextCreate(m_p_font_texture.data, m_p_font_texture.texture.width, m_p_font_texture.texture.height, 8, m_p_font_texture.texture.width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
    
    //フォントを確保する
    m_font = [UIFont systemFontOfSize:14];
    
    //実際の描画サイズを取得
    
    CGSize size=[text sizeWithFont:m_font constrainedToSize:CGSizeMake(sx,512) lineBreakMode:UILineBreakModeWordWrap];
    m_p_font_texture.texture.original_width=size.width;
    m_p_font_texture.texture.original_height=size.height;
    
    //文字画像は上下反転しているので描画時にUV反転する
    //また、クリッピングエリアも反転するので注意
    
    // 文字を描画する
    memset(m_p_font_texture.data,0,m_p_font_texture.texture.width*m_p_font_texture.texture.height*4);
    UIGraphicsPushContext(m_p_font_texture._context);
    //    UIColor *color=[UIColor colorWithRed:r/255.0f green:g/255.0f blue: b/255.0f alpha:1.0f];
    UIColor *color=[UIColor colorWithRed:255 green:255 blue:255 alpha:1.0f];
    [color set];
    [text drawInRect:CGRectMake(0,m_p_font_texture.texture.height-m_p_font_texture.texture.original_height,sx,m_p_font_texture.texture.original_height) withFont:m_font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
    UIGraphicsPopContext();
    
    // テクスチャをバインドする
    glBindTexture(GL_TEXTURE_2D, m_p_font_texture.texture.id);
    
    // テクスチャを更新する
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0,m_p_font_texture.texture.height-m_p_font_texture.texture.original_height, m_p_font_texture.texture.width,m_p_font_texture.texture.original_height, GL_RGBA, GL_UNSIGNED_BYTE, m_p_font_texture.data);

Justy

Re:OpenGL ESでTTFを読み込んで使用する

#10

投稿記事 by Justy » 15年前

>このテクスチャを表示してみたのですが何も表示できませんでした。
 FontLabelは導入していないので省きましたが、それ以下のコードはそのままコピペしてもちゃんと表示されましたよ。
 描画周りを見直してみて下さい。

閉鎖

“C言語何でも質問掲示板” へ戻る