タイトルCocoaはやっぱり!出張版》8. OpenGLを使う(5)カテゴリーグラフィックス, Cocoa, 鶴薗賢吾のCocoaはやっぱり!出張版
作成日2002/2/19 14:2:5作成者新居雅行
その後、texImgRepというNSBitmapImageRepクラスのインスタンスを生成していますが、これは、このNSBitmapImageRepを経由することで、圧縮などが行われていない生のビットマップデータをbitmapDataメソッド取り出すことが出来るためです。テクスチャー生成のためには、OpenGLに生のビットマップデータを渡す必要があるのです。

glPixelStoreiでメモリへの格納形式を指定し、glGenTexturesで空のテクスチャーを生成します。ここでテクスチャーのIDが返ってきます。glBindTextureはテクスチャー操作関数の対象を変更する関数なので、生成したテクスチャーに変更します。そして、glTexImage2Dでテクスチャーのビットマップイメージを送り込みます。

glTexImage2Dのパラメータのところに [ imgTexRep hasAlpha ] ? GL_RGBA : GL_RGB という記述があります。TIFFフォーマットのようにアルファチャンネル ( 透明度情報 ) を画像に含んでいる場合がありますので、その場合のために、データの並びをこのような記述で切り替えています。

 ★ NSImageRep : アルファチャンネルを持っているか
  [書式] - (BOOL) hasAlpha
  [出力] 返り値 : アルファチャンネルを持っている場合 - YES、ない場合 - NO

最後のパラメータで、生のビットマップデータを渡しますが、これは、NSBitmapImageRepのbitmapDataメソッドを使います。

 ★ NSBitmapImageRep : ビットマップの生データを取得
  [書式] - (unsigned char *) bitmapData
  [入力]
  [出力] 返り値 : ビットマップデータの生データの存在する先頭のアドレスを返す

なお、アルファチャンネルを画像に含んでいる場合は、テクスチャー上データもアルファチャンネルを持つことになり、そのテクスチャーが貼られた四角形上のピクセルも、そのアルファチャンネルに従って透明になります。Mac OS Xに標準添付のAqua Iconsスクリーンセーバーでは、アプリケーションアイコンが飛び交っていますが、ここに書いているのと同様の方法で実現していると思われます。

◎ テクスチャーの描画
続いては、テクスチャーを貼り付けた四角形の描画です。以下のような、drawRectTextureId : alpha : というメソッドを定義します。指定したIDのテクスチャーを指定の透明度で表示するものです。

//ソース:MyOpenGLView.m、メソッド:drawRectTextureId : alpha :

- (void) drawRectTextureId : (GLuint) texId
alpha : (float ) alpha {

glColor4f( 1.0, 1.0 ,1.0, alpha ); // 四角の色を透明度付きで指定
glBindTexture( GL_TEXTURE_2D, texId ); // テクスチャー指定

glBegin( GL_QUADS ); {

glTexCoord2f( 0.0, 1.0 ); // テクスチャーの左上をマッピング
glVertex2f( -1.0, -1.0 ); // 左下の頂点

glTexCoord2f( 1.0, 1.0 ); // テクスチャーの右上をマッピング
glVertex2f( +1.0, -1.0 ); // 右下の頂点

glTexCoord2f( 1.0, 0.0 ); // テクスチャーの右下をマッピング
glVertex2f( +1.0, +1.0 ); // 右上の頂点

glTexCoord2f( 0.0, 0.0 ); // テクスチャーの左下をマッピング
glVertex2f( -1.0, +1.0 ); // 左上の頂点

} glEnd();

glBindTexture( GL_TEXTURE_2D, 0 ); // テクスチャー指定解除

}

glColor4fの4つ目のパラメータでこの四角形の透明度を指定します。そして、対象のテクスチャーをglBindTextureで指定してから四角形の描画になります。グラデーション付きの四角形の時には、各頂点の色を指定していましたが、テクスチャーの場合は、テクスチャー上のどこの座標をこの頂点に割り付けるかをglTexCoord2fで指定します。テクスチャーのイメージ全体には、左下 ( 0.0, 0.0 ) 〜 右上 ( 1.0, 1.0 ) という座標系が割り当たっています。

よく見ると、テクスチャーを上下反転してマッピングしていることが分かると思います。実は、そのままマッピングすると画像が上下反転して表示されてしまうためです。多分、ビットマップのデータの上下の並びが、OpenGLが期待しているものとNSBitmapImageRepのbitmapDataメソッドが返すものとが逆だからだと思いますが、このようにして回避しています。

◎ テクスチャーとアルファチャンネルのための初期化
テクスチャーとアルファチャンネル を使うためには、OpenGLに対していくつかの初期化が必要です。そこで、initWithFrame : の末尾に以下のコードを追加します。

//ソース:MyOpenGLView.m、メソッド:initWithFrame :

- (id) initWithFrame : (NSRect) rect {
: 省略

// テクスチャー関連

glEnable( GL_TEXTURE_2D ); // 2Dテクスチャーを使用可能する
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // 拡大
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); // 縮小


// 半透明関連

glEnable( GL_BLEND ); // アルファブレンディングを使用する
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // ブレンド時の演算を選択

return( self );

}

glEnableは、OpenGLの機能のどれかをオンにするための関数です。パラメータにGL_TEXTURE_2Dにすることでテクスチャー機能が使えるようになります。glDisableというオフにする関数もあります。glTexParameteriは、テクスチャーに関する設定を行う関数で、ここでは、テクスチャーの拡大や縮小で用いる画像補間アルゴリズムを設定しています。GL_TEXTURE_MAG_FILTERで拡大時の指定、GL_TEXTURE_MIN_FILTERで縮小時の指定が出来ます。GL_LINEARは直線補間になります。GL_NEARESTを使うと一番近いピクセルを使って補関することができます。このアルゴリズムの場合、画質は低下しますが、描画は高速になります。用途やマシンスピードに応じて使い分けをすることができます。

glEnable( GL_BLEND ) でアルファブレンディング ( 透明度を考慮した画像描画処理 ) を可能にします。glBlendFuncは、ブレンド処理の時の演算種別を指定します。通常はこのままで構いません。そして、この実行結果のサンプルは以下のようになります。カエルの絵をテクスチャーとして貼り付けた四角形を描いています。

◇テクスチャー付きの四角の描画結果
 

アルファチャンネルを持たせてあるので、カエルの形状に切り抜かれた四角形として描画されています。

ここまでの内容で、画像のクロスフェードまではできるようになります。次に現れるべき画像を最初に描いておいて、消えていく画像を透明度を時間とともに高くしながらかぶせて描画していくだけです。回転なども先程のメソッドで出来ます。
‥‥‥‥‥‥‥この項、続く‥‥‥‥‥‥‥[鶴薗賢吾]‥‥‥‥‥‥‥
関連リンクCocoaはやっぱり!