From 9c2130e88ae5c1193b7e1378798e10d886322d36 Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Tue, 24 Nov 2015 18:01:50 +0800 Subject: [PATCH 1/7] fix Layout and ClippingNode nested rendering issue --- build/cocos2d_libs.xcodeproj/project.pbxproj | 22 +++++++-- cocos/2d/CCClippingNode.cpp | 10 ++-- cocos/2d/libcocos2d.vcxproj | 6 ++- cocos/2d/libcocos2d.vcxproj.filters | 10 +++- .../libcocos2d_8_1.Shared.vcxitems | 6 ++- .../libcocos2d_8_1.Shared.vcxitems.filters | 10 +++- cocos/2d/libcocos2d_win10/libcocos2d.vcxproj | 6 ++- .../libcocos2d.vcxproj.filters | 10 +++- cocos/Android.mk | 1 + cocos/base/CCStencilBitsManager.cpp | 44 +++++++++++++++++ cocos/base/CCStencilBitsManager.hpp | 49 +++++++++++++++++++ cocos/base/CMakeLists.txt | 1 + cocos/ui/UILayout.cpp | 7 ++- .../UIListViewTest/UIListViewTest.cpp | 10 ++++ 14 files changed, 170 insertions(+), 22 deletions(-) create mode 100644 cocos/base/CCStencilBitsManager.cpp create mode 100644 cocos/base/CCStencilBitsManager.hpp diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index b98cba41f3..7357b4b972 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1234,6 +1234,11 @@ 2980F02B1BA9A5550059E678 /* UITextView+CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0201BA9A5550059E678 /* UITextView+CCUITextInput.h */; }; 2980F02C1BA9A5550059E678 /* UITextView+CCUITextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F0211BA9A5550059E678 /* UITextView+CCUITextInput.mm */; }; 2986667F18B1B246000E39CA /* CCTweenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2986667818B1B079000E39CA /* CCTweenFunction.cpp */; }; + 298C75D51C0465D0006BAE63 /* CCStencilBitsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */; }; + 298C75D61C0465D1006BAE63 /* CCStencilBitsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */; }; + 298C75D71C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */; }; + 298C75D81C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */; }; + 298C75D91C04681F006BAE63 /* CCStencilBitsManager.hpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */; }; 299754F4193EC95400A54AC3 /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; }; 299754F5193EC95400A54AC3 /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; }; 299754F6193EC95400A54AC3 /* ObjectFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 299754F3193EC95400A54AC3 /* ObjectFactory.h */; }; @@ -2072,10 +2077,10 @@ B5668D7E1B3838E4003CBD5E /* UIScrollViewBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5668D7B1B3838E4003CBD5E /* UIScrollViewBar.cpp */; }; B5668D7F1B3838E4003CBD5E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; }; B5668D801B3838E4003CBD5E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; }; - B5A738961BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; settings = {ASSET_TAGS = (); }; }; - B5A738971BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; settings = {ASSET_TAGS = (); }; }; - B5A738981BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; settings = {ASSET_TAGS = (); }; }; - B5A738991BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; settings = {ASSET_TAGS = (); }; }; + B5A738961BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; }; + B5A738971BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; }; + B5A738981BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; }; + B5A738991BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; }; B5CE6DBE1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; }; B5CE6DBF1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; }; B5CE6DC01B3BF2B1002B0419 /* UIAbstractCheckButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DBD1B3BF2B1002B0419 /* UIAbstractCheckButton.h */; }; @@ -4144,6 +4149,8 @@ 2980F0211BA9A5550059E678 /* UITextView+CCUITextInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UITextView+CCUITextInput.mm"; sourceTree = ""; }; 2986667818B1B079000E39CA /* CCTweenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTweenFunction.cpp; sourceTree = ""; }; 2986667918B1B079000E39CA /* CCTweenFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTweenFunction.h; sourceTree = ""; }; + 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCStencilBitsManager.cpp; path = ../base/CCStencilBitsManager.cpp; sourceTree = ""; }; + 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CCStencilBitsManager.hpp; path = ../base/CCStencilBitsManager.hpp; sourceTree = ""; }; 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectFactory.cpp; path = ../base/ObjectFactory.cpp; sourceTree = ""; }; 299754F3193EC95400A54AC3 /* ObjectFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectFactory.h; path = ../base/ObjectFactory.h; sourceTree = ""; }; 299CF1F919A434BC00C378C1 /* ccRandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ccRandom.cpp; path = ../base/ccRandom.cpp; sourceTree = ""; }; @@ -6037,6 +6044,8 @@ 50ABBE1C1925AB6F00A911A9 /* utlist.h */, 50ABBE1D1925AB6F00A911A9 /* ZipUtils.cpp */, 50ABBE1E1925AB6F00A911A9 /* ZipUtils.h */, + 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */, + 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */, ); name = base; path = ../cocos/2d; @@ -9229,6 +9238,7 @@ 15AE182A19AAD2F700C27E9E /* CCMeshSkin.h in Headers */, B276EF5F1988D1D500CD400F /* CCVertexIndexData.h in Headers */, 1A57007F180BC5A10088DEC7 /* CCActionInterval.h in Headers */, + 298C75D71C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */, B6DD2FDB1B04825B00E47F5F /* DetourLocalBoundary.h in Headers */, B6CAB3491AF9AA1A00B9B856 /* gim_clip_polygon.h in Headers */, B677B0DB1B18492D006762CB /* CCNavMeshUtils.h in Headers */, @@ -10669,6 +10679,7 @@ 85505F051B60E3B2003F2CD4 /* CCBoneNode.h in Headers */, B665E2491AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h in Headers */, B6CAB4461AF9AA1A00B9B856 /* btParallelConstraintSolver.h in Headers */, + 298C75D81C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */, 15AE18D119AAD33D00C27E9E /* CCNodeLoaderLibrary.h in Headers */, 15AE1AC319AAD40300C27E9E /* b2DistanceJoint.h in Headers */, B6CAB5261AF9AA1A00B9B856 /* btQuickprof.h in Headers */, @@ -11830,6 +11841,7 @@ B665E2EE1AA80A6500DDB1C5 /* CCPULineEmitter.cpp in Sources */, B6CAB2DD1AF9AA1A00B9B856 /* btScaledBvhTriangleMeshShape.cpp in Sources */, B665E4121AA80A6600DDB1C5 /* CCPUTextureAnimator.cpp in Sources */, + 298C75D51C0465D0006BAE63 /* CCStencilBitsManager.cpp in Sources */, B665E3D21AA80A6600DDB1C5 /* CCPUScriptLexer.cpp in Sources */, B665E4021AA80A6600DDB1C5 /* CCPUSphereColliderTranslator.cpp in Sources */, 15AE1A3619AAD3D500C27E9E /* b2PolygonShape.cpp in Sources */, @@ -11964,6 +11976,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 298C75D91C04681F006BAE63 /* CCStencilBitsManager.hpp in Sources */, D0FD03541A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp in Sources */, 15AE1B9819AADAA100C27E9E /* UIVideoPlayer-ios.mm in Sources */, B665E38F1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp in Sources */, @@ -12114,6 +12127,7 @@ 15AE193C19AAD35100C27E9E /* CCArmatureDefine.cpp in Sources */, B665E35F1AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp in Sources */, B29594B51926D5EC003EEF37 /* CCMeshCommand.cpp in Sources */, + 298C75D61C0465D1006BAE63 /* CCStencilBitsManager.cpp in Sources */, 15AE194B19AAD35100C27E9E /* CCComRender.cpp in Sources */, 382384451A25915C002C4610 /* SpriteReader.cpp in Sources */, B6CAB2321AF9AA1A00B9B856 /* btCollisionWorld.cpp in Sources */, diff --git a/cocos/2d/CCClippingNode.cpp b/cocos/2d/CCClippingNode.cpp index fa1a5fdd55..e6e1b6a5cc 100644 --- a/cocos/2d/CCClippingNode.cpp +++ b/cocos/2d/CCClippingNode.cpp @@ -32,6 +32,7 @@ #include "renderer/CCRenderer.h" #include "renderer/CCRenderState.h" #include "base/CCDirector.h" +#include "base/CCStencilBitsManager.hpp" #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) #define CC_CLIPPING_NODE_OPENGLES 0 @@ -42,10 +43,7 @@ NS_CC_BEGIN static GLint g_sStencilBits = -1; -// store the current stencil layer (position in the stencil buffer), -// this will allow nesting up to n ClippingNode, -// where n is the number of bits of the stencil buffer. -static GLint s_layer = -1; + #if CC_CLIPPING_NODE_OPENGLES static void setProgram(Node *n, GLProgram *p) @@ -398,7 +396,9 @@ void ClippingNode::onBeforeVisit() // INIT // increment the current layer + auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); s_layer++; + StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); // mask of the current layer (ie: for layer 3: 00000100) GLint mask_layer = 0x1 << s_layer; @@ -563,7 +563,9 @@ void ClippingNode::onAfterVisit() } // we are done using this layer, decrement + auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); s_layer--; + StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); } NS_CC_END diff --git a/cocos/2d/libcocos2d.vcxproj b/cocos/2d/libcocos2d.vcxproj index 7f4b973e6d..8752d8ba2f 100644 --- a/cocos/2d/libcocos2d.vcxproj +++ b/cocos/2d/libcocos2d.vcxproj @@ -1,4 +1,4 @@ - + @@ -433,6 +433,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.* + @@ -1015,6 +1016,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.* + @@ -1383,4 +1385,4 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.* - \ No newline at end of file + diff --git a/cocos/2d/libcocos2d.vcxproj.filters b/cocos/2d/libcocos2d.vcxproj.filters index d664d13291..01067a13cf 100644 --- a/cocos/2d/libcocos2d.vcxproj.filters +++ b/cocos/2d/libcocos2d.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -1896,6 +1896,9 @@ base + + base + renderer @@ -3728,6 +3731,9 @@ base + + base + renderer @@ -3807,4 +3813,4 @@ 3d - \ No newline at end of file + diff --git a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems index 55826bcba5..3ca9b6814f 100644 --- a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems +++ b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems @@ -1,4 +1,4 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -286,6 +286,7 @@ + @@ -917,6 +918,7 @@ + @@ -1286,4 +1288,4 @@ - \ No newline at end of file + diff --git a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters index 67cb711ca5..5cd31d8512 100644 --- a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters +++ b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters @@ -1,4 +1,4 @@ - + @@ -1812,6 +1812,9 @@ base + + base + physics3d @@ -3525,6 +3528,9 @@ base + + base + physics3d @@ -3979,4 +3985,4 @@ - \ No newline at end of file + diff --git a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj index 05a3f1c085..cd02a95bd9 100644 --- a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj +++ b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj @@ -1,4 +1,4 @@ - + @@ -415,6 +415,7 @@ + @@ -1013,6 +1014,7 @@ + @@ -1673,4 +1675,4 @@ - \ No newline at end of file + diff --git a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters index d5bb1efb55..67d153e5e9 100644 --- a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters +++ b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -1767,6 +1767,9 @@ base + + base + renderer @@ -3635,6 +3638,9 @@ base + + base + renderer @@ -4017,4 +4023,4 @@ 3d - \ No newline at end of file + diff --git a/cocos/Android.mk b/cocos/Android.mk index c8bbba2b0e..a6f789ce7b 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -107,6 +107,7 @@ math/Vec2.cpp \ math/Vec3.cpp \ math/Vec4.cpp \ base/CCNinePatchImageParser.cpp \ +base/CCStencilBitsManager.cpp \ base/CCAsyncTaskPool.cpp \ base/CCAutoreleasePool.cpp \ base/CCConfiguration.cpp \ diff --git a/cocos/base/CCStencilBitsManager.cpp b/cocos/base/CCStencilBitsManager.cpp new file mode 100644 index 0000000000..ab6f20d7eb --- /dev/null +++ b/cocos/base/CCStencilBitsManager.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** + Copyright (c) 2010-2012 cocos2d-x.org + Copyright (c) 2013-2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#include "CCStencilBitsManager.hpp" + +StencilBitsManager* StencilBitsManager::_stencilBitsManager = nullptr; + +GLint StencilBitsManager::getStencilLayerMask()const +{ + return _stencilLayerMask; +} + +void StencilBitsManager::setStencilLayerMask(GLint stencilLayer) +{ + _stencilLayerMask = stencilLayer; +} + +StencilBitsManager::StencilBitsManager() +:_stencilLayerMask(-1) +{ + +} \ No newline at end of file diff --git a/cocos/base/CCStencilBitsManager.hpp b/cocos/base/CCStencilBitsManager.hpp new file mode 100644 index 0000000000..86a5476f9b --- /dev/null +++ b/cocos/base/CCStencilBitsManager.hpp @@ -0,0 +1,49 @@ +/**************************************************************************** + Copyright (c) 2010-2012 cocos2d-x.org + Copyright (c) 2013-2015 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ +#ifndef StencilBitsManager_hpp +#define StencilBitsManager_hpp + +class StencilBitsManager +{ +public: + static StencilBitsManager* getInstance() + { + if(nullptr == _stencilBitsManager) + { + _stencilBitsManager = new StencilBitsManager(); + } + return _stencilBitsManager; + } + GLint getStencilLayerMask()const; + void setStencilLayerMask(GLint stencilLayer); +private: + static StencilBitsManager* _stencilBitsManager; + StencilBitsManager(); + StencilBitsManager(const StencilBitsManager& other); + StencilBitsManager& operator=(const StencilBitsManager& other); + GLint _stencilLayerMask; +}; + +#endif /* StencilBitsManager_hpp */ diff --git a/cocos/base/CMakeLists.txt b/cocos/base/CMakeLists.txt index ec3884ddeb..7f18a43b18 100644 --- a/cocos/base/CMakeLists.txt +++ b/cocos/base/CMakeLists.txt @@ -45,6 +45,7 @@ set(COCOS_BASE_SRC base/CCUserDefault.cpp base/CCValue.cpp base/ObjectFactory.cpp + base/CCStencilBitsManager.cpp base/TGAlib.cpp base/ZipUtils.cpp base/allocator/CCAllocatorDiagnostics.cpp diff --git a/cocos/ui/UILayout.cpp b/cocos/ui/UILayout.cpp index 3f8cc02db8..cc6df90d6d 100644 --- a/cocos/ui/UILayout.cpp +++ b/cocos/ui/UILayout.cpp @@ -37,7 +37,7 @@ THE SOFTWARE. #include "2d/CCLayer.h" #include "2d/CCSprite.h" #include "base/CCEventFocus.h" - +#include "base/CCStencilBitsManager.hpp" NS_CC_BEGIN @@ -47,7 +47,6 @@ static const int BACKGROUNDIMAGE_Z = (-1); static const int BCAKGROUNDCOLORRENDERER_Z = (-2); static GLint g_sStencilBits = -1; -static GLint s_layer = -1; IMPLEMENT_CLASS_GUI_INFO(Layout) @@ -329,7 +328,9 @@ void Layout::stencilClippingVisit(Renderer *renderer, const Mat4& parentTransfor void Layout::onBeforeVisitStencil() { + auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); s_layer++; + StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); GLint mask_layer = 0x1 << s_layer; GLint mask_layer_l = mask_layer - 1; _mask_layer_le = mask_layer | mask_layer_l; @@ -454,7 +455,9 @@ void Layout::onAfterVisitStencil() glDisable(GL_STENCIL_TEST); // RenderState::StateBlock::_defaultState->setStencilTest(false); } + auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); s_layer--; + StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); } void Layout::onBeforeVisitScissor() diff --git a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp index b9e4655aed..7628a20ccf 100644 --- a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp +++ b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIListViewTest/UIListViewTest.cpp @@ -123,6 +123,16 @@ bool UIListViewTest_Vertical::init() custom_item->addChild(custom_button); listView->addChild(custom_item); + + auto clippingNode = ClippingNode::create(); + auto sprite = Sprite::create("cocosui/clippingHead.jpg"); + clippingNode->addChild(sprite); + auto stencil = Sprite::create("cocosui/clippingStencil.jpg"); + clippingNode->setStencil(stencil); + auto custom_item_contentSize = custom_item->getContentSize(); + clippingNode->setPosition(custom_item_contentSize.width/2, custom_item_contentSize.height/2); + clippingNode->setScale(0.5); + custom_item->addChild(clippingNode); } // insert custom item Vector& items = listView->getItems(); From b36f464c091b759b67c790be01269175acd7d1a7 Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Tue, 24 Nov 2015 18:06:11 +0800 Subject: [PATCH 2/7] update ccs-res submodule --- tests/cpp-tests/Resources/ccs-res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpp-tests/Resources/ccs-res b/tests/cpp-tests/Resources/ccs-res index 636129882b..e82bd71212 160000 --- a/tests/cpp-tests/Resources/ccs-res +++ b/tests/cpp-tests/Resources/ccs-res @@ -1 +1 @@ -Subproject commit 636129882b612b5fe6d1d21be1eec136a2b1340b +Subproject commit e82bd71212e53e016bf5f262f8e4bc1c50b54203 From 866c992f412a3f4514bb647080b9eb38d3d90018 Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Tue, 24 Nov 2015 20:26:48 +0800 Subject: [PATCH 3/7] add cocos2d namespace --- cocos/base/CCStencilBitsManager.cpp | 6 +++++- cocos/base/CCStencilBitsManager.hpp | 14 +++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cocos/base/CCStencilBitsManager.cpp b/cocos/base/CCStencilBitsManager.cpp index ab6f20d7eb..be689286f5 100644 --- a/cocos/base/CCStencilBitsManager.cpp +++ b/cocos/base/CCStencilBitsManager.cpp @@ -25,6 +25,8 @@ #include "CCStencilBitsManager.hpp" +NS_CC_BEGIN + StencilBitsManager* StencilBitsManager::_stencilBitsManager = nullptr; GLint StencilBitsManager::getStencilLayerMask()const @@ -41,4 +43,6 @@ StencilBitsManager::StencilBitsManager() :_stencilLayerMask(-1) { -} \ No newline at end of file +} + +NS_CC_END diff --git a/cocos/base/CCStencilBitsManager.hpp b/cocos/base/CCStencilBitsManager.hpp index 86a5476f9b..b630f83068 100644 --- a/cocos/base/CCStencilBitsManager.hpp +++ b/cocos/base/CCStencilBitsManager.hpp @@ -24,8 +24,17 @@ ****************************************************************************/ #ifndef StencilBitsManager_hpp #define StencilBitsManager_hpp +#include "base/ccConfig.h" +#include "platform/CCPlatformMacros.h" +#include "platform/CCGL.h" -class StencilBitsManager +/** + * @addtogroup base + * @{ + */ +NS_CC_BEGIN + +class CC_DLL StencilBitsManager { public: static StencilBitsManager* getInstance() @@ -46,4 +55,7 @@ private: GLint _stencilLayerMask; }; +NS_CC_END +// end of base group +/** @} */ #endif /* StencilBitsManager_hpp */ From 5fef0886957d4cec37925d370ecd65e3e8a0f51e Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Wed, 25 Nov 2015 14:14:17 +0800 Subject: [PATCH 4/7] refactor stencil state management code --- cocos/2d/CCClippingNode.cpp | 267 ++------------------------ cocos/2d/CCClippingNode.h | 31 +-- cocos/base/CCStencilBitsManager.cpp | 281 +++++++++++++++++++++++++++- cocos/base/CCStencilBitsManager.hpp | 50 +++-- cocos/ui/UILayout.cpp | 163 +--------------- cocos/ui/UILayout.h | 25 +-- 6 files changed, 327 insertions(+), 490 deletions(-) diff --git a/cocos/2d/CCClippingNode.cpp b/cocos/2d/CCClippingNode.cpp index e6e1b6a5cc..e2490e14fd 100644 --- a/cocos/2d/CCClippingNode.cpp +++ b/cocos/2d/CCClippingNode.cpp @@ -42,9 +42,6 @@ NS_CC_BEGIN -static GLint g_sStencilBits = -1; - - #if CC_CLIPPING_NODE_OPENGLES static void setProgram(Node *n, GLProgram *p) { @@ -59,22 +56,8 @@ static void setProgram(Node *n, GLProgram *p) ClippingNode::ClippingNode() : _stencil(nullptr) -, _alphaThreshold(0.0f) -, _inverted(false) -, _currentStencilEnabled(GL_FALSE) -, _currentStencilWriteMask(~0) -, _currentStencilFunc(GL_ALWAYS) -, _currentStencilRef(0) -, _currentStencilValueMask(~0) -, _currentStencilFail(GL_KEEP) -, _currentStencilPassDepthFail(GL_KEEP) -, _currentStencilPassDepthPass(GL_KEEP) -, _currentDepthWriteMask(GL_TRUE) -, _currentAlphaTestEnabled(GL_FALSE) -, _currentAlphaTestFunc(GL_ALWAYS) -, _currentAlphaTestRef(1) +,_stencilStateManager(new StencilStateManager()) { - } ClippingNode::~ClippingNode() @@ -127,19 +110,8 @@ bool ClippingNode::init(Node *stencil) _stencil = stencil; CC_SAFE_RETAIN(_stencil); - _alphaThreshold = 1; - _inverted = false; - // get (only once) the number of bits of the stencil buffer - static bool once = true; - if (once) - { - glGetIntegerv(GL_STENCIL_BITS, &g_sStencilBits); - if (g_sStencilBits <= 0) - { - CCLOG("Stencil buffer is not enabled."); - } - once = false; - } + _stencilStateManager->setAlphaThreshold(1.0f); + _stencilStateManager->setInverted(false); return true; } @@ -220,45 +192,6 @@ void ClippingNode::onExit() Node::onExit(); } -void ClippingNode::drawFullScreenQuadClearStencil() -{ - Director* director = Director::getInstance(); - CCASSERT(nullptr != director, "Director is null when setting matrix stack"); - - director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - - director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - - Vec2 vertices[] = { - Vec2(-1.0f, -1.0f), - Vec2(1.0f, -1.0f), - Vec2(1.0f, 1.0f), - Vec2(-1.0f, 1.0f) - }; - - auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_U_COLOR); - - int colorLocation = glProgram->getUniformLocation("u_color"); - CHECK_GL_ERROR_DEBUG(); - - Color4F color(1, 1, 1, 1); - - glProgram->use(); - glProgram->setUniformsForBuiltins(); - glProgram->setUniformLocationWith4fv(colorLocation, (GLfloat*) &color.r, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION ); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 4); - - director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); -} void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags) { @@ -283,9 +216,10 @@ void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32 renderer->pushGroup(_groupCommand.getRenderQueueID()); _beforeVisitCmd.init(_globalZOrder); - _beforeVisitCmd.func = CC_CALLBACK_0(ClippingNode::onBeforeVisit, this); + _beforeVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencilStateManager); renderer->addCommand(&_beforeVisitCmd); - if (_alphaThreshold < 1) + + if (_stencilStateManager->getAlphaThreshold() < 1) { #if CC_CLIPPING_NODE_OPENGLES // since glAlphaTest do not exists in OES, use a shader that writes @@ -305,7 +239,7 @@ void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32 _stencil->visit(renderer, _modelViewTransform, flags); _afterDrawStencilCmd.init(_globalZOrder); - _afterDrawStencilCmd.func = CC_CALLBACK_0(ClippingNode::onAfterDrawStencil, this); + _afterDrawStencilCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterDrawStencil, _stencilStateManager); renderer->addCommand(&_afterDrawStencilCmd); int i = 0; @@ -337,7 +271,7 @@ void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32 } _afterVisitCmd.init(_globalZOrder); - _afterVisitCmd.func = CC_CALLBACK_0(ClippingNode::onAfterVisit, this); + _afterVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterVisit, _stencilStateManager); renderer->addCommand(&_afterVisitCmd); renderer->popGroup(); @@ -372,200 +306,23 @@ bool ClippingNode::hasContent() const GLfloat ClippingNode::getAlphaThreshold() const { - return _alphaThreshold; + return _stencilStateManager->getAlphaThreshold(); } void ClippingNode::setAlphaThreshold(GLfloat alphaThreshold) { - _alphaThreshold = alphaThreshold; + _stencilStateManager->setAlphaThreshold(alphaThreshold); } bool ClippingNode::isInverted() const { - return _inverted; + return _stencilStateManager->isInverted(); } void ClippingNode::setInverted(bool inverted) { - _inverted = inverted; + _stencilStateManager->setInverted(inverted); } -void ClippingNode::onBeforeVisit() -{ - /////////////////////////////////// - // INIT - - // increment the current layer - auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); - s_layer++; - StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); - - // mask of the current layer (ie: for layer 3: 00000100) - GLint mask_layer = 0x1 << s_layer; - // mask of all layers less than the current (ie: for layer 3: 00000011) - GLint mask_layer_l = mask_layer - 1; - // mask of all layers less than or equal to the current (ie: for layer 3: 00000111) - _mask_layer_le = mask_layer | mask_layer_l; - - // manually save the stencil state - - _currentStencilEnabled = glIsEnabled(GL_STENCIL_TEST); - glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint *)&_currentStencilWriteMask); - glGetIntegerv(GL_STENCIL_FUNC, (GLint *)&_currentStencilFunc); - glGetIntegerv(GL_STENCIL_REF, &_currentStencilRef); - glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)&_currentStencilValueMask); - glGetIntegerv(GL_STENCIL_FAIL, (GLint *)&_currentStencilFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&_currentStencilPassDepthFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)&_currentStencilPassDepthPass); - - // enable stencil use - glEnable(GL_STENCIL_TEST); -// RenderState::StateBlock::_defaultState->setStencilTest(true); - - // check for OpenGL error while enabling stencil test - CHECK_GL_ERROR_DEBUG(); - - // all bits on the stencil buffer are readonly, except the current layer bit, - // this means that operation like glClear or glStencilOp will be masked with this value - glStencilMask(mask_layer); -// RenderState::StateBlock::_defaultState->setStencilWrite(mask_layer); - - // manually save the depth test state - - glGetBooleanv(GL_DEPTH_WRITEMASK, &_currentDepthWriteMask); - - // disable depth test while drawing the stencil - //glDisable(GL_DEPTH_TEST); - // disable update to the depth buffer while drawing the stencil, - // as the stencil is not meant to be rendered in the real scene, - // it should never prevent something else to be drawn, - // only disabling depth buffer update should do - glDepthMask(GL_FALSE); - RenderState::StateBlock::_defaultState->setDepthWrite(false); - - /////////////////////////////////// - // CLEAR STENCIL BUFFER - - // manually clear the stencil buffer by drawing a fullscreen rectangle on it - // setup the stencil test func like this: - // for each pixel in the fullscreen rectangle - // never draw it into the frame buffer - // if not in inverted mode: set the current layer value to 0 in the stencil buffer - // if in inverted mode: set the current layer value to 1 in the stencil buffer - glStencilFunc(GL_NEVER, mask_layer, mask_layer); - glStencilOp(!_inverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP); - - // draw a fullscreen solid rectangle to clear the stencil buffer - //ccDrawSolidRect(Vec2::ZERO, ccpFromSize([[Director sharedDirector] winSize]), Color4F(1, 1, 1, 1)); - drawFullScreenQuadClearStencil(); - - /////////////////////////////////// - // DRAW CLIPPING STENCIL - - // setup the stencil test func like this: - // for each pixel in the stencil node - // never draw it into the frame buffer - // if not in inverted mode: set the current layer value to 1 in the stencil buffer - // if in inverted mode: set the current layer value to 0 in the stencil buffer - glStencilFunc(GL_NEVER, mask_layer, mask_layer); -// RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_NEVER, mask_layer, mask_layer); - - glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP); -// RenderState::StateBlock::_defaultState->setStencilOperation( -// !_inverted ? RenderState::STENCIL_OP_REPLACE : RenderState::STENCIL_OP_ZERO, -// RenderState::STENCIL_OP_KEEP, -// RenderState::STENCIL_OP_KEEP); - - - // enable alpha test only if the alpha threshold < 1, - // indeed if alpha threshold == 1, every pixel will be drawn anyways - if (_alphaThreshold < 1) { -#if !CC_CLIPPING_NODE_OPENGLES - // manually save the alpha test state - _currentAlphaTestEnabled = glIsEnabled(GL_ALPHA_TEST); - glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint *)&_currentAlphaTestFunc); - glGetFloatv(GL_ALPHA_TEST_REF, &_currentAlphaTestRef); - // enable alpha testing - glEnable(GL_ALPHA_TEST); - // check for OpenGL error while enabling alpha test - CHECK_GL_ERROR_DEBUG(); - // pixel will be drawn only if greater than an alpha threshold - glAlphaFunc(GL_GREATER, _alphaThreshold); -#endif - } - - //Draw _stencil -} - -void ClippingNode::onAfterDrawStencil() -{ - // restore alpha test state - if (_alphaThreshold < 1) - { -#if CC_CLIPPING_NODE_OPENGLES - // FIXME: we need to find a way to restore the shaders of the stencil node and its children -#else - // manually restore the alpha test state - glAlphaFunc(_currentAlphaTestFunc, _currentAlphaTestRef); - if (!_currentAlphaTestEnabled) - { - glDisable(GL_ALPHA_TEST); - } -#endif - } - - // restore the depth test state - glDepthMask(_currentDepthWriteMask); - RenderState::StateBlock::_defaultState->setDepthWrite(_currentDepthWriteMask != 0); - - //if (currentDepthTestEnabled) { - // glEnable(GL_DEPTH_TEST); - //} - - /////////////////////////////////// - // DRAW CONTENT - - // setup the stencil test function like this: - // for each pixel of this node and its children - // if all layers less than or equals to the current are set to 1 in the stencil buffer - // draw the pixel and keep the current layer in the stencil buffer - // else - // do not draw the pixel but keep the current layer in the stencil buffer - glStencilFunc(GL_EQUAL, _mask_layer_le, _mask_layer_le); -// RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_EQUAL, _mask_layer_le, _mask_layer_le); - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); -// RenderState::StateBlock::_defaultState->setStencilOperation(RenderState::STENCIL_OP_KEEP, RenderState::STENCIL_OP_KEEP, RenderState::STENCIL_OP_KEEP); - - // draw (according to the stencil test function) this node and its children -} - - -void ClippingNode::onAfterVisit() -{ - /////////////////////////////////// - // CLEANUP - - // manually restore the stencil state - glStencilFunc(_currentStencilFunc, _currentStencilRef, _currentStencilValueMask); -// RenderState::StateBlock::_defaultState->setStencilFunction((RenderState::StencilFunction)_currentStencilFunc, _currentStencilRef, _currentStencilValueMask); - - glStencilOp(_currentStencilFail, _currentStencilPassDepthFail, _currentStencilPassDepthPass); -// RenderState::StateBlock::_defaultState->setStencilOperation((RenderState::StencilOperation)_currentStencilFail, -// (RenderState::StencilOperation)_currentStencilPassDepthFail, -// (RenderState::StencilOperation)_currentStencilPassDepthPass); - - glStencilMask(_currentStencilWriteMask); - if (!_currentStencilEnabled) - { - glDisable(GL_STENCIL_TEST); -// RenderState::StateBlock::_defaultState->setStencilTest(false); - } - - // we are done using this layer, decrement - auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); - s_layer--; - StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); -} NS_CC_END diff --git a/cocos/2d/CCClippingNode.h b/cocos/2d/CCClippingNode.h index 63ea9140ca..faba9dfd3b 100644 --- a/cocos/2d/CCClippingNode.h +++ b/cocos/2d/CCClippingNode.h @@ -34,6 +34,8 @@ #include "renderer/CCCustomCommand.h" NS_CC_BEGIN + +class StencilStateManager; /** * @addtogroup _2d * @{ @@ -153,34 +155,9 @@ CC_CONSTRUCTOR_ACCESS: virtual bool init(Node *stencil); protected: - /**draw fullscreen quad to clear stencil bits - */ - void drawFullScreenQuadClearStencil(); - Node* _stencil; - GLfloat _alphaThreshold; - bool _inverted; - - //renderData and callback - void onBeforeVisit(); - void onAfterDrawStencil(); - void onAfterVisit(); - - GLboolean _currentStencilEnabled; - GLuint _currentStencilWriteMask; - GLenum _currentStencilFunc; - GLint _currentStencilRef; - GLuint _currentStencilValueMask; - GLenum _currentStencilFail; - GLenum _currentStencilPassDepthFail; - GLenum _currentStencilPassDepthPass; - GLboolean _currentDepthWriteMask; - - GLboolean _currentAlphaTestEnabled; - GLenum _currentAlphaTestFunc; - GLclampf _currentAlphaTestRef; - - GLint _mask_layer_le; + + StencilStateManager* _stencilStateManager; GroupCommand _groupCommand; CustomCommand _beforeVisitCmd; diff --git a/cocos/base/CCStencilBitsManager.cpp b/cocos/base/CCStencilBitsManager.cpp index be689286f5..e1c6835f50 100644 --- a/cocos/base/CCStencilBitsManager.cpp +++ b/cocos/base/CCStencilBitsManager.cpp @@ -24,25 +24,286 @@ ****************************************************************************/ #include "CCStencilBitsManager.hpp" +#include "base/CCDirector.h" +#include "renderer/CCGLProgramCache.h" +#include "renderer/ccGLStateCache.h" +#include "renderer/CCRenderer.h" +#include "renderer/CCRenderState.h" +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) +#define CC_CLIPPING_NODE_OPENGLES 0 +#else +#define CC_CLIPPING_NODE_OPENGLES 1 +#endif NS_CC_BEGIN -StencilBitsManager* StencilBitsManager::_stencilBitsManager = nullptr; +GLint StencilStateManager::s_layer = -1; +static GLint g_sStencilBits = -1; + +StencilStateManager::StencilStateManager() +: _alphaThreshold(0.0f) +, _inverted(false) +, _currentStencilEnabled(GL_FALSE) +, _currentStencilWriteMask(~0) +, _currentStencilFunc(GL_ALWAYS) +, _currentStencilRef(0) +, _currentStencilValueMask(~0) +, _currentStencilFail(GL_KEEP) +, _currentStencilPassDepthFail(GL_KEEP) +, _currentStencilPassDepthPass(GL_KEEP) +, _currentDepthWriteMask(GL_TRUE) +, _currentAlphaTestEnabled(GL_FALSE) +, _currentAlphaTestFunc(GL_ALWAYS) +, _currentAlphaTestRef(1) -GLint StencilBitsManager::getStencilLayerMask()const { - return _stencilLayerMask; + // get (only once) the number of bits of the stencil buffer + static bool once = true; + if (once) + { + glGetIntegerv(GL_STENCIL_BITS, &g_sStencilBits); + if (g_sStencilBits <= 0) + { + CCLOG("Stencil buffer is not enabled."); + } + once = false; + } } -void StencilBitsManager::setStencilLayerMask(GLint stencilLayer) -{ - _stencilLayerMask = stencilLayer; -} - -StencilBitsManager::StencilBitsManager() -:_stencilLayerMask(-1) +void StencilStateManager::drawFullScreenQuadClearStencil() { + Director* director = Director::getInstance(); + CCASSERT(nullptr != director, "Director is null when setting matrix stack"); + director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); + director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); + + director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); + director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); + + Vec2 vertices[] = { + Vec2(-1.0f, -1.0f), + Vec2(1.0f, -1.0f), + Vec2(1.0f, 1.0f), + Vec2(-1.0f, 1.0f) + }; + + auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_U_COLOR); + + int colorLocation = glProgram->getUniformLocation("u_color"); + CHECK_GL_ERROR_DEBUG(); + + Color4F color(1, 1, 1, 1); + + glProgram->use(); + glProgram->setUniformsForBuiltins(); + glProgram->setUniformLocationWith4fv(colorLocation, (GLfloat*) &color.r, 1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION ); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 4); + + director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); + director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } + +void StencilStateManager::setAlphaThreshold(GLfloat alphaThreshold) +{ + _alphaThreshold = alphaThreshold; +} + +GLfloat StencilStateManager::getAlphaThreshold()const +{ + return _alphaThreshold; +} + +void StencilStateManager::setInverted(bool inverted) +{ + _inverted = inverted; +} + +bool StencilStateManager::isInverted()const +{ + return _inverted; +} + +void StencilStateManager::onBeforeVisit() +{ + /////////////////////////////////// + // INIT + + // increment the current layer + s_layer++; + + // mask of the current layer (ie: for layer 3: 00000100) + GLint mask_layer = 0x1 << s_layer; + // mask of all layers less than the current (ie: for layer 3: 00000011) + GLint mask_layer_l = mask_layer - 1; + // mask of all layers less than or equal to the current (ie: for layer 3: 00000111) + _mask_layer_le = mask_layer | mask_layer_l; + + // manually save the stencil state + + _currentStencilEnabled = glIsEnabled(GL_STENCIL_TEST); + glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint *)&_currentStencilWriteMask); + glGetIntegerv(GL_STENCIL_FUNC, (GLint *)&_currentStencilFunc); + glGetIntegerv(GL_STENCIL_REF, &_currentStencilRef); + glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)&_currentStencilValueMask); + glGetIntegerv(GL_STENCIL_FAIL, (GLint *)&_currentStencilFail); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&_currentStencilPassDepthFail); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)&_currentStencilPassDepthPass); + + // enable stencil use + glEnable(GL_STENCIL_TEST); + // RenderState::StateBlock::_defaultState->setStencilTest(true); + + // check for OpenGL error while enabling stencil test + CHECK_GL_ERROR_DEBUG(); + + // all bits on the stencil buffer are readonly, except the current layer bit, + // this means that operation like glClear or glStencilOp will be masked with this value + glStencilMask(mask_layer); + // RenderState::StateBlock::_defaultState->setStencilWrite(mask_layer); + + // manually save the depth test state + + glGetBooleanv(GL_DEPTH_WRITEMASK, &_currentDepthWriteMask); + + // disable depth test while drawing the stencil + //glDisable(GL_DEPTH_TEST); + // disable update to the depth buffer while drawing the stencil, + // as the stencil is not meant to be rendered in the real scene, + // it should never prevent something else to be drawn, + // only disabling depth buffer update should do + glDepthMask(GL_FALSE); + RenderState::StateBlock::_defaultState->setDepthWrite(false); + + /////////////////////////////////// + // CLEAR STENCIL BUFFER + + // manually clear the stencil buffer by drawing a fullscreen rectangle on it + // setup the stencil test func like this: + // for each pixel in the fullscreen rectangle + // never draw it into the frame buffer + // if not in inverted mode: set the current layer value to 0 in the stencil buffer + // if in inverted mode: set the current layer value to 1 in the stencil buffer + glStencilFunc(GL_NEVER, mask_layer, mask_layer); + glStencilOp(!_inverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP); + + // draw a fullscreen solid rectangle to clear the stencil buffer + //ccDrawSolidRect(Vec2::ZERO, ccpFromSize([[Director sharedDirector] winSize]), Color4F(1, 1, 1, 1)); + drawFullScreenQuadClearStencil(); + + /////////////////////////////////// + // DRAW CLIPPING STENCIL + + // setup the stencil test func like this: + // for each pixel in the stencil node + // never draw it into the frame buffer + // if not in inverted mode: set the current layer value to 1 in the stencil buffer + // if in inverted mode: set the current layer value to 0 in the stencil buffer + glStencilFunc(GL_NEVER, mask_layer, mask_layer); + // RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_NEVER, mask_layer, mask_layer); + + glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP); + // RenderState::StateBlock::_defaultState->setStencilOperation( + // !_inverted ? RenderState::STENCIL_OP_REPLACE : RenderState::STENCIL_OP_ZERO, + // RenderState::STENCIL_OP_KEEP, + // RenderState::STENCIL_OP_KEEP); + + + // enable alpha test only if the alpha threshold < 1, + // indeed if alpha threshold == 1, every pixel will be drawn anyways + if (_alphaThreshold < 1) { +#if !CC_CLIPPING_NODE_OPENGLES + // manually save the alpha test state + _currentAlphaTestEnabled = glIsEnabled(GL_ALPHA_TEST); + glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint *)&_currentAlphaTestFunc); + glGetFloatv(GL_ALPHA_TEST_REF, &_currentAlphaTestRef); + // enable alpha testing + glEnable(GL_ALPHA_TEST); + // check for OpenGL error while enabling alpha test + CHECK_GL_ERROR_DEBUG(); + // pixel will be drawn only if greater than an alpha threshold + glAlphaFunc(GL_GREATER, _alphaThreshold); +#endif + } + + //Draw _stencil +} + +void StencilStateManager::onAfterDrawStencil() +{ + // restore alpha test state + if (_alphaThreshold < 1) + { +#if CC_CLIPPING_NODE_OPENGLES + // FIXME: we need to find a way to restore the shaders of the stencil node and its children +#else + // manually restore the alpha test state + glAlphaFunc(_currentAlphaTestFunc, _currentAlphaTestRef); + if (!_currentAlphaTestEnabled) + { + glDisable(GL_ALPHA_TEST); + } +#endif + } + + // restore the depth test state + glDepthMask(_currentDepthWriteMask); + RenderState::StateBlock::_defaultState->setDepthWrite(_currentDepthWriteMask != 0); + + //if (currentDepthTestEnabled) { + // glEnable(GL_DEPTH_TEST); + //} + + /////////////////////////////////// + // DRAW CONTENT + + // setup the stencil test function like this: + // for each pixel of this node and its children + // if all layers less than or equals to the current are set to 1 in the stencil buffer + // draw the pixel and keep the current layer in the stencil buffer + // else + // do not draw the pixel but keep the current layer in the stencil buffer + glStencilFunc(GL_EQUAL, _mask_layer_le, _mask_layer_le); + // RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_EQUAL, _mask_layer_le, _mask_layer_le); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + // RenderState::StateBlock::_defaultState->setStencilOperation(RenderState::STENCIL_OP_KEEP, RenderState::STENCIL_OP_KEEP, RenderState::STENCIL_OP_KEEP); + + // draw (according to the stencil test function) this node and its children + +} + +void StencilStateManager::onAfterVisit() +{ + /////////////////////////////////// + // CLEANUP + + // manually restore the stencil state + glStencilFunc(_currentStencilFunc, _currentStencilRef, _currentStencilValueMask); + // RenderState::StateBlock::_defaultState->setStencilFunction((RenderState::StencilFunction)_currentStencilFunc, _currentStencilRef, _currentStencilValueMask); + + glStencilOp(_currentStencilFail, _currentStencilPassDepthFail, _currentStencilPassDepthPass); + // RenderState::StateBlock::_defaultState->setStencilOperation((RenderState::StencilOperation)_currentStencilFail, + // (RenderState::StencilOperation)_currentStencilPassDepthFail, + // (RenderState::StencilOperation)_currentStencilPassDepthPass); + + glStencilMask(_currentStencilWriteMask); + if (!_currentStencilEnabled) + { + glDisable(GL_STENCIL_TEST); + // RenderState::StateBlock::_defaultState->setStencilTest(false); + } + + // we are done using this layer, decrement + s_layer--; +} + + NS_CC_END diff --git a/cocos/base/CCStencilBitsManager.hpp b/cocos/base/CCStencilBitsManager.hpp index b630f83068..be67f58c90 100644 --- a/cocos/base/CCStencilBitsManager.hpp +++ b/cocos/base/CCStencilBitsManager.hpp @@ -34,25 +34,43 @@ */ NS_CC_BEGIN -class CC_DLL StencilBitsManager +class CC_DLL StencilStateManager { public: - static StencilBitsManager* getInstance() - { - if(nullptr == _stencilBitsManager) - { - _stencilBitsManager = new StencilBitsManager(); - } - return _stencilBitsManager; - } - GLint getStencilLayerMask()const; - void setStencilLayerMask(GLint stencilLayer); + StencilStateManager(); + void onBeforeVisit(); + void onAfterDrawStencil(); + void onAfterVisit(); + void setAlphaThreshold(GLfloat alphaThreshold); + void setInverted(bool inverted); + bool isInverted()const; + GLfloat getAlphaThreshold()const; private: - static StencilBitsManager* _stencilBitsManager; - StencilBitsManager(); - StencilBitsManager(const StencilBitsManager& other); - StencilBitsManager& operator=(const StencilBitsManager& other); - GLint _stencilLayerMask; + CC_DISALLOW_COPY_AND_ASSIGN(StencilStateManager); + static GLint s_layer; + /**draw fullscreen quad to clear stencil bits + */ + void drawFullScreenQuadClearStencil(); + + + GLfloat _alphaThreshold; + bool _inverted; + + GLboolean _currentStencilEnabled; + GLuint _currentStencilWriteMask; + GLenum _currentStencilFunc; + GLint _currentStencilRef; + GLuint _currentStencilValueMask; + GLenum _currentStencilFail; + GLenum _currentStencilPassDepthFail; + GLenum _currentStencilPassDepthPass; + GLboolean _currentDepthWriteMask; + + GLboolean _currentAlphaTestEnabled; + GLenum _currentAlphaTestFunc; + GLclampf _currentAlphaTestRef; + + GLint _mask_layer_le; }; NS_CC_END diff --git a/cocos/ui/UILayout.cpp b/cocos/ui/UILayout.cpp index cc6df90d6d..17c441f887 100644 --- a/cocos/ui/UILayout.cpp +++ b/cocos/ui/UILayout.cpp @@ -74,18 +74,7 @@ _clippingStencil(nullptr), _clippingRect(Rect::ZERO), _clippingParent(nullptr), _clippingRectDirty(true), -_currentStencilEnabled(GL_FALSE), -_currentStencilWriteMask(~0), -_currentStencilFunc(GL_ALWAYS), -_currentStencilRef(0), -_currentStencilValueMask(~0), -_currentStencilFail(GL_KEEP), -_currentStencilPassDepthFail(GL_KEEP), -_currentStencilPassDepthPass(GL_KEEP), -_currentDepthWriteMask(GL_TRUE), -_currentAlphaTestEnabled(GL_FALSE), -_currentAlphaTestFunc(GL_ALWAYS), -_currentAlphaTestRef(1), +_stencileStateManager(new StencilStateManager()), _doLayoutDirty(true), _isInterceptTouch(false), _loopFocus(false), @@ -264,13 +253,13 @@ void Layout::stencilClippingVisit(Renderer *renderer, const Mat4& parentTransfor renderer->pushGroup(_groupCommand.getRenderQueueID()); _beforeVisitCmdStencil.init(_globalZOrder); - _beforeVisitCmdStencil.func = CC_CALLBACK_0(Layout::onBeforeVisitStencil, this); + _beforeVisitCmdStencil.func = CC_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencileStateManager); renderer->addCommand(&_beforeVisitCmdStencil); _clippingStencil->visit(renderer, _modelViewTransform, flags); _afterDrawStencilCmd.init(_globalZOrder); - _afterDrawStencilCmd.func = CC_CALLBACK_0(Layout::onAfterDrawStencil, this); + _afterDrawStencilCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterDrawStencil, _stencileStateManager); renderer->addCommand(&_afterDrawStencilCmd); int i = 0; // used by _children @@ -318,7 +307,7 @@ void Layout::stencilClippingVisit(Renderer *renderer, const Mat4& parentTransfor _afterVisitCmdStencil.init(_globalZOrder); - _afterVisitCmdStencil.func = CC_CALLBACK_0(Layout::onAfterVisitStencil, this); + _afterVisitCmdStencil.func = CC_CALLBACK_0(StencilStateManager::onAfterVisit, _stencileStateManager); renderer->addCommand(&_afterVisitCmdStencil); renderer->popGroup(); @@ -326,140 +315,6 @@ void Layout::stencilClippingVisit(Renderer *renderer, const Mat4& parentTransfor director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } -void Layout::onBeforeVisitStencil() -{ - auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); - s_layer++; - StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); - GLint mask_layer = 0x1 << s_layer; - GLint mask_layer_l = mask_layer - 1; - _mask_layer_le = mask_layer | mask_layer_l; - _currentStencilEnabled = glIsEnabled(GL_STENCIL_TEST); - glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint *)&_currentStencilWriteMask); - glGetIntegerv(GL_STENCIL_FUNC, (GLint *)&_currentStencilFunc); - glGetIntegerv(GL_STENCIL_REF, &_currentStencilRef); - glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)&_currentStencilValueMask); - glGetIntegerv(GL_STENCIL_FAIL, (GLint *)&_currentStencilFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&_currentStencilPassDepthFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)&_currentStencilPassDepthPass); - - glEnable(GL_STENCIL_TEST); -// RenderState::StateBlock::_defaultState->setStencilTest(true); - - CHECK_GL_ERROR_DEBUG(); - glStencilMask(mask_layer); -// RenderState::StateBlock::_defaultState->setStencilWrite(mask_layer); - - glGetBooleanv(GL_DEPTH_WRITEMASK, &_currentDepthWriteMask); - - glDepthMask(GL_FALSE); - RenderState::StateBlock::_defaultState->setDepthWrite(false); - - glStencilFunc(GL_NEVER, mask_layer, mask_layer); - glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP); - - - this->drawFullScreenQuadClearStencil(); - - glStencilFunc(GL_NEVER, mask_layer, mask_layer); -// RenderState::StateBlock::_defaultState->setStencilFunction( -// RenderState::STENCIL_NEVER, -// mask_layer, -// mask_layer); - - glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); -// RenderState::StateBlock::_defaultState->setStencilOperation( -// RenderState::STENCIL_OP_REPLACE, -// RenderState::STENCIL_OP_KEEP, -// RenderState::STENCIL_OP_KEEP); -} - -void Layout::drawFullScreenQuadClearStencil() -{ - Director* director = Director::getInstance(); - CCASSERT(nullptr != director, "Director is null when setting matrix stack"); - - director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - - director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - - Vec2 vertices[] = - { - Vec2(-1, -1), - Vec2(1, -1), - Vec2(1, 1), - Vec2(-1, 1) - }; - - auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_U_COLOR); - - int colorLocation = glProgram->getUniformLocation("u_color"); - CHECK_GL_ERROR_DEBUG(); - - Color4F color(1, 1, 1, 1); - - glProgram->use(); - glProgram->setUniformsForBuiltins(); - glProgram->setUniformLocationWith4fv(colorLocation, (GLfloat*) &color.r, 1); - - GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION ); - - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 4); - - director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); -} - -void Layout::onAfterDrawStencil() -{ - glDepthMask(_currentDepthWriteMask); - RenderState::StateBlock::_defaultState->setDepthWrite(_currentDepthWriteMask != 0); - - glStencilFunc(GL_EQUAL, _mask_layer_le, _mask_layer_le); -// RenderState::StateBlock::_defaultState->setStencilFunction( -// RenderState::STENCIL_EQUAL, -// _mask_layer_le, -// _mask_layer_le); - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); -// RenderState::StateBlock::_defaultState->setStencilOperation( -// RenderState::STENCIL_OP_KEEP, -// RenderState::STENCIL_OP_KEEP, -// RenderState::STENCIL_OP_KEEP); - -} - - -void Layout::onAfterVisitStencil() -{ - glStencilFunc(_currentStencilFunc, _currentStencilRef, _currentStencilValueMask); -// RenderState::StateBlock::_defaultState->setStencilFunction( -// (RenderState::StencilFunction)_currentStencilFunc, -// _currentStencilRef, -// _currentStencilValueMask); - - glStencilOp(_currentStencilFail, _currentStencilPassDepthFail, _currentStencilPassDepthPass); -// RenderState::StateBlock::_defaultState->setStencilOperation( -// (RenderState::StencilOperation)_currentStencilFail, -// (RenderState::StencilOperation)_currentStencilPassDepthFail, -// (RenderState::StencilOperation)_currentStencilPassDepthPass); - - glStencilMask(_currentStencilWriteMask); - if (!_currentStencilEnabled) - { - glDisable(GL_STENCIL_TEST); -// RenderState::StateBlock::_defaultState->setStencilTest(false); - } - auto s_layer = StencilBitsManager::getInstance()->getStencilLayerMask(); - s_layer--; - StencilBitsManager::getInstance()->setStencilLayerMask(s_layer); -} - void Layout::onBeforeVisitScissor() { auto glview = Director::getInstance()->getOpenGLView(); @@ -532,16 +387,6 @@ void Layout::setClippingEnabled(bool able) case ClippingType::STENCIL: if (able) { - static bool once = true; - if (once) - { - glGetIntegerv(GL_STENCIL_BITS, &g_sStencilBits); - if (g_sStencilBits <= 0) - { - CCLOG("Stencil buffer is not enabled."); - } - once = false; - } _clippingStencil = DrawNode::create(); if (_running) { diff --git a/cocos/ui/UILayout.h b/cocos/ui/UILayout.h index f98c37bcdf..5975162ed0 100644 --- a/cocos/ui/UILayout.h +++ b/cocos/ui/UILayout.h @@ -39,7 +39,7 @@ NS_CC_BEGIN class DrawNode; class LayerColor; class LayerGradient; - +class StencilStateManager; namespace ui { @@ -486,12 +486,6 @@ protected: virtual const Vector& getLayoutElements()const override; //clipping - void onBeforeVisitStencil(); - void onAfterDrawStencil(); - void onAfterVisitStencil(); - /**draw fullscreen quad to clear stencil bits - */ - void drawFullScreenQuadClearStencil(); void onBeforeVisitScissor(); void onAfterVisitScissor(); @@ -635,23 +629,8 @@ protected: bool _clippingRectDirty; //clipping + StencilStateManager *_stencileStateManager; - GLboolean _currentStencilEnabled; - GLuint _currentStencilWriteMask; - GLenum _currentStencilFunc; - GLint _currentStencilRef; - GLuint _currentStencilValueMask; - GLenum _currentStencilFail; - GLenum _currentStencilPassDepthFail; - GLenum _currentStencilPassDepthPass; - GLboolean _currentDepthWriteMask; - - GLboolean _currentAlphaTestEnabled; - GLenum _currentAlphaTestFunc; - GLclampf _currentAlphaTestRef; - - - GLint _mask_layer_le; GroupCommand _groupCommand; CustomCommand _beforeVisitCmdStencil; CustomCommand _afterDrawStencilCmd; From 759c0bbf31b49b3ab54be22aed44461b5ca5a850 Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Wed, 25 Nov 2015 14:24:27 +0800 Subject: [PATCH 5/7] rename CCStencilBitsManager to StencilStateManager --- build/cocos2d_libs.xcodeproj/project.pbxproj | 28 +++++++++---------- cocos/2d/CCClippingNode.cpp | 2 +- cocos/2d/libcocos2d.vcxproj | 4 +-- cocos/2d/libcocos2d.vcxproj.filters | 4 +-- .../libcocos2d_8_1.Shared.vcxitems | 4 +-- .../libcocos2d_8_1.Shared.vcxitems.filters | 4 +-- cocos/2d/libcocos2d_win10/libcocos2d.vcxproj | 4 +-- .../libcocos2d.vcxproj.filters | 4 +-- cocos/Android.mk | 2 +- ...sManager.cpp => CCStencilStateManager.cpp} | 2 +- ...sManager.hpp => CCStencilStateManager.hpp} | 6 ++-- cocos/base/CMakeLists.txt | 2 +- cocos/ui/UILayout.cpp | 4 +-- 13 files changed, 34 insertions(+), 36 deletions(-) rename cocos/base/{CCStencilBitsManager.cpp => CCStencilStateManager.cpp} (99%) rename cocos/base/{CCStencilBitsManager.hpp => CCStencilStateManager.hpp} (96%) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 7357b4b972..027713d954 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1234,11 +1234,11 @@ 2980F02B1BA9A5550059E678 /* UITextView+CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0201BA9A5550059E678 /* UITextView+CCUITextInput.h */; }; 2980F02C1BA9A5550059E678 /* UITextView+CCUITextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F0211BA9A5550059E678 /* UITextView+CCUITextInput.mm */; }; 2986667F18B1B246000E39CA /* CCTweenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2986667818B1B079000E39CA /* CCTweenFunction.cpp */; }; - 298C75D51C0465D0006BAE63 /* CCStencilBitsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */; }; - 298C75D61C0465D1006BAE63 /* CCStencilBitsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */; }; - 298C75D71C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */; }; - 298C75D81C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */; }; - 298C75D91C04681F006BAE63 /* CCStencilBitsManager.hpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */; }; + 298C75D51C0465D0006BAE63 /* CCStencilStateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */; }; + 298C75D61C0465D1006BAE63 /* CCStencilStateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */; }; + 298C75D71C0465D1006BAE63 /* CCStencilStateManager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilStateManager.hpp */; }; + 298C75D81C0465D1006BAE63 /* CCStencilStateManager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilStateManager.hpp */; }; + 298C75D91C04681F006BAE63 /* CCStencilStateManager.hpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D41C0465D0006BAE63 /* CCStencilStateManager.hpp */; }; 299754F4193EC95400A54AC3 /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; }; 299754F5193EC95400A54AC3 /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; }; 299754F6193EC95400A54AC3 /* ObjectFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 299754F3193EC95400A54AC3 /* ObjectFactory.h */; }; @@ -4149,8 +4149,8 @@ 2980F0211BA9A5550059E678 /* UITextView+CCUITextInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UITextView+CCUITextInput.mm"; sourceTree = ""; }; 2986667818B1B079000E39CA /* CCTweenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTweenFunction.cpp; sourceTree = ""; }; 2986667918B1B079000E39CA /* CCTweenFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTweenFunction.h; sourceTree = ""; }; - 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCStencilBitsManager.cpp; path = ../base/CCStencilBitsManager.cpp; sourceTree = ""; }; - 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CCStencilBitsManager.hpp; path = ../base/CCStencilBitsManager.hpp; sourceTree = ""; }; + 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCStencilStateManager.cpp; path = ../base/CCStencilStateManager.cpp; sourceTree = ""; }; + 298C75D41C0465D0006BAE63 /* CCStencilStateManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CCStencilStateManager.hpp; path = ../base/CCStencilStateManager.hpp; sourceTree = ""; }; 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectFactory.cpp; path = ../base/ObjectFactory.cpp; sourceTree = ""; }; 299754F3193EC95400A54AC3 /* ObjectFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectFactory.h; path = ../base/ObjectFactory.h; sourceTree = ""; }; 299CF1F919A434BC00C378C1 /* ccRandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ccRandom.cpp; path = ../base/ccRandom.cpp; sourceTree = ""; }; @@ -6044,8 +6044,8 @@ 50ABBE1C1925AB6F00A911A9 /* utlist.h */, 50ABBE1D1925AB6F00A911A9 /* ZipUtils.cpp */, 50ABBE1E1925AB6F00A911A9 /* ZipUtils.h */, - 298C75D31C0465D0006BAE63 /* CCStencilBitsManager.cpp */, - 298C75D41C0465D0006BAE63 /* CCStencilBitsManager.hpp */, + 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */, + 298C75D41C0465D0006BAE63 /* CCStencilStateManager.hpp */, ); name = base; path = ../cocos/2d; @@ -9238,7 +9238,7 @@ 15AE182A19AAD2F700C27E9E /* CCMeshSkin.h in Headers */, B276EF5F1988D1D500CD400F /* CCVertexIndexData.h in Headers */, 1A57007F180BC5A10088DEC7 /* CCActionInterval.h in Headers */, - 298C75D71C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */, + 298C75D71C0465D1006BAE63 /* CCStencilStateManager.hpp in Headers */, B6DD2FDB1B04825B00E47F5F /* DetourLocalBoundary.h in Headers */, B6CAB3491AF9AA1A00B9B856 /* gim_clip_polygon.h in Headers */, B677B0DB1B18492D006762CB /* CCNavMeshUtils.h in Headers */, @@ -10679,7 +10679,7 @@ 85505F051B60E3B2003F2CD4 /* CCBoneNode.h in Headers */, B665E2491AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h in Headers */, B6CAB4461AF9AA1A00B9B856 /* btParallelConstraintSolver.h in Headers */, - 298C75D81C0465D1006BAE63 /* CCStencilBitsManager.hpp in Headers */, + 298C75D81C0465D1006BAE63 /* CCStencilStateManager.hpp in Headers */, 15AE18D119AAD33D00C27E9E /* CCNodeLoaderLibrary.h in Headers */, 15AE1AC319AAD40300C27E9E /* b2DistanceJoint.h in Headers */, B6CAB5261AF9AA1A00B9B856 /* btQuickprof.h in Headers */, @@ -11841,7 +11841,7 @@ B665E2EE1AA80A6500DDB1C5 /* CCPULineEmitter.cpp in Sources */, B6CAB2DD1AF9AA1A00B9B856 /* btScaledBvhTriangleMeshShape.cpp in Sources */, B665E4121AA80A6600DDB1C5 /* CCPUTextureAnimator.cpp in Sources */, - 298C75D51C0465D0006BAE63 /* CCStencilBitsManager.cpp in Sources */, + 298C75D51C0465D0006BAE63 /* CCStencilStateManager.cpp in Sources */, B665E3D21AA80A6600DDB1C5 /* CCPUScriptLexer.cpp in Sources */, B665E4021AA80A6600DDB1C5 /* CCPUSphereColliderTranslator.cpp in Sources */, 15AE1A3619AAD3D500C27E9E /* b2PolygonShape.cpp in Sources */, @@ -11976,7 +11976,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 298C75D91C04681F006BAE63 /* CCStencilBitsManager.hpp in Sources */, + 298C75D91C04681F006BAE63 /* CCStencilStateManager.hpp in Sources */, D0FD03541A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp in Sources */, 15AE1B9819AADAA100C27E9E /* UIVideoPlayer-ios.mm in Sources */, B665E38F1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp in Sources */, @@ -12127,7 +12127,7 @@ 15AE193C19AAD35100C27E9E /* CCArmatureDefine.cpp in Sources */, B665E35F1AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp in Sources */, B29594B51926D5EC003EEF37 /* CCMeshCommand.cpp in Sources */, - 298C75D61C0465D1006BAE63 /* CCStencilBitsManager.cpp in Sources */, + 298C75D61C0465D1006BAE63 /* CCStencilStateManager.cpp in Sources */, 15AE194B19AAD35100C27E9E /* CCComRender.cpp in Sources */, 382384451A25915C002C4610 /* SpriteReader.cpp in Sources */, B6CAB2321AF9AA1A00B9B856 /* btCollisionWorld.cpp in Sources */, diff --git a/cocos/2d/CCClippingNode.cpp b/cocos/2d/CCClippingNode.cpp index e2490e14fd..1e6ccdcf01 100644 --- a/cocos/2d/CCClippingNode.cpp +++ b/cocos/2d/CCClippingNode.cpp @@ -32,7 +32,7 @@ #include "renderer/CCRenderer.h" #include "renderer/CCRenderState.h" #include "base/CCDirector.h" -#include "base/CCStencilBitsManager.hpp" +#include "base/CCStencilStateManager.hpp" #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) #define CC_CLIPPING_NODE_OPENGLES 0 diff --git a/cocos/2d/libcocos2d.vcxproj b/cocos/2d/libcocos2d.vcxproj index 8752d8ba2f..16ff56024b 100644 --- a/cocos/2d/libcocos2d.vcxproj +++ b/cocos/2d/libcocos2d.vcxproj @@ -433,7 +433,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.* - + @@ -1016,7 +1016,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.* - + diff --git a/cocos/2d/libcocos2d.vcxproj.filters b/cocos/2d/libcocos2d.vcxproj.filters index 01067a13cf..b1e6cf118f 100644 --- a/cocos/2d/libcocos2d.vcxproj.filters +++ b/cocos/2d/libcocos2d.vcxproj.filters @@ -1896,7 +1896,7 @@ base - + base @@ -3731,7 +3731,7 @@ base - + base diff --git a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems index 3ca9b6814f..31c39d506c 100644 --- a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems +++ b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems @@ -286,7 +286,7 @@ - + @@ -918,7 +918,7 @@ - + diff --git a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters index 5cd31d8512..b82b2259d5 100644 --- a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters +++ b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters @@ -1812,7 +1812,7 @@ base - + base @@ -3528,7 +3528,7 @@ base - + base diff --git a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj index cd02a95bd9..43532a8b82 100644 --- a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj +++ b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj @@ -415,7 +415,7 @@ - + @@ -1014,7 +1014,7 @@ - + diff --git a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters index 67d153e5e9..4bfeeae4aa 100644 --- a/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters +++ b/cocos/2d/libcocos2d_win10/libcocos2d.vcxproj.filters @@ -1767,7 +1767,7 @@ base - + base @@ -3638,7 +3638,7 @@ base - + base diff --git a/cocos/Android.mk b/cocos/Android.mk index a6f789ce7b..70afa67aa7 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -107,7 +107,7 @@ math/Vec2.cpp \ math/Vec3.cpp \ math/Vec4.cpp \ base/CCNinePatchImageParser.cpp \ -base/CCStencilBitsManager.cpp \ +base/CCStencilStateManager.cpp \ base/CCAsyncTaskPool.cpp \ base/CCAutoreleasePool.cpp \ base/CCConfiguration.cpp \ diff --git a/cocos/base/CCStencilBitsManager.cpp b/cocos/base/CCStencilStateManager.cpp similarity index 99% rename from cocos/base/CCStencilBitsManager.cpp rename to cocos/base/CCStencilStateManager.cpp index e1c6835f50..3467b12c97 100644 --- a/cocos/base/CCStencilBitsManager.cpp +++ b/cocos/base/CCStencilStateManager.cpp @@ -23,7 +23,7 @@ THE SOFTWARE. ****************************************************************************/ -#include "CCStencilBitsManager.hpp" +#include "CCStencilStateManager.hpp" #include "base/CCDirector.h" #include "renderer/CCGLProgramCache.h" #include "renderer/ccGLStateCache.h" diff --git a/cocos/base/CCStencilBitsManager.hpp b/cocos/base/CCStencilStateManager.hpp similarity index 96% rename from cocos/base/CCStencilBitsManager.hpp rename to cocos/base/CCStencilStateManager.hpp index be67f58c90..82e0c2ee0f 100644 --- a/cocos/base/CCStencilBitsManager.hpp +++ b/cocos/base/CCStencilStateManager.hpp @@ -22,8 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ -#ifndef StencilBitsManager_hpp -#define StencilBitsManager_hpp +#ifndef StencilStateManager_hpp +#define StencilStateManager_hpp #include "base/ccConfig.h" #include "platform/CCPlatformMacros.h" #include "platform/CCGL.h" @@ -76,4 +76,4 @@ private: NS_CC_END // end of base group /** @} */ -#endif /* StencilBitsManager_hpp */ +#endif /* StencilStateManager_hpp */ diff --git a/cocos/base/CMakeLists.txt b/cocos/base/CMakeLists.txt index 7f18a43b18..8e2881e7cc 100644 --- a/cocos/base/CMakeLists.txt +++ b/cocos/base/CMakeLists.txt @@ -45,7 +45,7 @@ set(COCOS_BASE_SRC base/CCUserDefault.cpp base/CCValue.cpp base/ObjectFactory.cpp - base/CCStencilBitsManager.cpp + base/CCStencilStateManager.cpp base/TGAlib.cpp base/ZipUtils.cpp base/allocator/CCAllocatorDiagnostics.cpp diff --git a/cocos/ui/UILayout.cpp b/cocos/ui/UILayout.cpp index 17c441f887..f5b15bfad2 100644 --- a/cocos/ui/UILayout.cpp +++ b/cocos/ui/UILayout.cpp @@ -37,7 +37,7 @@ THE SOFTWARE. #include "2d/CCLayer.h" #include "2d/CCSprite.h" #include "base/CCEventFocus.h" -#include "base/CCStencilBitsManager.hpp" +#include "base/CCStencilStateManager.hpp" NS_CC_BEGIN @@ -45,8 +45,6 @@ namespace ui { static const int BACKGROUNDIMAGE_Z = (-1); static const int BCAKGROUNDCOLORRENDERER_Z = (-2); - -static GLint g_sStencilBits = -1; IMPLEMENT_CLASS_GUI_INFO(Layout) From 03046d6fbd9b9616d515e831bbd7a919b697c5a1 Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Wed, 25 Nov 2015 14:31:32 +0800 Subject: [PATCH 6/7] change the default alphaThreshold --- cocos/2d/CCClippingNode.cpp | 4 ---- cocos/base/CCStencilStateManager.cpp | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/cocos/2d/CCClippingNode.cpp b/cocos/2d/CCClippingNode.cpp index 1e6ccdcf01..ea80510b7b 100644 --- a/cocos/2d/CCClippingNode.cpp +++ b/cocos/2d/CCClippingNode.cpp @@ -109,10 +109,6 @@ bool ClippingNode::init(Node *stencil) CC_SAFE_RELEASE(_stencil); _stencil = stencil; CC_SAFE_RETAIN(_stencil); - - _stencilStateManager->setAlphaThreshold(1.0f); - _stencilStateManager->setInverted(false); - return true; } diff --git a/cocos/base/CCStencilStateManager.cpp b/cocos/base/CCStencilStateManager.cpp index 3467b12c97..0525054780 100644 --- a/cocos/base/CCStencilStateManager.cpp +++ b/cocos/base/CCStencilStateManager.cpp @@ -41,7 +41,7 @@ GLint StencilStateManager::s_layer = -1; static GLint g_sStencilBits = -1; StencilStateManager::StencilStateManager() -: _alphaThreshold(0.0f) +: _alphaThreshold(1.0f) , _inverted(false) , _currentStencilEnabled(GL_FALSE) , _currentStencilWriteMask(~0) From 584a5d7407f1dc74571f739d18a0dc71bb30d4a5 Mon Sep 17 00:00:00 2001 From: zilongshanren Date: Wed, 25 Nov 2015 18:27:38 +0800 Subject: [PATCH 7/7] fix alphaThreshold undefined issue --- cocos/2d/CCClippingNode.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cocos/2d/CCClippingNode.cpp b/cocos/2d/CCClippingNode.cpp index ea80510b7b..8557203765 100644 --- a/cocos/2d/CCClippingNode.cpp +++ b/cocos/2d/CCClippingNode.cpp @@ -215,7 +215,8 @@ void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32 _beforeVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencilStateManager); renderer->addCommand(&_beforeVisitCmd); - if (_stencilStateManager->getAlphaThreshold() < 1) + auto alphaThreshold = this->getAlphaThreshold(); + if (alphaThreshold < 1) { #if CC_CLIPPING_NODE_OPENGLES // since glAlphaTest do not exists in OES, use a shader that writes @@ -224,7 +225,7 @@ void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32 GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); // set our alphaThreshold program->use(); - program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold); + program->setUniformLocationWith1f(alphaValueLocation, alphaThreshold); // we need to recursively apply this shader to all the nodes in the stencil node // FIXME: we should have a way to apply shader to all nodes without having to do this setProgram(_stencil, program);