でらうま倶楽部

バカってゆうか、ゲームを作る事しか能の無いプログラマの、面白おかしな日々を綴ってみる実験。

2012年12月

iPhoneでモデルデータを読み込むなら「assimp」をオススメ

dragonsplash
今回も相変わらずニッチでマニアックなネタなので、iPhoneでObjective-Cでうんぬんかんぬん的な人は軽ぅくスルーして頂いて結構です…

拙作『こなへん』では宇宙空間に浮かぶ地球のデータは、プログラムで生成するようにしていました。球体をプログラムで生成するのはそんなに難しくないです。

じゃあ次はアヒル隊長やはちゅねミクさんを表示しようとしてみて困りました。さすがにアヒルを計算で生成するのはちょっと自分のスキルでは難易度高い…。

じゃあ、モデリングツールを探して、それを使ってみようかしらんと考える訳ですが…

  • データ形式はどれがいいの?
  • アプリでモデルデータを読み込んで表示するのにどうしたらいいの?

という事で困る訳です。モデルデータの仕様にはいくつかあって、どれも仕様を読み解くのに時間が掛かりそう…。
そしたら…なんと!この問いに答えてくれるライブラリを見つけました。


何と、以下のフォーマットのモデルデータを読み込んで、共通の内部形式にしてくれるという素晴らしいライブラリです。

Collada ( *.dae;*.xml )
Blender ( *.blend )
Biovision BVH ( *.bvh ) 
3D Studio Max 3DS ( *.3ds ) 
3D Studio Max ASE ( *.ase ) 
Wavefront Object ( *.obj ) 
Stanford Polygon Library ( *.ply ) 
AutoCAD DXF ( *.dxf ) 
IFC-STEP, Industry Foundation Classes ( *.ifc )
Neutral File Format ( *.nff ) 
Sense8 WorldToolkit ( *.nff ) 
Valve Model ( *.smd,*.vta )
Quake I ( *.mdl ) 
Quake II ( *.md2 ) 
Quake III ( *.md3 ) 
Quake 3 BSP ( *.pk3 )
RtCW ( *.mdc )
Doom 3 ( *.md5mesh;*.md5anim;*.md5camera ) 
DirectX X ( *.x )
Quick3D ( *.q3o;q3s )
Raw Triangles ( .raw )
AC3D ( *.ac )
Stereolithography ( *.stl )
Autodesk DXF ( *.dxf )
Irrlicht Mesh ( *.irrmesh;*.xml )
Irrlicht Scene ( *.irr;*.xml )
Object File Format ( *.off )
Terragen Terrain ( *.ter ) 
3D GameStudio Model ( *.mdl ) 
3D GameStudio Terrain ( *.hmp )
Ogre (*.mesh.xml, *.skeleton.xml, *.material)
Milkshape 3D ( *.ms3d )
LightWave Model ( *.lwo )
LightWave Scene ( *.lws )
Modo Model ( *.lxo )
CharacterStudio Motion ( *.csm )
Stanford Ply ( *.ply )
TrueSpace ( *.cob, *.scn )
XGL ( *.xgl, *.zgl )

なんかめっちゃある…。しかもCとC++の両方で使えるという訳でテンション上がりまくりんぐ。Windows、OSX、LinuxをサポートしてるんだったらきっとiOSでも使えるよね!という事で挑戦してみました。

ポータルサイトからソースをダウンロード…でもいいのですが、githubに最新版が置いてあるのでそっちからダウンロードしましょう。Windowsの人はdllファイルが同梱されているのでそれを使えばいいと思います。OSXの場合Xcodeのプロジェクトが同梱されています。
 
photo01
ちなみに、ビルドするには先日ビルドしたboostが必要となります。PROJECT->assimp->Build Settings->Header Search Pathsで、boostのヘッダファイルの場所を指定しておいてください。

photo2
もし自分のプロジェクトでboostを使っていなかったり、今後も使う予定が無ければ、PROJECT->assimp->Build Settings->Preprocessor MacrosASSIMP_BUILD_BOOST_WORKAROUNDを指定しておけば、assimpに同梱されているboostのライブラリを使ってビルドが行われます。

さて。OSXはビルドしてできた.aを自分のプロジェクトで使えばいいのですが、iOSの場合は、boostと同じく、実機とシミュレーターで2回ビルドして、2つの.aをlipoで1つにまとめます。ターミナルを立ち上げて、ライブラリが生成された場所をカレントにしたら、

lipo -create Release-iphonesimulator/libassimp.a Release-iphoneos/libassimp.a -output libassimp.a

みたいな感じですね。

photo3
さてついでに、簡単なサンプルも用意してみたので、実際に読み込んでみましょう。サンプルではCheetah3Dというモデリングソフトから書き出したColladaファイル(.dae)を読み込んで表示しています。あいかわらずヘッダファイルしかない実装ですいません。

ちなみに「自分は.objしか使わないから、他のは余分…」という場合、ビルド時にプリプロセッサにASSIMP_BUILD_NO_3DS_IMPORTERとかASSIMP_BUILD_NO_Q3BSP_IMPORTERとか指定すれば、使わない読み込み処理をコンパイルしないでライブラリのサイズを小さくする事ができます。詳しくは同梱されているヘルプのExtending the Libraryを読んでみてください。

3Dモデルやアニメーションデータは使うツールによってまちまちで、いちいち仕様を解析して読み込み処理を実装する必要に迫られて凹むのですが、もうこれで悩まされる事も無くなりそうな勢いです。assimpかしこいよassimp。


ではまた次回!

間違いやすい「iPhoneで異方性フィルタリング」

09
iPhoneやiPadでも使える異方性フィルタリング!

投影方向に対してキツい傾斜の状態で、ミップマップ有りのテクスチャをより奇麗に描画する技術で、もちろん拙作「こなへん」でも設定を…してたはずだったのですが…!

設定を間違ってました。

えっと…すいません!
正しくは以下の通り!

GLfloat max_aniso;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_aniso);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso);
GL_TEXTURE_MAX_ANISOTROPY_EXTと書くべきところをGL_MAX_TEXTURE_MAX_ANISOTROPY_EXTと書いてしまっていました…。

び、微妙な違い…!

ちなみにXcode4.5以降のOpenGL ES Analysisでは、この間違ったパラメータ設定で落ちてしまう不具合があったのですが、ちゃんと直ってました。アップルさんすいません…。

ではまた次回!

C++ 初心者だって Boost が iPhone で使えるんだぜ!

C++ Advent Calendar 2012参加中!

今年は、生まれて始めてC++で書いたiPhoneアプリ「こなへん」をリリースした特別な一年でした。

信じられないかと思われるんですが、本当にC++は初めてだったんです!

ゲーム業界の片隅で20年以上プログラムを書いてる人のいう台詞じゃないですよね…すいません。

でもそれが現実なんだよ!

これまで何度もそのチャンスはあったんですが、なんかこうズルズルと(言い訳)

ここ数年のC++の参考書の充実っぷりは目を見張りますね。結局のところ、リファレンスを読んでstd::stringとstd::vectorの使い方を覚えたらあとはすんなりでした。単なる食わず嫌い。

でもまだ多重継承とかテンプレートメタプログラミングとかよくわからないよ!よくわからないんだけど…でもとにかく一つ、完結したものを作ったことでC++に対する理解と自信が深まったと思います。

そんなC++暦も三年目に突入。そこで、なんかこう…新しいことに挑戦しようと思って、目についたのが…先輩らがせっせと布教しているboost

今日の時点での最新バージョンは1.52.0。アキラさんいつも懇切丁寧な翻訳ありがとうございます。WindowsとOSXなら、boost.jpを見て導入すれば間違いないです。

ところで…boost.jpにはOSXとWindowsの手順は書いてあるんだけど、iOSの場合どーすんの?という訳でさっそく調べて導入してみたので以下そのメモ書きです。

その前にOSXとWindowsでの導入をおさらい。もう知ってる人はすっ飛ばして読んでね!

まずはOSXの場合
コンソールを起動して、ダウンロードしたboostのファイルのある場所をカレントディレクトリにしたら
./bootstrap.sh
./b2 install -j2 --prefix=/Users/nishi/src/boost
これで ~/src/boost/include にヘッダファイル、~/src/boost/lib にライブラリファイルが生成されます。
 
photo02
boostヘッダのインクルードファイルのパスはXcodeのPROJECTのHeader Search Paths に追加。

photo01

ライブラリファイルの方は、XcodeのTARGETSのLinked Frameworks and Librariesに.aファイルを適時追加する方式。このとき、ライブラリファイルのパスはプロジェクトに自動的に追加されます。んで、libの中にある.dylibは全部削除。

これで設定は完了!

Windowsの場合
コマンドプロンプトを起動して、ダウンロードしたboostのファイルのある場所をカレントディレクトリにしたら
bootstrap.bat
b2.exe install -j2 --prefix=C:\Users\nishi\Documents\src\boost
これで ~/src/boost/include にヘッダファイル、~/src/boost/lib にライブラリファイルが生成されます。

photo03
んで、VisualStudioの設定で、インクルードパスとライブラリパスにboostのパスを追加したら設定完了!Windowsの方は.libファイルを追加する作業が無いのでちょっと楽です。

iOS向けビルド!
まだXcodeのコマンドラインツールラインツールをダウンロードしてない人はまずそいつをダウンロード。そしたらコンソールを起動して、ダウンロードしたboostのファイルのある場所をカレントディレクトリにしたら
./b2 toolset=clang cflags="-arch armv7 -fvisibility=default -miphoneos-version-min=5.0" architecture=arm target-os=iphone link=static threading=multi define=_LITTLE_ENDIAN include=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include/
でビルド。stage/libにライブラリファイルが生成されるので、名前をlib→lib_armv7に変えて、
./b2 toolset=clang cflags="-arch armv7 -fvisibility=default -miphoneos-version-min=5.0" architecture=arm target-os=iphone link=static threading=multi define=_LITTLE_ENDIAN include=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include/ --clean

./b2 toolset=clang cflags="-arch armv7s -fvisibility=default -miphoneos-version-min=5.0" architecture=arm target-os=iphone link=static threading=multi define=_LITTLE_ENDIAN include=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include/
と、いったんクリーンしてからビルド。stage/libにライブラリファイルが生成されるので、名前をlib→lib_armv7sに変えて、
./b2 toolset=clang cflags="-arch armv7s -fvisibility=default -miphoneos-version-min=5.0" architecture=arm target-os=iphone link=static threading=multi define=_LITTLE_ENDIAN include=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include/ --clean

./b2 toolset=clang cflags="-arch i386 -fvisibility=default -miphoneos-version-min=5.0" architecture=x86 address-model=32 target-os=iphone link=static threading=multi include=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/iPhoneSimulator6.0.sdk/usr/include/
と、再びクリーン&ビルド。stage/libにライブラリファイルが生成されるので、名前をlib→lib_x86に変える。

これで3つのアーキテクチャー(armv7、armv7s、x86)のライブラリが生成されたことになります。

そしたら、これを合体します。この作業は、stage/lib を生成したら、stageをカレントにして、
lipo -create lib_armv7/libboost_chrono.a lib_armv7s/libboost_chrono.a lib_x86/libboost_chrono.a -output lib/libboost_chrono.a
lipo -create lib_armv7/libboost_context.a lib_armv7s/libboost_context.a lib_x86/libboost_context.a -output lib/libboost_context.a
lipo -create lib_armv7/libboost_date_time.a lib_armv7s/libboost_date_time.a lib_x86/libboost_date_time.a -output lib/libboost_date_time.a
lipo -create lib_armv7/libboost_exception.a lib_armv7s/libboost_exception.a lib_x86/libboost_exception.a -output lib/libboost_exception.a
lipo -create lib_armv7/libboost_filesystem.a lib_armv7s/libboost_filesystem.a lib_x86/libboost_filesystem.a -output lib/libboost_filesystem.a
lipo -create lib_armv7/libboost_graph.a lib_armv7s/libboost_graph.a lib_x86/libboost_graph.a -output lib/libboost_graph.a
lipo -create lib_armv7/libboost_iostreams.a lib_armv7s/libboost_iostreams.a lib_x86/libboost_iostreams.a -output lib/libboost_iostreams.a
lipo -create lib_armv7/libboost_math_c99.a lib_armv7s/libboost_math_c99.a lib_x86/libboost_math_c99.a -output lib/libboost_math_c99.a
lipo -create lib_armv7/libboost_math_c99f.a lib_armv7s/libboost_math_c99f.a lib_x86/libboost_math_c99f.a -output lib/libboost_math_c99f.a
lipo -create lib_armv7/libboost_math_c99l.a lib_armv7s/libboost_math_c99l.a lib_x86/libboost_math_c99l.a -output lib/libboost_math_c99l.a
lipo -create lib_armv7/libboost_math_tr1.a lib_armv7s/libboost_math_tr1.a lib_x86/libboost_math_tr1.a -output lib/libboost_math_tr1.a
lipo -create lib_armv7/libboost_math_tr1f.a lib_armv7s/libboost_math_tr1f.a lib_x86/libboost_math_tr1f.a -output lib/libboost_math_tr1f.a
lipo -create lib_armv7/libboost_math_tr1l.a lib_armv7s/libboost_math_tr1l.a lib_x86/libboost_math_tr1l.a -output lib/libboost_math_tr1l.a
lipo -create lib_armv7/libboost_prg_exec_monitor.a lib_armv7s/libboost_prg_exec_monitor.a lib_x86/libboost_prg_exec_monitor.a -output lib/libboost_prg_exec_monitor.a
lipo -create lib_armv7/libboost_program_options.a lib_armv7s/libboost_program_options.a lib_x86/libboost_program_options.a -output lib/libboost_program_options.a
lipo -create lib_armv7/libboost_python.a lib_armv7s/libboost_python.a lib_x86/libboost_python.a -output lib/libboost_python.a
lipo -create lib_armv7/libboost_random.a lib_armv7s/libboost_random.a lib_x86/libboost_random.a -output lib/libboost_random.a
lipo -create lib_armv7/libboost_regex.a lib_armv7s/libboost_regex.a lib_x86/libboost_regex.a -output lib/libboost_regex.a
lipo -create lib_armv7/libboost_serialization.a lib_armv7s/libboost_serialization.a lib_x86/libboost_serialization.a -output lib/libboost_serialization.a
lipo -create lib_armv7/libboost_signals.a lib_armv7s/libboost_signals.a lib_x86/libboost_signals.a -output lib/libboost_signals.a
lipo -create lib_armv7/libboost_system.a lib_armv7s/libboost_system.a lib_x86/libboost_system.a -output lib/libboost_system.a
lipo -create lib_armv7/libboost_test_exec_monitor.a lib_armv7s/libboost_test_exec_monitor.a lib_x86/libboost_test_exec_monitor.a -output lib/libboost_test_exec_monitor.a
lipo -create lib_armv7/libboost_thread.a lib_armv7s/libboost_thread.a lib_x86/libboost_thread.a -output lib/libboost_thread.a
lipo -create lib_armv7/libboost_timer.a lib_armv7s/libboost_timer.a lib_x86/libboost_timer.a -output lib/libboost_timer.a
lipo -create lib_armv7/libboost_unit_test_framework.a lib_armv7s/libboost_unit_test_framework.a lib_x86/libboost_unit_test_framework.a -output lib/libboost_unit_test_framework.a
lipo -create lib_armv7/libboost_wave.a lib_armv7s/libboost_wave.a lib_x86/libboost_wave.a -output lib/libboost_wave.a
lipo -create lib_armv7/libboost_wserialization.a lib_armv7s/libboost_wserialization.a lib_x86/libboost_wserialization.a -output lib/libboost_wserialization.a
で、ライブラリファイルがstage/libに出来てたら成功!

あとはOSXの時と同じ要領でboostのヘッダやらライブラリファイルを追加すれば、実機でもシミュレーターでもboostが使えるようになっているでしょう。

ただしこの作戦でひとつだけ問題が。ビルドの際に「iconvかicuライブラリが無いからBoost.Localeがビルドできないよー」って言われるんですが…これマズいですよね…

あと、ちょっと古いバージョンのboostではXcodeのプロジェクトを生成できるみたいなんですが、今はどーなってるんでしょうかね…

とりあえずそなへんのことは置いといて、boostを使う練習を始めます。

そして…明日の C++ Advent Calendar 2012狂える中3女子ボレロ村上 さんです。
わくわくしますね!

ではまた次回!

これからは1つのプロジェクトでiOSとOSXのアプリを同時に作ろう

new_hero20110308
えーっと。

個人的に「きっとできそうなんだけどなぁ… できたらいいなぁ…」と思っていたXcodeのプロジェクトをiOSとOSXで共用する作戦が実に見事に成功したので、そのメモ的な。

自分のアプリはOSXでもiOSでもWindowsでも実行出来るように作っています。実機に転送したり、シミュレーターを起動してうんぬんかんぬん…がめんどくさい…せっかちさん!

なので、普段はOSX向けのプロジェクトでビルドとテストをしていて、ちょいちょいiOS向けプロジェクトに切り替えてビルド…みたいな。
photo02
それもめんどくさーい!XcodeでOSXとiOSの2つのプロジェクトが開いてる状態がすでにめんどい!

その時、先輩がiOSアプリのフル版とライト版を1つのプロジェクトで賄っているというのを耳にしました。

ひみつはターゲット設定にあるらしい…

というわけで、プロジェクト内にiOSの2つのビルド設定を持てるなら、OSX用とiOS用とかでもイケるでしょ!と設定をごにょごにょしたら…できました!
photo01
Xcodeえらい!!

基本的な設定をPROJECTのBuild Settingsに書いて、iOSとOSXで違う設定を、TARGETSのBuild Settingsに書くだけでいけます。
 
phoro03
フレームワークやライブラリもちょいちょいちょいと個別に指定できます。楽!

photo05
どっちのターゲットのビルドで使うのかは、ここで指定します。iOS用の.xibファイルはOSXのビルドには必要ないですからね。ちゃんと確認しておきましょう。
 
photo04
どの設定でビルドするかはスキームで選ぶだけ。誰ですか!スキーム使いにくいよって言ってたのは!!

という感じであっさり実現出来てしまったのですが…これはだらだらとブログで解説するより実際に設定を追ってもらった方がいいと思ったので、雛形のプロジェクトを公開しておきました。お暇なときにでもダウンロードして開いてみてちょ。githubとか使えなくてすいません…

そして私もC++ Advent Calendar 2012にも参加していますので、そちらもお楽しみに…って、自分の出番あさってだがね!(焦)


ではまた次回!
記事検索
電子書籍発売中

「チュートリアル形式で始めるOpenAL」
サウンド怖くない。C++による8つのチュートリアルで始めるOpenALプログラミング。さああなたも、自作アプリに魅力的な音効を添えてみませんか??
⇒Kindle版 ⇒iBooks版


「iPhoneアプリ『ういろう』のレシピ」
ゲームってどうやって作ってるの?? 拙アプリ『ういろう』の製作過程を本にまとめました。もちろんソースコードつき
⇒Kindle版 ⇒iBooks版


『チュートリアル形式で始めるOpenGL[2D編]』
OpenGL怖くない。C++による16のチュートリアルで始めるOpenGLプログラミング[2D編]。さああなたも、ゲーム作りを始めてみませんか?
⇒Kindle版 ⇒iBooks版
自作ゲーム配信中

『Puzzle & Monarch』
「君主候補となって国作り!! ただし制限時間は90秒。」森を作って道をつないで...あなただけの国を作ってみませんか??
⇒AppStore


『BRICK & TRIP』
咄嗟の判断に、あなたの指先はついてこれるか?! 爽快フリックアクション!! 様々な難関をくぐり抜けて旅の終着点を目指そう!!
⇒AppStore


『ういろう』
名古屋土産ういろうがiPhoneで大活躍?! 白ういろうを守れるのはあなただけ。ひゅーん、ぼよよーん!!
⇒AppStore ⇒LITE版


『こなへん』
ヒマラヤ山脈、大西洋、世界で一番深い湖… それって地球のどこにあるのか知ってるかな?『全方位直感地理クイズ』という新ジャンルに挑戦!あ、それ。地球をくーるくるw
⇒AppStore ⇒LITE版


『GEOSPOT』
ヒマラヤ山脈、大西洋、世界で一番深い湖… それって地球のどこにあるのか知ってるかな?『全方位直感地理クイズ』という新ジャンルに挑戦!あ、それ。地球をくーるくるw
⇒Windows ⇒Mac


『TieGunner』
マウス片手に大宇宙へ飛び立とう!『しっぽシューティング』というジャンルを作って頂きました^^; WinでもMacでも動きます。ソースもあるでよw
⇒Windows ⇒Mac
QRコード
QRコード
  • ライブドアブログ