More Related Content
Similar to Cocos2d x-sprite3d
Similar to Cocos2d x-sprite3d (20)
Cocos2d x-sprite3d
- 2. 自己紹介
• 河野 洋志(こうの ひろし)
• 株式会社アカツキ エンジニア
• サウザンドメモリーズを担当
• 主にサーバサイド
• Ruby on Rails, MySQL, Redis, AWS, etc…
• cocos2d-x…? C++…?
- 6. 目次
• cocos2d-x Ver 3.1で追加されたSprite3Dクラス
の紹介
• Sprite3Dの使い方
• シェーダー拡張
• Sprite3Dで(まだ?)できないこと
- 7. 目次
• cocos2d-x Ver 3.1で追加されたSprite3Dクラス
の紹介
• Sprite3Dの使い方
• シェーダー拡張
• Sprite3Dで(まだ?)できないこと
- 10. Position3D
• z軸は手前が正、奥が負
• パースがかかっているので、設定したx, yより
も手前側は画面縁に、奥側は画面中央寄りに
配置される
auto model_a = Sprite3D::create("sample.obj");!
model_a->setTexture("sample.png");!
model_a->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height * 2 / 3, 400));!
this->addChild(model_a);!
!
auto model_b = Sprite3D::create("samle.obj");!
model3_b->setTexture("samle.png");!
model3_b->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height / 2, 0));!
this->addChild(model_b);!
!
auto model_c = Sprite3D::create("samle.obj");!
model3_c->setTexture("samle.png");!
model3_c->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height * 1 / 3, -400));!
this->addChild(model_c);
model_a
model_b
model_c
- 11. Rotation3D
• Vec3を渡して3次元的なrotationを設定できる
auto model_a = Sprite3D::create("sample.obj");!
model_a->setTexture("sample.png");!
model_a->setRotation3D(Vec3(90.0f, 0.0f, 0.0f));!
model_a->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height * 2 / 3, 0));!
model_a->setScale(15);!
this->addChild(model_a);!
!
auto model_b = Sprite3D::create("sample.obj");!
model_b->setTexture("sample.png");!
model_b->setRotation3D(Vec3(0.0f, 90.0f, 0.0f));!
model_b->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height / 2, 0));!
model_b->setScale(15);!
this->addChild(model_b);!
!
auto model_c = Sprite3D::create("sample.obj");!
model_c->setTexture("sample.png");!
model_c->setRotation3D(Vec3(0.0f, 0.0f, 90.0f));!
model_c->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height / 3, 0));!
model_c->setScale(15);!
this->addChild(model_c);
- 12. 移動・拡縮
• 移動
!
!
• 拡縮
void HelloWorld::onTouchesEnded(const std::vector<cocos2d::Touch *> &touches, cocos2d::Event *event)!
{!
for (auto touch: touches) {!
auto location = touch->getLocation();!
auto action = MoveTo::create(0.5f, location);!
model3d->runAction(action);!
}!
}
void HelloWorld::onTouchesEnded(const std::vector<cocos2d::Touch *> &touches, cocos2d::Event *event)!
{!
for (auto touch: touches) {!
auto location = touch->getLocation();!
auto seq = Sequence::create(ScaleTo::create(0.1f, 75.f),!
ScaleTo::create(0.1f, 30.f),!
ScaleTo::create(0.1f, 45.f), NULL);!
model3d->runAction(seq);!
}!
}
- 13. 回転
• z軸方向にしか回転してくれない
!
!
• Vec3クラスを渡すと3次元的に回転できる
void HelloWorld::onTouchesEnded(const std::vector<cocos2d::Touch *> &touches, cocos2d::Event *event)!
{!
for (auto touch: touches) {!
auto location = touch->getLocation();!
auto action = RotateBy::create(0.5f, 360);!
model3d->runAction(action);!
}!
}
void HelloWorld::onTouchesEnded(const std::vector<cocos2d::Touch *> &touches, cocos2d::Event *event)!
{!
for (auto touch: touches) {!
auto location = touch->getLocation();!
auto action = RotateBy::create(0.5f, Vec3(location.x, location.y, 30));!
model3d->runAction(action);!
}!
}
- 15. 目次
• cocos2d-x Ver 3.1で追加されたSprite3Dクラス
の紹介
• Sprite3Dの使い方
• シェーダー拡張
• Sprite3Dで(まだ?)できないこと
- 18. 3DEffectクラス
• 3Dエフェクトに関する抽象クラス
class Effect3D : public Ref!
{!
public:!
virtual void drawWithSprite(EffectSprite3D* sprite, const Mat4 &transform) = 0;!
protected:!
Effect3D() : _glProgramState(nullptr) {}!
virtual ~Effect3D()!
{!
CC_SAFE_RELEASE(_glProgramState);!
}!
protected:!
GLProgramState* _glProgramState;!
};!
• OpenGLシェーダを格納する _glProgramState
プロパティを持つ
• シェーダを描画する drawWithSprite() メソッド
- 19. 3DEffectOutlineクラス
• シェーダーを読み込んで描画を実行するクラス
class Effect3DOutline: public Effect3D!
{!
public:!
static Effect3DOutline* create();!
!
void setOutlineColor(const Vec3& color);!
!
void setOutlineWidth(float width);!
!
void drawWithSprite(EffectSprite3D* sprite, const Mat4 &transform);!
!
protected:!
!
Effect3DOutline();!
virtual ~Effect3DOutline();!
!
bool init();!
!
Vec3 _outlineColor;!
float _outlineWidth;!
public:!
static const std::string _vertShaderFile;!
static const std::string _fragShaderFile;!
static const std::string _keyInGLProgramCache;!
static GLProgram* getOrCreateProgram();!
!
};!
• 初期化時にシェーダーを
読み込む
• drawWithSprite()の実装
もこのクラスにあります
- 20. シェーダ
• Resources/Shaders3D 以下に配置
• OutLine.frag
• OutLine.vert
uniform vec3 OutLineColor;!
uniform vec4 u_color;!
!
void main(void)!
{!
gl_FragColor = vec4(OutLineColor,1.0) * u_color;!
}
attribute vec4 a_position;!
attribute vec3 a_normal;!
uniform float OutlineWidth;!
!
void main(void)!
{!
vec4 pos = CC_MVPMatrix * a_position;!
vec4 normalproj = CC_MVPMatrix * vec4(a_normal, 0);!
normalproj = normalize(normalproj);!
pos.xy += normalproj.xy * (OutlineWidth * (pos.z * 0.5 + 0.5));!
!
gl_Position = pos;!
}
- 21. EffectSprite3Dクラス
• Sprite3Dクラスを継承して3DEffectを追加できる
ように拡張
class EffectSprite3D : public Sprite3D!
{!
public:!
static EffectSprite3D* createFromObjFileAndTexture(const std::string& objFilePath, const std::string& textureFilePath);!
void setEffect3D(Effect3D* effect);!
void addEffect(Effect3D* effect, ssize_t order);!
void eraseEffect(Effect3D* effect);!
ssize_t getEffectCount() const;!
Effect3D* getEffect(ssize_t index) const;!
virtual void draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated) override;!
protected:!
EffectSprite3D();!
virtual ~EffectSprite3D();!
!
std::vector<std::tuple<ssize_t,Effect3D*,CustomCommand>> _effects;!
Effect3D* _defaultEffect;!
CustomCommand _command;!
};!
- 22. EffectSprite3Dクラス
• 使い方
auto model = EffectSprite3D::createFromObjFileAndTexture("sample.obj", "sample.png");!
model->setScale(45);!
model->setRotation3D(Vec3(265.0f, 265.0f, 265.0f));!
model->setPosition3D(Vec3(visibleSize.width / 2, visibleSize.height / 2, 0));!
!
auto effect = Effect3DOutline::create();!
effect->setOutlineColor(Vec3(1,1,0));!
effect->setOutlineWidth(0.03f);!
model->addEffect(effect, 1);!
!
this->addChild(model);
- 23. 目次
• cocos2d-x Ver 3.1で追加されたSprite3Dクラス
の紹介
• Sprite3Dの使い方
• シェーダー拡張
• Sprite3Dで(まだ?)できないこと
- 24. できないこと
• タップイベントの取得
• getBoundBox()でRectが取得できない
• 物理演算
• アニメーション
• モデルの表示、アクション以上のことはできない
auto position = model3d->getPosition3D();!
CCLOG("position: X:%f Y:%f Z:%f", position.x, position.y, position.z);!
auto rect = model3d->getBoundingBox();!
CCLOG("bounding box: MinX:%f MaxX:%f MinY:%f MaxY:%f", rect.getMinX(), rect.getMaxX(), rect.getMinY(), rect.getMaxY());!
!
// cocos2d: position: X:320.000000 Y:480.000000 Z:0.000000!
// cocos2d: bounding box: MinX:320.000000 MaxX:320.000000 MinY:480.000000 MaxY:480.000000