物体の表面を環境、拡散、反射それぞれの要素で色を指定できても、木目みたいな質感は再現できない。
 で、用意されたのがテクスチャマッピング。
 木目なら木目画像を物体表面に貼り付けてごまかしちまえ~という荒技。

テン・シー・シー-1

 今回は、このテクスチャマッピングをお勉強。
 OpenGL ES側のサンプルソースは、割とあるというか、「iPhoneアプリ開発、その(101)」のlesson07.c使えばいいわけですが、iPhone OSでは、テクスチャ画像をどういった画像フォーマット提供すればいいのかとか興味があったので、またまたテクスチャ関係のサンプル探しの旅へ行ってみました。
 自分探しの旅なんぞには一生行かないけどな~!

Phone Dev Center > iPhone Reference Library > Frameworks > Media Layer: OpenGL ES

 で、この中で
  • Creating textures in the PVRTC compression format
     テクスチャ画像の容量を小さく(ただしJPEGと同じで圧縮率を上げると、細部の描写力は低下する)するために、PVRTCというテクスチャ画像フォーマットの画像を使用するのがいいです。その作成ツールの使い方を説明しま~す。

てのが、あって、そこで紹介されてる、PVRTC画像を読み込んでOpenGLのテクスチャに指定するサンプルソースが
  • PVRTextureLoader
     このアプリはPVRTC画像ファイルをプロジェクトに含まれているPVRTextureクラスを使い読み込み、それらをOpenGLで表示する方法を提示する。プロジェクトのビルド段階で埋め込まれたサンプル画像は回転可能で縮小拡大可能な四角形上に再現され、さまざまな圧縮率、フィルタリング設定でコントロールできる。

 ここらへんが利用できそう。
 PVRTextureLoaderをダウンロードして開いた直後はこんな感じ。

テン・シー・シー-2
この赤いBrick_2.pvrやBrick_4.pvrてのが、PVRTC画像ファイルみたいです。

 赤いってことは、存在してないってことだけど、とりあえずビルド。
 おお、ちゃんと動いた。

テン・シー・シー-3

 圧縮(Compression)とか、ミップマップ(Mipmap Filter)、補間方法(Texture Filter)なんかが指定できるようになっとるわけね。

ミップマップ、補間方法については、 以下のページがわかりやすいと思う。

http://www.komoto.org/opengl/sample09.html

で、軽く設定をいじって画像の変化を見終わったら終了させる。

テン・シー・シー-4
プロジェクトに戻ってみるとBrick_2.pvrやBrick_4.pvrが黒文字になってました。

 観察力のある人は気づいたと思うけど、ビルド時にカスタムシェルスクリプトって作業が発生してて、ここで作られてたようです。

テン・シー・シー-5

 このカスタムシェルスクリプトは、ターゲット/PVRTextureLoader/Encode Imagesてのをダブルクリックすると内容を見ることができるっす。

テン・シー・シー-6

 このスクリプトは元々のBrick.png画像からBrick_2.pvrやBrick_4.pvrなんかを作るためのもので、Creating textures in the PVRTC compression formatで説明されてるものなんだけど、今回はPVRTC画像使うつもりないんで、深く掘り下げない。

テン・シー・シー-7

 まずは、アプリ起動時に、どのクラスが呼び出されていくかをチェックするべく、MainWindow.xibをダブルクリックしてInterface Builderを起動だ~。
 ここらへんは「iPhoneアプリ開発、その(30)」を読み返してちょ(今回の場合は、xibファイルが2つに分かれてるわけじゃないんで、もう少し単純です)。

 xibファイル読み込み時は、File's Ownerの設定が読み込まれるわけで、ここでOutletsとして指定されてるTexture Loader App Delegateがアプリケーションのdelegateに設定されるわけです。

テン・シー・シー-9

 delegateに指定されたTexture Loader App DelegateをみるとTypeはPVRTextureLoaderAppDelegateで、OutletsにviewControllerがMy View Controllerを指定。

テン・シー・シー-10

 My View ControllerのTypeはMyViewController、ちゅーわけで、解析はMyViewControllerのviewDidLoadメソッドあたりから攻めるのが吉とでた。

テン・シー・シー-11
ちなみにMy View ControllerのOutletsとしてviewに指定されてるのは、おなじみEAGLView。

 Xcodeに戻ってMyViewController.mのviewDidLoadメソッドをみると、しょっぱなで_controlViewを追加してますな。

- (void)viewDidLoad
{
_controlView = [[ControlView alloc] initWithFrame:...



 読んでいくと、なんか画面とかなり重なり合う文字列がいっぱいなわけで、_controlViewはテクスチャマッピングの設定をGUIで変更可能にするためのコントローラビューなんだってのがわかります。
 UISegmentedControl使ってますな。このやり方パクったら前回の環境、拡散、反射のテストできるっぽいね。

テン・シー・シー-12

 ま、特にOpenGLのテクスチャマッピング関係の直接操作APIは見当たらないので、本丸のEAGLViewに進む。
 やっぱ最初に見るのは

initWithCoder

ですわ。
 あれ?マルチタッチ対応してる。touchesMoved読むと、平面への引きや寄りもできるようにしてたのがわかる。エミュレータしか使ってないから気づかなかった。ま、それはいいや。

_textures

てのが、OpenGL用のテクスチャ画像っぽいですな。

glBindTexture(GL_TEXTURE_2D, _textures[_texSelection]);

なんてのがあるし、

_texSelection

を探ってみると

kTexturePvrtcMipmap4,
kTexturePvrtcMipmap2,
kTexturePvrtc4,
kTexturePvrtc2,
kTextureMipmap,
kTexture,

のいずれかの値をとって、設定してるのはupdateSettingsメソッドで、画面のキーワードがかなり連動してるんだよね。

テン・シー・シー-13

 それを元にloadTexturesメソッドなんかを読み進むと、PNG画像を読み込んでテクスチャとしてダイレクトに使えるみたいですな。
 とりあえず、今回はPVRTC画像ファイルはおいといて、PNG画像を使う限定でやってみましょう。

 createFramebufferやdestroyFramebufferメソッドでは、Zバッファの時と違って特に必要な追加はないようです。drawViewメソッドでは

glTexCoordPointer(2, GL_FLOAT, 0, squareTexCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);

てのが、平面上に画像をどう配置するかの指定っぽい。

glBindTexture(GL_TEXTURE_2D, _textures[_texSelection]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _minTexParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _magTexParam);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, _anisotropyTexParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

はテクスチャマップの細かな調整だな。とりあえず今回は

_minTexParam = GL_NEAREST
_magTexParam = GL_NEAREST
_anisotropyTexParam = 1.0f;

固定として考えてみます。となれば、あとはPNG画像の読み込みのみということでloadImageFileメソッドが、そのままパクれそう。
 パクって前回のes6プロジェクトに組み込んでみますた。es6に追加した箇所は

#if TEXTUREMAPPING_TEST
#endif

で囲んでます。これが最小限テクスチャマップに必要な作業てことになる。PNG扱うのでCoreGraphics.frameworkの追加も必要。

テン・シー・シー-frog
PNG画像は大好きなカエル先生を指定、さてさて。

テン・シー・シー-14
げ~えええ、あ、青い。

 て、いやいや、落ち着け、ドイツ軍人はうろたえないいいい。
 素材色、青色にしたままだからだな。たぶん。なので、素材色RGBを0.0,0.0,0.8から0.8,0.8,0.8に変更。

テン・シー・シー-15
ほらね。ありゃ、上下逆さま...

ま、いいか。
以下次回!

------------
サンプルプロジェクト:es7.zip