Archive for the OpenGL ES Category

Blender → SIO2 (備忘録)

Blenderで作った3DモデルをSIO2に持って行く際に、Blender上でattache出来たと思っていたTexture (Material)をSIO2側で実行すると上手く行かない事がありました。その際に注意すべき点を備忘録として書き残しておきます。

  • SIO2にTextureを持って行く為にはBlender上でUVマップにUnwrapしておく必要があります。
  • Blenderではメッシュは全てQuadで作成されます。これはOpenGLの仕様の違いだと思います。OpenGL ESではTriangleでレンダリングして行く必要があるため各オブジェクトはExportする前に変換しておく必要があります。
    1. オブジェクトを選択する
    2. Edit Modeに入る。
    3. Meshメニューから “Faces” -> “Quad to Tri” を選び実行する。

    以上

 

 

UIImageからOpenGLのテクスチャーを作る (備忘録)

OpenGL ESは非常に柔軟で強力なAPIを提供してくれています。
しかしその一方でOpen GL ESが非常に柔軟過ぎるが為にどこから取っ付いて良いか分からなくなってしまうのが、その移行への障害になっているように思います。

iOSではUIImageを始めとして非常に使い勝手の良い画像処理用のクラスが用意されています。しかしそれをOpenGLで使おうとすると画像フォーマットの変換やCPUとGPU間のメモリー転送等、考慮しなければいけない課題が多いように思います。

OpenGLで提供されている画像イメージはTextureの概念に拘束されます。従って、iOSで一般的に使用されているUIImageやCGImageとTextureの間の画像フォーマット変換とメモリーの転送の効率は非常に重要な問題になると思います。

調べているうちにiOS5からは便利なクラスが提供されていました。

GLKTextureLoader

このクラスを使用するとファイル上のイメージデータやUIImage(CGImageに変換した後)をかなり効率的にOpenGL ESのTextureに変換出来ます。

UIImage* uiImage;
CGImage* cgImage;
uiImage = [UIImage imageNamed:@"xxxx.png"];
cgImage = uiImage.CGImage;

NSMutableDictionary* dic;
NSError* error;

dic = [NSMutableDictionary alloc];
dic = [dic initWithCapacity:0];
[dic setObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderApplyPremultiplication];
[dic setObject:[NSNumber numberWithBool:NO] forKey:GLKTextureLoaderGenerateMipmaps];
[dic setObject:[NSNumber numberWithBool:NO] forKey:GLKTextureLoaderOriginBottomLeft];
[dic setObject:[NSNumber numberWithBool:NO] forKey:GLKTextureLoaderGrayscaleAsAlpha];

textureInfo = [GLKTextureLoader textureWithCGImage:cgImage options:dic error:&error];
[textureInfo retain];

他のビットマップイメージを直接アクセスしながら変換する方法と、パフォーマンスの違いがどの程度あるのかは、今のところ測定していませんが、Appleから直接提供されているAPIですのである程度は信頼出来るのではないかと思います。

最終的に取得される GLKTextureInfo の nameプロパティでTextureにアクセス出来ます。

Road to OpenGL ES (6)

Cheetah3D再び

次はBlenderの話を書こうと思っていたのですが、再びCheetah3Dに戻って来ました。Cheetah3Dに面白い機能を見つけたからです。

Blenderと同様にCheetah3Dも様々なフォーマットでデータをExportする事が出来るのですが、その中の”.h”へのExportが気になったからです。

試しにExportを実行して見ると、下記のようなヘッダファイルが出力されます。3Dモデルにもよるのですが、かなり巨大なヘッダファイルです。

嬉しいのが、その使い方まで書いてあります。

まずは構成ですがまず、NAME_vertex,NAME_indexの2つの2次元配列。

そしてNAME_vertexcountとNAME_polygoncountがそれぞれの配列の個数。

NAMEの部分はそれぞれメッシュのの名前が自動的に割り当てられます。

 

 

おまけにどのようにしてこの配列を使って描画すれば良いかまで書いてあります。

 

// You can draw the mesh the following way:
//      glEnableClientState(GL_INDEX_ARRAY);
//      glEnableClientState(GL_NORMAL_ARRAY);
//      glEnableClientState(GL_VERTEX_ARRAY);
//      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//      glInterleavedArrays(GL_T2F_N3F_V3F,0,NAME_vertex);
//      glDrawElements(GL_TRIANGLES,NAME_polygoncount*3,GL_UNSIGNED_INT,NAME_index);

 

しかしこれが引っかけ(?)で、このままではiOS上で実行出来ません。
ビルドで弾かれてしまいます。実装されていないAPIがあるからです。
多分、MacOS X のOpenGLなら大丈夫なんでしょうね。
Cheetah3DのサポートHPにもあるように、
http://cheetah3d.de/forum/showthread.php?t=4617
上記APIの代わりに下記のAPIを呼んであげれば無事に描画する事が出来ます。
glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), &NAME_vertex[0][5]);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), &NAME_vertex[0][0]);
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), &NAME_vertex[0][2]);
glDrawElements(GL_TRIANGLES,NAME_polygoncount*3,GL _UNSIGNED_SHORT,NAME_index);

 

 

Road to OpenGL ES (5)

Cheetah3D

Unityにはまだ未練があります。なぜならこの時点でまだ他にソリューションが見つかっていないからです。

その意味で、3Dレンダリングソフトを試してみて相性が良ければ…という気持ちがありました。前回ご紹介したUnityと連携出来る3Dレンダリングソフトですが、やはりAutodesk関連のソフトは高価すぎます。ですので迷い無くCheetah3DとBlenderに絞りました。

まずはCheetah3D。

AppStoreからも購入可能です。

僕は簡単なんでAppStoreから購入してしまいました。購入してしまうと値段が出ないのでカードの請求書を見るしかありませんが、だいたい8千円台だったと思います。

autodeskのソフトから比べると天と地です。(余談ですが、autodeskの日本法人の社長はまだApple Japan出身の志賀さんなのでしょうか?)

日本語化されていますので、メニュー等も全て日本語です。一部を除いてオンラインヘルプも日本語になっています。

Macのソフトらしく、マウス操作で基本的なメッシュからそれを変形しながら様々なオブジェクトを作って行く事も簡単に出来ます。アニメーションやパーティクルにも対応していて成果物をムービーに落とす事も出来るようです。

本格的なプロにとっては物足りないのかもしれませんが、僕にとっては機能豊富なソフトです。

もともとレンダリングソフト上でアニメーションをするつもりがありませんでしたので(これはUnityでも後でご紹介するフレームワークでも極めて重要なのですが)、これで十分でした。

 

しかし…

マイナーなのです。

ググっても、今やりたい事を助けてくれるようなサイトが極めて少ないのでした。

レンダリングソフト初心者の僕にとっては、この部分がかなりハードルが高いものになって来ました。

 

移り気な僕は、8千円の出費は痛いもののフリーソフトのBlenderへと簡単に行く事になりました。

 

時系列で言えばCheetah3DとBlenderは、かなり平行してevaluateしていました。その中で引っかかったのが、両方とも「.fbx」というファイル形式でエクスポート出来ると言う事です。

それはまた別の項でご紹介します。

 

 

追記。

そしてまたCheetah3Dに戻ってくるのですが…

 

Road to OpenGL ES (4)

単にiOS上でゲームを作るならUnityは一番早い方法だと思います。

日本語の書籍もある程度出ていますし、ネット上でもブログ等で紹介されています。

何よりも画面上で様々な設定が出来て、簡単なゲームならチョコッと(?)プログラムを描くだけでもそれらしく見えます。

ゲームのキャラクターや場面の画像も比較的容易で、UnityのHPでも紹介されている様に

などの3Dレンダリングソフトと連携する事が出来ます。

高価なものもありますが、対象をiOSと絞った場合にはCheetar3DBlendeardeもサポートしていますので、その部分では非常に安価におさめる事が出来るのではないでしょうか。

ただ、Unityでは独自の開発環境で開発し、それをxcodeのプロジェクトに書き出すという形式を取っています。

そのため生成されるコードをイジル事は殆ど出来ません。

もちろんプロダクトを作って売る事が目的ですが、根っからの開発者としてはちょっと物足りません。

とりあえずUnityの採用はPendingにしたものの、もう一つ解決しなければいけない課題。3Dレンダリングです。

 

先ほどご紹介したBlenderとCheetah3Dを試しましたので、次回はそこら編をご紹介したいと思います。

 

 

 

 

 

 

 

Road to OpenGL ES (3)

前回ご紹介したcocos2dには、その拡張としてcocos3dというのがあります。

名前の通り、cocos2dを拡張した3D用のフレームワークのようです。現在のバージョンは0.6.4。まだβの状態ですね。ソースが公開されているとはいえ、ははり製品にβバージョンのフレームワークを使う気には今のところなりません。

今後、マイナーバージョンとなった時には考えたいと思います。

Unityを試す

今まで断片的にOpenGL ESのネイティブAPIやCocosを試す中で思ったのが、3Dモデリングをする際の「座標」です。どれも当然ですが座標を指定して描画する必要があります。2DまでのそれもiPhoneなどの480×320程度の座標系でしたら頑張って何とかなるんですが、3DとなってZ軸まで入ってくると簡単には行きません。通常はそこに3軸(x, y, z軸)の回転が入って来て、僕の頭の中では簡単には処理しきれません。

いわゆる3Dモデリングツールと連携出来る事が求められます。

いわばお絵描きソフトの中で3Dの物体を描いて、それをそのまま読み込んでフレームワークの中で使う。

それが出来れば願ったり叶ったりです。

そういった希望を込めて検索して行くとUnityというソフトに巡り会いました。

このソフトは凄いです。

マニュアルによるとMaya、Cinema 3D、3D Studio Max、Cheetah 3D 、Modo、Lightwave、Blenderなどで作成した3Dモデルをプロジェクトの中にインポートして簡単なスクリプトでゲームアプリを作成してしまうのです。その中にはiOSアプリも含まれます。試してはいませんが、上手に作ればMac, Windows, iOS, Androidのアプリを1つのソースで作ってしまう事も可能かもしれません。

物理モデルもあるので、cocos2dのような衝突判断も自前で行う必要がありません。

たぶん、ゲームに特化すれば一番早い道かも知れません。

 

ただ、僕に取って気に入らなかったのは、ロジックをいじる部分がJavaScriptで、それをiOS用にビルドしてやると、xcode用のプロジェクトが出来上がり、殆どがブラックボックスの中でxcodoから再びビルドするという部分です。

たぶん、自前でiOSのコードを追加してやろうとすると、かなり大変な事になると思いました。

それとライセンス料

iOS用のアプリを作成しようとすると最低でも400ドルかかります。しかしその中ではスプラッシュ画面はUnityのロゴのまま。影を付けたりする事も出来なさそうなのです。(バージョン対応表をご参照ください

その上のバージョンだとUnity ProとiOS Proで3,000ドル。円高になったとはいえ最初の投資としては高いかな…という感想です。

ましてやUnityで作れるのは基本的にゲームです。

私としてはOpenGL ESをゲームに特化させるつもりはありません。もちろんグラフィックスを使う上でゲームは一番の市場でしょうが、もう少し利用範囲を考えたいと思っています。

 

そしてまた次に続きます。

ん…

Road to OpenGL ES (2)

cocos2d for iPhoneを試してみる

まずはcocos2d for iPhoneを試してみる事にしたました。
cocos2dは文字通り2Dのグラフィックス・フレームワークです。多くのAPIはOpenGL ESに対応しており、多彩なグラフィックス表現ができます。

ライブラリのサンプルを実行するだけでもその機能の奥深さが伺えます。

OpenGL ESだけではなく文字列などにも対応しており、UILabelなどを使わずに日本語を表示したりも出来ます。

cocos2dにはインストーラも付いていて、これを起動するとxcodeのテンプレートをインストールしてくれます。パッケージをダウンロードしたディレクトリーに移動し、ターミナルから下記の様に実行します。


 $ ./install-templates.sh
 

これによってxcodeから”File” -> “New…” -> “New Project…” と進むと

このようにテンプレートを選ぶ事が出来ます。

Universal Applicationも作成出来ます。便利ですね。

もちろんこのプロジェクトの中で開発を進めれば効率よくエフェクトなどをインプリしたアプリが出来ると思います。

 

ただ個々で私にとって問題なのが以下の点です。

  • Interface Builderが使いにくい
  • フレーム・ワークが強く結びつきすぎている。
  • 2D

最初の2つは努力次第でなんとかなるのではないかと思います。

RootViewControllerもUIViewControllerのサブクラスですし、そこで生成されるビューもUIViewのサブクラスのEAGLViewで見慣れた感じの構成です。

3番目の2Dもエフェクトなどで3Dっぽく見せる事は可能だと思います。何より全てがオープン・ソースですので、いざとなれば将来のiOSのバージョンアップ等に対しても自分で対応は可能だと思います。

実際に今までのプロダクトの中でもcocos2dのルーチンを参考にさせてもらって部分もあります。依存関係の薄いルーチン群でしたらとても重宝に使えます。

しかしやはり今回は3Dにコダワリを持っていますので、cocos2dの採用については保留にしておく事にします。

 

xcode 4.xでのOpenGL ESテンプレート

xcode 4.xの”OpenGL Game”で生成されるテンプレートは使うつもりはありません。このテンプレートで生成されるプロジェクトがiOS 5.xをベースとしたGLKViewを使っているからです。おそらく生産性は良いのでしょうがrequirementをiOS5.0にするのには抵抗があります。OpenGL ES 2.0ベースにするだけでiPhone3Gを切り捨てなくてはなりません。そのうえiOS4.x以前を切り捨ててしまうのはマーケットの大きさとして大丈夫かな?と単純に思います。

Appleが各デバイスや各iOSの出荷数などを公表してくれれば別ですが、今の所は不採用としたいと思います。

 

 

 

 

 

 

 

 

 

 

 

 

Road to OpenGL ES (1)

例によって定期的に書いていくわけではありませんが、新たなカテゴリーとしてOpenGL ESについて少しずつ買いて行こうと思います。

 

OpenGLはSilicon Graphicsが最盛期の頃から名前だけは知っていましたが、なかなか使う機会がありませんでした。それがヒョンな事から興味の焦点が集中しリサーチをしています。

きっかけはiOS5.0から採用された Using Core Image Filters です。これを使ってアプリを作ってやろうかなと思ったのですが、Mac OS Xと比べると意外と制約が多かったりして諦めました。しかしその一方でアプリを開発する上で重要な「見た目」について掘り下げて行くと「はやり3Dかな?」なんて思うようになりました。

そんな気軽な思いで色々調べておりました。

もちろん今の時点でOpenGL ESのAPIについて詳しく知りません。サンプルのソースを見ながら「へ〜」と思う程度です。

そもそも前提となるのは以下の点です。

  • 面倒くさい事はしたくない(工数を膨らませたくない)
  • でも細かい所に手を入れられるようにしたい。
  • パフォ=マンスで妥協したくない
  • プログラマーとしての充実感も味わいたい。。

最初の障害として立ちはだかった壁は最初の「面倒くさい事はしたくない」でした。OpenGLでそのままプログラミングしようとするとどうしても三次元の座標を処理しながらAPIに渡して行かなければならないと言う事でした。

素人っぽくて申し訳ないのですが、てっきりOpenGLには「球を書く」とか「立方体を書く」くらいのAPIはあるんだと高をくくっていましたが、いざ明けてみるとそれすらも無い。

「おいおいどうするんだ?座標を全部拾えって?冗談でしょ…」と思った所で最初の障害にぶつかってしまいました。

 

ハイレベルなテクニカルの内容を期待した人がいましたら申し訳ございません。

第一回目はこのへんで…