diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp index 780abace13..262d97c73b 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp @@ -34,6 +34,7 @@ namespace ShaderTest2 static std::function createFunctions[] = { CL(EffectSpriteTest), + CL(EffectSpriteLamp), }; static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]); @@ -433,6 +434,77 @@ protected: } }; +class EffectNormalMapped : public Effect +{ +public: + CREATE_FUNC(EffectNormalMapped); + static EffectNormalMapped* create(const std::string&normalMapFileName) + { + EffectNormalMapped *normalMappedSprite = new (std::nothrow) EffectNormalMapped(); + if (normalMappedSprite && normalMappedSprite->init() && normalMappedSprite->initNormalMap(normalMapFileName)) + { + + normalMappedSprite->autorelease(); + return normalMappedSprite; + } + CC_SAFE_DELETE(normalMappedSprite); + return nullptr; + } + void setKBump(float value); + void setLightPos(const Vec3& pos); + void setLightColor(const Color4F& color); + float getKBump()const{return _kBump;} +protected: + bool init(); + bool initNormalMap(const std::string&normalMapFileName); + virtual void setTarget(EffectSprite* sprite) override; + EffectSprite* _sprite; + Vec3 _lightPos; + Color4F _lightColor; + float _kBump; +}; + +bool EffectNormalMapped::init() +{ + initGLProgramState("Shaders3D/Normal.frag"); + _kBump = 2; + return true; +} +bool EffectNormalMapped::initNormalMap(const std::string&normalMapFileName) +{ + auto normalMapTextrue = TextureCache::getInstance()->addImage(normalMapFileName.c_str()); + getGLProgramState()->setUniformTexture("u_normalMap", normalMapTextrue); + return true; +} +void EffectNormalMapped::setTarget(EffectSprite* sprite) +{ + _sprite = sprite; + getGLProgramState()->setUniformFloat("u_kBump", _kBump); + getGLProgramState()->setUniformVec2("u_contentSize", Vec2(sprite->getContentSize().width,sprite->getContentSize().height)); +} + +void EffectNormalMapped::setKBump(float value) +{ + _kBump = value; + auto glProgramState = getGLProgramState(); + if(glProgramState) glProgramState->setUniformFloat("u_kBump", _kBump); +} + +void EffectNormalMapped::setLightPos(const Vec3& pos) +{ + _lightPos = pos; + auto glProgramState = getGLProgramState(); + if(glProgramState) glProgramState->setUniformVec4("u_lightPosInLocalSpace", Vec4(_lightPos.x,_lightPos.y,_lightPos.z,1)); + +} + +void EffectNormalMapped::setLightColor(const Color4F& color) +{ + _lightColor = color; + auto glProgramState = getGLProgramState(); + if(glProgramState) getGLProgramState()->setUniformVec3("u_diffuseL", Vec3(_lightColor.r,_lightColor.g,_lightColor.b)); + +} EffectSpriteTest::EffectSpriteTest() { @@ -495,3 +567,79 @@ EffectSpriteTest::EffectSpriteTest() } } +EffectSpriteLamp::EffectSpriteLamp() +{ + if (ShaderTestDemo2::init()) { + + auto s = Director::getInstance()->getWinSize(); + _sprite = EffectSprite::create("Images/elephant1_Diffuse.png"); + //auto contentSize = _sprite->getContentSize(); + _sprite->setPosition(Vec2(s.width/2, s.height/2)); + addChild(_sprite); + + auto lampEffect = EffectNormalMapped::create("Images/elephant1_Normal.png"); + + Vec3 pos(150,150, 50); + _lightSprite = Sprite::create("Images/ball.png"); + this->addChild(_lightSprite); + _lightSprite->setPosition(Vec2(pos.x, s.height- pos.y)); + Mat4 mat = _sprite->getNodeToWorldTransform(); + Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform()); + lampEffect->setLightColor(Color4F(1,1,1,1)); + lampEffect->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50)); + lampEffect->setKBump(2); + _sprite->setEffect(lampEffect); + _effect = lampEffect; + auto listerner = EventListenerTouchAllAtOnce::create(); + listerner->onTouchesBegan = CC_CALLBACK_2(EffectSpriteLamp::onTouchesBegan, this); + listerner->onTouchesMoved = CC_CALLBACK_2(EffectSpriteLamp::onTouchesMoved, this); + listerner->onTouchesEnded = CC_CALLBACK_2(EffectSpriteLamp::onTouchesEnded, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listerner, this); + } +} + + +void EffectSpriteLamp::onTouchesBegan(const std::vector& touches, Event *unused_event) +{ + for ( auto &item: touches ) + { + auto touch = item; + auto s = Director::getInstance()->getWinSize(); + Point loc_winSpace = touch->getLocationInView(); + _lightSprite->setPosition(Vec2( loc_winSpace.x, s.height - loc_winSpace.y)); + Vec3 pos(loc_winSpace.x,loc_winSpace.y, 50); + Mat4 mat = _sprite->getNodeToWorldTransform(); + Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform()); + ((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50)); + } +} + +void EffectSpriteLamp::onTouchesMoved(const std::vector& touches, Event *unused_event) +{ + for ( auto &item: touches ) + { + auto touch = item; + auto s = Director::getInstance()->getWinSize(); + Point loc_winSpace = touch->getLocationInView(); + _lightSprite->setPosition(Vec2( loc_winSpace.x, s.height - loc_winSpace.y)); + Vec3 pos(loc_winSpace.x,loc_winSpace.y, 50); + Mat4 mat = _sprite->getNodeToWorldTransform(); + Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform()); + ((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50)); + } +} + +void EffectSpriteLamp::onTouchesEnded(const std::vector& touches, Event *unused_event) +{ + for ( auto &item: touches ) + { + auto touch = item; + auto s = Director::getInstance()->getWinSize(); + Point loc_winSpace = touch->getLocationInView(); + _lightSprite->setPosition(Vec2( loc_winSpace.x, s.height - loc_winSpace.y)); + Vec3 pos(loc_winSpace.x,loc_winSpace.y, 50); + Mat4 mat = _sprite->getNodeToWorldTransform(); + Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform()); + ((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50)); + } +} diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h index 707d1cb80b..162ab11a44 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h @@ -59,5 +59,21 @@ protected: EffectSprite *_sprite; }; +class EffectSpriteLamp : public ShaderTestDemo2 +{ +public: + CREATE_FUNC(EffectSpriteLamp); + EffectSpriteLamp(); + virtual std::string subtitle() const {return "Sprite Lamp effects";} + //callback +public: + virtual void onTouchesBegan(const std::vector& touches, Event *unused_event); + virtual void onTouchesMoved(const std::vector& touches, Event *unused_event); + virtual void onTouchesEnded(const std::vector& touches, Event *unused_event); +protected: + EffectSprite *_sprite; + Effect* _effect; + Sprite* _lightSprite; +}; #endif diff --git a/tests/cpp-tests/Resources/Images/elephant1_Diffuse.png b/tests/cpp-tests/Resources/Images/elephant1_Diffuse.png new file mode 100755 index 0000000000..05f532150f Binary files /dev/null and b/tests/cpp-tests/Resources/Images/elephant1_Diffuse.png differ diff --git a/tests/cpp-tests/Resources/Images/elephant1_Normal.png b/tests/cpp-tests/Resources/Images/elephant1_Normal.png new file mode 100755 index 0000000000..c5c837817a Binary files /dev/null and b/tests/cpp-tests/Resources/Images/elephant1_Normal.png differ diff --git a/tests/cpp-tests/Resources/Shaders3D/Normal.frag b/tests/cpp-tests/Resources/Shaders3D/Normal.frag new file mode 100755 index 0000000000..7f1f3d6735 --- /dev/null +++ b/tests/cpp-tests/Resources/Shaders3D/Normal.frag @@ -0,0 +1,31 @@ +#ifdef GL_ES +precision mediump float; +#endif + +varying vec4 v_fragmentColor; +varying vec2 v_texCoord; +uniform sampler2D u_normalMap; +uniform float u_kBump; +uniform vec4 u_lightPosInLocalSpace; +uniform vec2 u_contentSize; +uniform vec3 u_diffuseL; +void main(void) +{ + vec4 texColor=texture2D(CC_Texture0, v_texCoord); + vec3 normal=texture2D(u_normalMap, v_texCoord).rgb; + normal=normal*2.0-1.0; + normal.y=-normal.y; + if(u_kBump!=1.0) + { + //if the vertex.z mult kBump, then the normal.z should div kBump and re-normalize + normal=vec3(normal.x,normal.y,normal.z/u_kBump); + normal=normalize(normal); + } + vec4 curPixelPosInLocalSpace=vec4(v_texCoord.x*u_contentSize.x,(1.0-v_texCoord.y)*u_contentSize.y,0.0,1.0); + vec4 lightDir=normalize(curPixelPosInLocalSpace-u_lightPosInLocalSpace); + vec3 posToLight=-lightDir.xyz; + float normDotPosToLight=max(0.0,dot(normal,posToLight)); + vec4 diffuse=vec4(normDotPosToLight*u_diffuseL,1.0); + vec4 ambient=vec4(0.5,0.5,0.5,1); + gl_FragColor=texColor*vec4(vec3(diffuse+ambient),diffuse.a);; +} \ No newline at end of file