Cocos2d-x であるプロジェクトを開発していたときに「CCSprite を移動させているとビデオをブロックノイズのようなものが発生する」という問題が発生しました。

ちょうど YouTube に同じような問題が発生しているビデオがありました。
こちらを見ていただいたほうが状況がわかりやすいと思います。


状況は

  • Z-Order は全てのスプライトでユニークになるように設定している。
  • またスプライトの重なり方で発生したり、しなかったりする。

そこで問題を切り分けるためにテストプロジェクトを作成して問題を簡略化してみたところ、行き着いたのは以下の様なコードになりました。

// CCLayer に2つのスプライト追加
CCSize size = CCDirector::sharedDirector()->getWinSize();

CCSprite* test = CCSprite::spriteWithFile("bigImage_0_0.png");
test->setPosition(ccp(345, 345));
this->addChild(test, 1);

CCSprite* sprite = CCSprite::spriteWithFile("Default.png");
sprite->setPosition(ccp(size.width/2, size.height/2));
this->addChild(sprite, 10);

このコードを実行したのが以下のスクリーンショットです。(cocos2d-x のロゴ画像の上の部分の表示がおかしくなっています)

X or Y座標を 1px でもずらせば発生しません。また違う座標でも発生することがあります。

悩んでたどり着いた答えがこれでした。
how to avoid the blink while move a big size texture (like 640*960) in cocos2d-x

OpenGL の GL_DEPTH_TEST を Disable にするというもの。
これは 3D 描画するときなどに視点により見える部分が変わるので見えない面を消去する必要があります。それを有効にするかどうかという設定です。Cocos2d でもエフェクトなどで 3D 描画するときがあるのでデフォルトでは有効になっています。

cocos2d でも同様の問題があるようで iPad2 が出た時に下記のようなフォーラムのやり取りがありました。
Screen flicker on iPad2

cocos2d の中の人が iPad2 のバグかもしれないということで Apple のフォーラムにも書いています。
iPad 2 + Z buffer + “big” quads on same Z produces artifacts

Apple の中の人は同じ Z-Order だからだと言っているようですが、私のコードでは違う Z-Order でも発生しています。
iPad2 以外でも new iPad, iPhone4S, iPhone5 と最近の機種ではいずれでも発生します。OpenGL は詳しくないのですが、OpenGL の問題なのでしょうか。

回避方法は先にも書いた通り「GL_DEPTH_TEST」を無効にすることです。

CCDirector::sharedDirector()->setDepthTest(false);

ただし、3Dエフェクトが正しく描画されなくなるので、3Dエフェクトを使用する際には有効に戻す必要があります。

関連する投稿