From 7e1adeb3e9b621757a7c4b03fa2cdb877e0c0974 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Fri, 8 Aug 2014 18:01:36 +0800 Subject: [PATCH 1/5] add new test case --- .../Classes/Sprite3DTest/Sprite3DTest.cpp | 106 ++++++++++++++++-- .../Classes/Sprite3DTest/Sprite3DTest.h | 20 +++- 2 files changed, 118 insertions(+), 8 deletions(-) diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 2c9c540c72..6936184a97 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -51,6 +51,9 @@ static std::function createFunctions[] = CL(Sprite3DEffectTest), #endif CL(Sprite3DWithSkinTest), +#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) && (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) + CL(Sprite3DWithSkinOutlineTest), +#endif CL(Animate3DTest), CL(AttachmentTest) }; @@ -316,7 +319,8 @@ EffectSprite3D* EffectSprite3D::createFromObjFileAndTexture(const std::string &o if (sprite && sprite->initWithFile(objFilePath)) { sprite->autorelease(); - sprite->setTexture(textureFilePath); + if(textureFilePath.size() > 0) + sprite->setTexture(textureFilePath); return sprite; } CC_SAFE_DELETE(sprite); @@ -360,15 +364,33 @@ void EffectSprite3D::addEffect(Effect3DOutline* effect, ssize_t order) const std::string Effect3DOutline::_vertShaderFile = "Shaders3D/OutLine.vert"; const std::string Effect3DOutline::_fragShaderFile = "Shaders3D/OutLine.frag"; const std::string Effect3DOutline::_keyInGLProgramCache = "Effect3DLibrary_Outline"; -GLProgram* Effect3DOutline::getOrCreateProgram() + +const std::string Effect3DOutline::_vertSkinnedShaderFile = "Shaders3D/OutLine.vert"; +const std::string Effect3DOutline::_fragSkinnedShaderFile = "Shaders3D/OutLine.frag"; +const std::string Effect3DOutline::_keySkinnedInGLProgramCache = "Effect3DLibrary_Outline"; +GLProgram* Effect3DOutline::getOrCreateProgram(bool isSkinned /* = false */ ) { - auto program = GLProgramCache::getInstance()->getGLProgram(_keyInGLProgramCache); - if(program == nullptr) + if(isSkinned) { - program = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile); - GLProgramCache::getInstance()->addGLProgram(program, _keyInGLProgramCache); + auto program = GLProgramCache::getInstance()->getGLProgram(_keySkinnedInGLProgramCache); + if(program == nullptr) + { + program = GLProgram::createWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile); + GLProgramCache::getInstance()->addGLProgram(program, _keySkinnedInGLProgramCache); + } + return program; } - return program; + else + { + auto program = GLProgramCache::getInstance()->getGLProgram(_keyInGLProgramCache); + if(program == nullptr) + { + program = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile); + GLProgramCache::getInstance()->addGLProgram(program, _keyInGLProgramCache); + } + return program; + } + } Effect3DOutline* Effect3DOutline::create() @@ -672,6 +694,76 @@ void Sprite3DWithSkinTest::onTouchesEnded(const std::vector& touches, Ev } } +Sprite3DWithSkinOutlineTest::Sprite3DWithSkinOutlineTest() +{ + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DWithSkinOutlineTest::onTouchesEnded, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); + + auto s = Director::getInstance()->getWinSize(); + addNewSpriteWithCoords( Vec2(s.width/2, s.height/2) ); +} +std::string Sprite3DWithSkinOutlineTest::title() const +{ + return "Testing Sprite3D for skinned outline"; +} +std::string Sprite3DWithSkinOutlineTest::subtitle() const +{ + return "Tap screen to add more sprite3D"; +} + +void Sprite3DWithSkinOutlineTest::addNewSpriteWithCoords(Vec2 p) +{ + + std::string fileName = "Sprite3DTest/orc.c3b"; + auto sprite = EffectSprite3D::createFromObjFileAndTexture(fileName, ""); + + Effect3DOutline* effect = Effect3DOutline::create(); + effect->setOutlineColor(Vec3(1,0,0)); + effect->setOutlineWidth(0.01f); + sprite->addEffect(effect, -1); + Effect3DOutline* effect2 = Effect3DOutline::create(); + effect2->setOutlineWidth(0.02f); + effect2->setOutlineColor(Vec3(1,1,0)); + sprite->addEffect(effect2, -2); + + sprite->setScale(3); + sprite->setRotation3D(Vec3(0,180,0)); + addChild(sprite); + sprite->setPosition( Vec2( p.x, p.y) ); + + auto animation = Animation3D::create(fileName); + if (animation) + { + auto animate = Animate3D::create(animation); + bool inverse = (std::rand() % 3 == 0); + + int rand2 = std::rand(); + float speed = 1.0f; + if(rand2 % 3 == 1) + { + speed = animate->getSpeed() + CCRANDOM_0_1(); + } + else if(rand2 % 3 == 2) + { + speed = animate->getSpeed() - 0.5 * CCRANDOM_0_1(); + } + animate->setSpeed(inverse ? -speed : speed); + + sprite->runAction(RepeatForever::create(animate)); + } +} + +void Sprite3DWithSkinOutlineTest::onTouchesEnded(const std::vector& touches, Event* event) +{ + for (auto touch: touches) + { + auto location = touch->getLocation(); + + addNewSpriteWithCoords( location ); + } +} + Animate3DTest::Animate3DTest() : _hurt(nullptr) , _swim(nullptr) diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h index a9f774d368..385b7ce16c 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h @@ -113,7 +113,12 @@ protected: static const std::string _vertShaderFile; static const std::string _fragShaderFile; static const std::string _keyInGLProgramCache; - static GLProgram* getOrCreateProgram(); + + static const std::string _vertSkinnedShaderFile; + static const std::string _fragSkinnedShaderFile; + static const std::string _keySkinnedInGLProgramCache; + + static GLProgram* getOrCreateProgram(bool isSkinned = false); }; class Sprite3DHitTest : public Sprite3DTestDemo @@ -167,6 +172,19 @@ public: void onTouchesEnded(const std::vector& touches, Event* event); }; +class Sprite3DWithSkinOutlineTest : public Sprite3DTestDemo +{ +public: + CREATE_FUNC(Sprite3DWithSkinOutlineTest); + Sprite3DWithSkinOutlineTest(); + virtual std::string title() const override; + virtual std::string subtitle() const override; + + void addNewSpriteWithCoords(Vec2 p); + + void onTouchesEnded(const std::vector& touches, Event* event); +}; + class Animate3DTest : public Sprite3DTestDemo { public: From e66d1f6f69271ae1d6c294d3aaad786a5dec0956 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Mon, 11 Aug 2014 18:11:15 +0800 Subject: [PATCH 2/5] add skinned outline effect --- .../Classes/Sprite3DTest/Sprite3DTest.cpp | 59 +++++++++------ .../Resources/Shaders3D/SkinnedOutline.vert | 75 +++++++++++++++++++ 2 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 tests/cpp-tests/Resources/Shaders3D/SkinnedOutline.vert diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 6936184a97..c0aba13cb3 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -365,7 +365,7 @@ const std::string Effect3DOutline::_vertShaderFile = "Shaders3D/OutLine.vert"; const std::string Effect3DOutline::_fragShaderFile = "Shaders3D/OutLine.frag"; const std::string Effect3DOutline::_keyInGLProgramCache = "Effect3DLibrary_Outline"; -const std::string Effect3DOutline::_vertSkinnedShaderFile = "Shaders3D/OutLine.vert"; +const std::string Effect3DOutline::_vertSkinnedShaderFile = "Shaders3D/SkinnedOutLine.vert"; const std::string Effect3DOutline::_fragSkinnedShaderFile = "Shaders3D/OutLine.frag"; const std::string Effect3DOutline::_keySkinnedInGLProgramCache = "Effect3DLibrary_Outline"; GLProgram* Effect3DOutline::getOrCreateProgram(bool isSkinned /* = false */ ) @@ -410,21 +410,6 @@ Effect3DOutline* Effect3DOutline::create() bool Effect3DOutline::init() { - - GLProgram* glprogram = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile); - if(nullptr == glprogram) - { - CC_SAFE_DELETE(glprogram); - return false; - } - _glProgramState = GLProgramState::create(glprogram); - if(nullptr == _glProgramState) - { - return false; - } - _glProgramState->retain(); - _glProgramState->setUniformVec3("OutLineColor", _outlineColor); - _glProgramState->setUniformFloat("OutlineWidth", _outlineWidth); return true; } @@ -480,6 +465,19 @@ void Effect3DOutline::setTarget(EffectSprite3D *sprite) if(sprite != _sprite) { + GLProgram* glprogram; + if(!sprite->getSkin()) + glprogram = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile); + else + glprogram = GLProgram::createWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile); + + _glProgramState = GLProgramState::create(glprogram); + + _glProgramState->retain(); + _glProgramState->setUniformVec3("OutLineColor", _outlineColor); + _glProgramState->setUniformFloat("OutlineWidth", _outlineWidth); + + _sprite = sprite; auto mesh = sprite->getMesh(); @@ -504,6 +502,11 @@ void Effect3DOutline::setTarget(EffectSprite3D *sprite) } +static void MatrixPalleteCallBack( GLProgram* glProgram, Uniform* uniform, int paletteSize, const float* palette) +{ + glUniform4fv( uniform->location, (GLsizei)paletteSize, (const float*)palette ); +} + void Effect3DOutline::draw(const Mat4 &transform) { //draw @@ -518,7 +521,17 @@ void Effect3DOutline::draw(const Mat4 &transform) auto mesh = _sprite->getMesh(); glBindBuffer(GL_ARRAY_BUFFER, mesh->getVertexBuffer()); - _glProgramState->apply(transform); + + if(_sprite && _sprite->getSkin()) + { + auto function = std::bind(MatrixPalleteCallBack, std::placeholders::_1, std::placeholders::_2, + _sprite->getSkin()->getMatrixPaletteSize(), (float*)_sprite->getSkin()->getMatrixPalette()); + _glProgramState->setUniformCallback("u_matrixPalette", function); + } + + if(_sprite) + _glProgramState->apply(transform); + for (ssize_t i = 0; i < mesh->getSubMeshCount(); i++) { auto submesh = mesh->getSubMesh((int)i); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, submesh->getIndexBuffer()); @@ -591,13 +604,14 @@ void Sprite3DEffectTest::addNewSpriteWithCoords(Vec2 p) //option 2: load obj and assign the texture auto sprite = EffectSprite3D::createFromObjFileAndTexture("Sprite3DTest/boss1.obj", "Sprite3DTest/boss.png"); Effect3DOutline* effect = Effect3DOutline::create(); + sprite->addEffect(effect, -1); effect->setOutlineColor(Vec3(1,0,0)); effect->setOutlineWidth(0.01f); - sprite->addEffect(effect, -1); + Effect3DOutline* effect2 = Effect3DOutline::create(); + sprite->addEffect(effect2, -2); effect2->setOutlineWidth(0.02f); effect2->setOutlineColor(Vec3(1,1,0)); - sprite->addEffect(effect2, -2); //sprite->setEffect3D(effect); sprite->setScale(6.f); @@ -656,7 +670,7 @@ std::string Sprite3DWithSkinTest::subtitle() const void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p) { std::string fileName = "Sprite3DTest/orc.c3b"; - auto sprite = Sprite3D::create(fileName); + auto sprite = EffectSprite3D::create(fileName); sprite->setScale(3); sprite->setRotation3D(Vec3(0,180,0)); addChild(sprite); @@ -719,13 +733,14 @@ void Sprite3DWithSkinOutlineTest::addNewSpriteWithCoords(Vec2 p) auto sprite = EffectSprite3D::createFromObjFileAndTexture(fileName, ""); Effect3DOutline* effect = Effect3DOutline::create(); + sprite->addEffect(effect, -1); effect->setOutlineColor(Vec3(1,0,0)); effect->setOutlineWidth(0.01f); - sprite->addEffect(effect, -1); + Effect3DOutline* effect2 = Effect3DOutline::create(); + sprite->addEffect(effect2, -2); effect2->setOutlineWidth(0.02f); effect2->setOutlineColor(Vec3(1,1,0)); - sprite->addEffect(effect2, -2); sprite->setScale(3); sprite->setRotation3D(Vec3(0,180,0)); diff --git a/tests/cpp-tests/Resources/Shaders3D/SkinnedOutline.vert b/tests/cpp-tests/Resources/Shaders3D/SkinnedOutline.vert new file mode 100644 index 0000000000..5cdd990d80 --- /dev/null +++ b/tests/cpp-tests/Resources/Shaders3D/SkinnedOutline.vert @@ -0,0 +1,75 @@ +attribute vec3 a_position; +attribute vec3 a_normal; +attribute vec4 a_blendWeight; +attribute vec4 a_blendIndex; + +attribute vec2 a_texCoord; +uniform float OutlineWidth; + +const int SKINNING_JOINT_COUNT = 60; +// Uniforms +uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; + +// Varyings +varying vec2 TextureCoordOut; + +vec4 SkinnedVec3(vec3 vec) +{ + float blendWeight = a_blendWeight[0]; + + int matrixIndex = int (a_blendIndex[0]) * 3; + vec4 matrixPalette1 = u_matrixPalette[matrixIndex] * blendWeight; + vec4 matrixPalette2 = u_matrixPalette[matrixIndex + 1] * blendWeight; + vec4 matrixPalette3 = u_matrixPalette[matrixIndex + 2] * blendWeight; + + + blendWeight = a_blendWeight[1]; + if (blendWeight > 0.0) + { + matrixIndex = int(a_blendIndex[1]) * 3; + matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; + matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; + matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + } + + + blendWeight = a_blendWeight[2]; + if (blendWeight > 0.0) + { + matrixIndex = int(a_blendIndex[2]) * 3; + matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; + matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; + matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + } + + + blendWeight = a_blendWeight[3]; + if (blendWeight > 0.0) + { + matrixIndex = int(a_blendIndex[3]) * 3; + matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; + matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; + matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + } + + + vec4 _skinnedPosition; + vec4 postion = vec4(vec, 1.0); + _skinnedPosition.x = dot(postion, matrixPalette1); + _skinnedPosition.y = dot(postion, matrixPalette2); + _skinnedPosition.z = dot(postion, matrixPalette3); + _skinnedPosition.w = postion.w; + + return _skinnedPosition; +} + +void main() +{ + vec4 pos = CC_MVPMatrix * SkinnedVec3(a_position); + + vec4 normalproj = CC_MVPMatrix * vec4(SkinnedVec3(a_normal).xyz, 0); + normalproj = normalize(normalproj); + pos.xy += normalproj.xy * (OutlineWidth * (pos.z * 0.5 + 0.5)); + + gl_Position = pos; +} From 0dff45cfc226910315e2dc55ca4018b6ec3ac2e3 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 12 Aug 2014 09:51:03 +0800 Subject: [PATCH 3/5] adjust SkinnedEffectCode --- .../cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index c0aba13cb3..d353b089ee 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -446,7 +446,8 @@ void Effect3DOutline::setOutlineColor(const Vec3& color) if(_outlineColor != color) { _outlineColor = color; - _glProgramState->setUniformVec3("OutLineColor", _outlineColor); + if(_glProgramState) + _glProgramState->setUniformVec3("OutLineColor", _outlineColor); } } @@ -455,7 +456,8 @@ void Effect3DOutline::setOutlineWidth(float width) if(_outlineWidth != width) { _outlineWidth = width; - _glProgramState->setUniformFloat("OutlineWidth", _outlineWidth); + if(_glProgramState) + _glProgramState->setUniformFloat("OutlineWidth", _outlineWidth); } } @@ -733,14 +735,16 @@ void Sprite3DWithSkinOutlineTest::addNewSpriteWithCoords(Vec2 p) auto sprite = EffectSprite3D::createFromObjFileAndTexture(fileName, ""); Effect3DOutline* effect = Effect3DOutline::create(); - sprite->addEffect(effect, -1); effect->setOutlineColor(Vec3(1,0,0)); effect->setOutlineWidth(0.01f); + sprite->addEffect(effect, -1); + Effect3DOutline* effect2 = Effect3DOutline::create(); - sprite->addEffect(effect2, -2); effect2->setOutlineWidth(0.02f); effect2->setOutlineColor(Vec3(1,1,0)); + sprite->addEffect(effect2, -2); + sprite->setScale(3); sprite->setRotation3D(Vec3(0,180,0)); From e387caf763c43389a94383d42afce9a499ed1c4c Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 12 Aug 2014 09:56:25 +0800 Subject: [PATCH 4/5] add create(modelPath) interface for EffectSprite3D --- .../Classes/Sprite3DTest/Sprite3DTest.cpp | 17 ++++++++++++++++- .../Classes/Sprite3DTest/Sprite3DTest.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index d353b089ee..7da0226345 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -327,6 +327,21 @@ EffectSprite3D* EffectSprite3D::createFromObjFileAndTexture(const std::string &o return nullptr; } +EffectSprite3D* EffectSprite3D::create(const std::string &path) +{ + if (path.length() < 4) + CCASSERT(false, "improper name specified when creating Sprite3D"); + + auto sprite = new EffectSprite3D(); + if (sprite && sprite->initWithFile(path)) + { + sprite->autorelease(); + return sprite; + } + CC_SAFE_DELETE(sprite); + return nullptr; +} + EffectSprite3D::EffectSprite3D() : _defaultEffect(nullptr) { @@ -732,7 +747,7 @@ void Sprite3DWithSkinOutlineTest::addNewSpriteWithCoords(Vec2 p) { std::string fileName = "Sprite3DTest/orc.c3b"; - auto sprite = EffectSprite3D::createFromObjFileAndTexture(fileName, ""); + auto sprite = EffectSprite3D::create(fileName); Effect3DOutline* effect = Effect3DOutline::create(); effect->setOutlineColor(Vec3(1,0,0)); diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h index 385b7ce16c..0d223fc8b5 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h @@ -134,6 +134,8 @@ class EffectSprite3D : public Sprite3D { public: static EffectSprite3D* createFromObjFileAndTexture(const std::string& objFilePath, const std::string& textureFilePath); + static EffectSprite3D* create(const std::string& path); + void setEffect3D(Effect3D* effect); void addEffect(Effect3DOutline* effect, ssize_t order); virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override; From cb8c80de0df1bb78c5a7d3d36dfb48d04c2626ef Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 12 Aug 2014 14:41:25 +0800 Subject: [PATCH 5/5] export MeshSkin as CC_DLL --- cocos/3d/CCMeshSkin.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cocos/3d/CCMeshSkin.h b/cocos/3d/CCMeshSkin.h index 160df4c635..bd5ff24245 100644 --- a/cocos/3d/CCMeshSkin.h +++ b/cocos/3d/CCMeshSkin.h @@ -28,6 +28,7 @@ #include #include "3d/CCBundle3DData.h" +#include "3d/CCSkeleton3D.h" #include "base/ccMacros.h" #include "base/CCRef.h" @@ -44,7 +45,7 @@ class Skeleton3D; * MeshSkin, A class maintain a collection of bones that affect Mesh vertex. * And it is responsible for computing matrix palletes that used by skin mesh rendering. */ -class MeshSkin: public Ref +class CC_DLL MeshSkin: public Ref { public: