From 30f4f256d877fa03255c882017f535204f89d7d5 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 28 May 2014 15:16:00 +0800 Subject: [PATCH 1/5] fix background/forground of Sprite3D on android platform --- cocos/renderer/CCGLProgramState.cpp | 40 ++++++++++++++++++++++++++--- cocos/renderer/CCGLProgramState.h | 14 +++++++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index eadae38e75..7b1b4d5f65 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -33,6 +33,10 @@ THE SOFTWARE. #include "renderer/CCGLProgramCache.h" #include "renderer/ccGLStateCache.h" #include "renderer/CCTexture2D.h" +#include "base/CCEventCustom.h" +#include "base/CCEventListenerCustom.h" +#include "base/CCEventType.h" +#include "base/CCDirector.h" NS_CC_BEGIN @@ -272,7 +276,20 @@ GLProgramState::GLProgramState() : _vertexAttribsFlags(0) , _glprogram(nullptr) , _textureUnitIndex(1) +, _uniformAttributeValueDirty(true) { +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + // listen the event when app go to foreground + CCLOG("create _backToForegroundlistener for GLProgramState"); + _backToForegroundlistener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(GLProgramState::setProgramStateDirty, this)); + Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundlistener, -1); +#endif +} + +void GLProgramState::setProgramStateDirty(EventCustom *event) +{ + CCLOG("GLProgramState to background---------"); + _uniformAttributeValueDirty = true; } GLProgramState::~GLProgramState() @@ -312,7 +329,24 @@ void GLProgramState::resetGLProgram() void GLProgramState::apply(const Mat4& modelView) { CCASSERT(_glprogram, "invalid glprogram"); - + if(_uniformAttributeValueDirty) + { + for(auto& uniformValue : _uniforms) + { + uniformValue.second._uniform = _glprogram->getUniform(uniformValue.first); + } + + _vertexAttribsFlags = 0; + for(auto& attributeValue : _attributes) + { + attributeValue.second._vertexAttrib = _glprogram->getVertexAttrib(attributeValue.first);; + if(attributeValue.second._enabled) + _vertexAttribsFlags |= 1 << attributeValue.second._vertexAttrib->index; + } + + _uniformAttributeValueDirty = false; + + } // set shader _glprogram->use(); _glprogram->setUniformsForBuiltins(modelView); @@ -322,9 +356,9 @@ void GLProgramState::apply(const Mat4& modelView) if(_vertexAttribsFlags) { // enable/disable vertex attribs GL::enableVertexAttribs(_vertexAttribsFlags); - // set attributes - for(auto &attribute : _attributes) { + for(auto &attribute : _attributes) + { attribute.second.apply(); } } diff --git a/cocos/renderer/CCGLProgramState.h b/cocos/renderer/CCGLProgramState.h index babfed8fed..f2b5d4000b 100644 --- a/cocos/renderer/CCGLProgramState.h +++ b/cocos/renderer/CCGLProgramState.h @@ -39,6 +39,8 @@ class GLProgram; class Texture2D; struct Uniform; struct VertexAttrib; +class EventListenerCustom; +class EventCustom; // // @@ -48,7 +50,7 @@ struct VertexAttrib; class UniformValue { friend class GLProgram; - + friend class GLProgramState; public: UniformValue(); UniformValue(Uniform *uniform, GLProgram* glprogram); @@ -177,21 +179,27 @@ public: void setUniformCallback(const std::string &uniformName, const std::function &callback); void setUniformTexture(const std::string &uniformName, Texture2D *texture); void setUniformTexture(const std::string &uniformName, GLuint textureId); - + protected: GLProgramState(); ~GLProgramState(); bool init(GLProgram* program); void resetGLProgram(); + void setProgramStateDirty(EventCustom* event); VertexAttribValue* getVertexAttribValue(const std::string &attributeName); UniformValue* getUniformValue(const std::string &uniformName); - + + bool _uniformAttributeValueDirty; std::unordered_map _uniforms; std::unordered_map _attributes; int _textureUnitIndex; uint32_t _vertexAttribsFlags; GLProgram *_glprogram; + +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + EventListenerCustom* _backToForegroundlistener; +#endif }; NS_CC_END From 2084fc4ddc99bcc650d6015de586482429a7d946 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 28 May 2014 15:50:37 +0800 Subject: [PATCH 2/5] using lambda function instead of member function --- cocos/renderer/CCGLProgramState.cpp | 8 +------- cocos/renderer/CCGLProgramState.h | 1 - 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index 7b1b4d5f65..e4e7fa5226 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -281,17 +281,11 @@ GLProgramState::GLProgramState() #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) // listen the event when app go to foreground CCLOG("create _backToForegroundlistener for GLProgramState"); - _backToForegroundlistener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(GLProgramState::setProgramStateDirty, this)); + _backToForegroundlistener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, [this](EventCustom*) { _uniformAttributeValueDirty = true; }); Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundlistener, -1); #endif } -void GLProgramState::setProgramStateDirty(EventCustom *event) -{ - CCLOG("GLProgramState to background---------"); - _uniformAttributeValueDirty = true; -} - GLProgramState::~GLProgramState() { CC_SAFE_RELEASE(_glprogram); diff --git a/cocos/renderer/CCGLProgramState.h b/cocos/renderer/CCGLProgramState.h index f2b5d4000b..019cd95222 100644 --- a/cocos/renderer/CCGLProgramState.h +++ b/cocos/renderer/CCGLProgramState.h @@ -185,7 +185,6 @@ protected: ~GLProgramState(); bool init(GLProgram* program); void resetGLProgram(); - void setProgramStateDirty(EventCustom* event); VertexAttribValue* getVertexAttribValue(const std::string &attributeName); UniformValue* getUniformValue(const std::string &uniformName); From 99d1ccf41e1e027d89bb893c1e894d5717f3e0db Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 28 May 2014 16:51:33 +0800 Subject: [PATCH 3/5] remove foreground event listener when GLProgramState is deleted --- cocos/renderer/CCGLProgramState.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index e4e7fa5226..4341cbe4ba 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -287,7 +287,11 @@ GLProgramState::GLProgramState() } GLProgramState::~GLProgramState() -{ +{ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundlistener); +#endif + CC_SAFE_RELEASE(_glprogram); } From ad3b1cf827523ac4a0471c8ec9d72da0acf889e8 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 28 May 2014 21:07:12 +0800 Subject: [PATCH 4/5] add background/foreground listener for Effectsprite3d/Effect3d test case --- .../Classes/Sprite3DTest/Sprite3DTest.cpp | 19 +++++++++++++++++-- .../Classes/Sprite3DTest/Sprite3DTest.h | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 01791d13b0..ed6b7ca043 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -296,7 +296,7 @@ Effect3DOutline* Effect3DOutline::create() bool Effect3DOutline::init() { - GLProgram* glprogram = Effect3DOutline::getOrCreateProgram(); + GLProgram* glprogram = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile); if(nullptr == glprogram) { CC_SAFE_DELETE(glprogram); @@ -318,11 +318,26 @@ Effect3DOutline::Effect3DOutline() : _outlineWidth(1.0f) , _outlineColor(1, 1, 1) { - +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + _backToForeGroundLister = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, + [this](EventCustom*) + { + auto glProgram = _glProgramState->getGLProgram(); + glProgram->reset(); + glProgram->initWithFilenames(_vertShaderFile, _fragShaderFile); + glProgram->link(); + glProgram->updateUniforms(); + } + ); + Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForeGroundLister, -1); +#endif } Effect3DOutline::~Effect3DOutline() { +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForeGroundLister); +#endif } void Effect3DOutline::setOutlineColor(const Vec3& color) diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h index 20a67bfd9e..a86cebd85f 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h @@ -96,6 +96,9 @@ protected: Vec3 _outlineColor; float _outlineWidth; +//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + EventListenerCustom* _backToForeGroundLister; +//#endif protected: static const std::string _vertShaderFile; From 8633ab9c142ef136dfd44573d789c3d8fcbc6a81 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Thu, 29 May 2014 12:43:04 +0800 Subject: [PATCH 5/5] add background/foreground listener for EffectSprite/Effect framework test case --- .../Classes/ShaderTest/ShaderTest2.cpp | 32 ++++++++++++++++++- .../Classes/ShaderTest/ShaderTest2.h | 9 ++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp index a697277c78..35cc597f14 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp @@ -207,13 +207,43 @@ bool Effect::initGLProgramState(const std::string &fragmentFilename) auto fragmentFullPath = fileUtiles->fullPathForFilename(fragmentFilename); auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath); auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.c_str()); - + +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + _fragSource = fragSource; +#endif + _glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram); _glprogramstate->retain(); return _glprogramstate != nullptr; } +Effect::Effect() +: _glprogramstate(nullptr) +{ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + _backgroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, + [this](EventCustom*) + { + auto glProgram = _glprogramstate->getGLProgram(); + glProgram->reset(); + glProgram->initWithByteArrays(ccPositionTextureColor_noMVP_vert, _fragSource.c_str()); + glProgram->link(); + glProgram->updateUniforms(); + } + ); + Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backgroundListener, -1); +#endif +} + +Effect::~Effect() +{ + CC_SAFE_RELEASE_NULL(_glprogramstate); +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + Director::getInstance()->getEventDispatcher()->removeEventListener(_backgroundListener); +#endif +} + // Blur class EffectBlur : public Effect { diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h index 2d7421fa80..0de6babe69 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h @@ -37,10 +37,13 @@ public: protected: bool initGLProgramState(const std::string &fragmentFilename); - Effect() : _glprogramstate(nullptr) - {} - virtual ~Effect() {} + Effect(); + virtual ~Effect(); GLProgramState *_glprogramstate; +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) + std::string _fragSource; + EventListenerCustom* _backgroundListener; +#endif }; class EffectSpriteTest : public ShaderTestDemo2