LoginSignup
1
1

More than 5 years have passed since last update.

cocos2d-xでArmatureにシェーダを反映させる

Last updated at Posted at 2015-02-06

cocos2d-xでETCのアルファマスクをシェーダを使って実装する際にArmatureで苦戦したので残しておこうと思います。
とりあえず調べた限りは日本語による記事は存在しなかったので何か役に立てば嬉しい。
(なお中国語の記事はあった模様。というかそれを参考にした。)

とりあえず書いてみた

hoge.cpp
// 初期化系統の処理内にぶち込む
void onEnter()
{
   // 頂点シェーダとフラグメントシェーダを使ってシェーダを作成
   auto shader = GLProgram::creatWithByteArrays();
   auto shader_state = GLProgramState::getOrCreateWithGLProgram(shader);

   // 自前のシェーダをセット
   setCustomShader(shader_state, getChildren());
}

// シェーダセット
void setCustomShader(GLProgramState *glpstate, Vector<Node*>& childrens)
{
   if(chidrens.empty()) return;

   for(auto& child : childrens)
   {
       // 再帰
       setCustomShader(glpstate, dhild->getChildren());

       // dynamic_castでSpriteに
       auto sp = dynamic_cast<Sprite*>(child);

       // nullptrじゃなければシェーダ突っ込む
       if(sp != nullptr){
         sp->setGLProgramState(glpstate);
       }
   }
}

と上記の書き方で基本的には対応出来たけど、Armatureだけ見事にマスク効いてない。
どうやらArmatureは違うらしい。

Armatureの中を潜っていくと...

いた。
Armature -> Bone -> DecorativeDisplay -> Node に対してシェーダ突っ込まないと駄目らしい。
なので

auto arm = dynamic_cast<Armature*>(child);

auto& map = arm->getBoneDic();
for(auto& entry : map){
   auto bone = entry.second;
   if(bone != nullptr){
      auto list = bone->getDisplayManager()->getDecortaiveDisplayList();
      for(auto dd : list){
         dd->getDisplay()->setGLProgramState(glpstate);
      }
   }
}

という感じで対応すると、Armatureに対してシェーダが反応しました。
もっと良い記述に出来ると思うけど、まぁ多少はね?

記事投稿初めてなのでこういう書き方でいいか分かりませんが、
とりあえず今回はこんな感じで。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1