2011/04/02

cocos2dのvertexZパラメータでソートしたい

cocos2dのCCSpriteを多数表示して、Y座標によって奥から手前へのソートを行うことで以下のような表示をする場合に、



簡単に行うには、CCSpriteクラスの中のupdateメソッドなどで現在のY座標を元にソートしなおすことを繰り返すと良いのですが。
たとえば、以下のようなコードですね。

-(void)update:(ccTime)delta {
  [self.parent reorderChild:self z:-position.y];
}

これでは結構処理が無駄になるのではないかと心配になりますよね。
で、vertexZプロパティを使うとOpenGLのZバッファを参照して前後比較をして描画してもらえるので、それを使って処理を軽くしたいと思います。
こんな感じです。

-(void)update:(ccTime)delta {
  self.vertexZ = -position.y;
}

こうすると、前後比較は正しくなるのですが、キャラクターの透明部分までZバッファに描かれてしまって四角い枠が見えるようなおかしな描画になってしまいます。
そこで、さらに以下のメソッドをオーバーライドといい感じになります。(ALPHA_TESTで透明部分はそもそも描画しないということを行ってキャラの絵が描かれている部分のみZ値を書きこむようにするということです)

-(void)draw {
  glEnable(GL_ALPHA_TEST);
  glAlphaFunc(GL_GREATER, 0.0f);
  [super draw];
  glDisable(GL_ALPHA_TEST);
}

これで万事解決ですね。
と思いますよね。
でも、さらに高速化しようとしてCCSpriteBatchNodeを使い始めると、上記のCCSpriteに設定したdrawメソッドが呼ばれなくなるために、せっかく設定したALPHA_TESTが無効化されてしまいます。
その場合は、CCSpriteBatchNodeの方のdrawをオーバーライドしましょう。
こんな感じです。(CCSpriteBatchNodeのdrawはDEPTH_TESTがデフォルトで無効になっているので、その設定も追加しています)

-(void)draw {
  glEnable(GL_DEPTH_TEST);

  glEnable(GL_ALPHA_TEST);
  glAlphaFunc(GL_GREATER, 0.0f);
  [super draw];
  glDisable(GL_ALPHA_TEST);

  glDisable(GL_DEPTH_TEST);
}

以上で楽しいcocos2dライフを送りましょうー。

0 件のコメント:

コメントを投稿