mirror of https://github.com/axmolengine/axmol.git
Merge pull request #14470 from zilongshanren/fixListViewClippingIssue
Fix list view clipping issue
This commit is contained in:
commit
c3604aa865
|
@ -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 /* 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 */; };
|
||||
|
@ -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 = "<group>"; };
|
||||
2986667818B1B079000E39CA /* CCTweenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTweenFunction.cpp; sourceTree = "<group>"; };
|
||||
2986667918B1B079000E39CA /* CCTweenFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTweenFunction.h; sourceTree = "<group>"; };
|
||||
298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCStencilStateManager.cpp; path = ../base/CCStencilStateManager.cpp; sourceTree = "<group>"; };
|
||||
298C75D41C0465D0006BAE63 /* CCStencilStateManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CCStencilStateManager.hpp; path = ../base/CCStencilStateManager.hpp; sourceTree = "<group>"; };
|
||||
299754F2193EC95400A54AC3 /* ObjectFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectFactory.cpp; path = ../base/ObjectFactory.cpp; sourceTree = "<group>"; };
|
||||
299754F3193EC95400A54AC3 /* ObjectFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectFactory.h; path = ../base/ObjectFactory.h; sourceTree = "<group>"; };
|
||||
299CF1F919A434BC00C378C1 /* ccRandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ccRandom.cpp; path = ../base/ccRandom.cpp; sourceTree = "<group>"; };
|
||||
|
@ -6037,6 +6044,8 @@
|
|||
50ABBE1C1925AB6F00A911A9 /* utlist.h */,
|
||||
50ABBE1D1925AB6F00A911A9 /* ZipUtils.cpp */,
|
||||
50ABBE1E1925AB6F00A911A9 /* ZipUtils.h */,
|
||||
298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */,
|
||||
298C75D41C0465D0006BAE63 /* CCStencilStateManager.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 /* CCStencilStateManager.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 /* CCStencilStateManager.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 /* CCStencilStateManager.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 /* CCStencilStateManager.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 /* CCStencilStateManager.cpp in Sources */,
|
||||
15AE194B19AAD35100C27E9E /* CCComRender.cpp in Sources */,
|
||||
382384451A25915C002C4610 /* SpriteReader.cpp in Sources */,
|
||||
B6CAB2321AF9AA1A00B9B856 /* btCollisionWorld.cpp in Sources */,
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "base/CCDirector.h"
|
||||
#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
|
||||
|
@ -41,12 +42,6 @@
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -61,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()
|
||||
|
@ -128,21 +109,6 @@ bool ClippingNode::init(Node *stencil)
|
|||
CC_SAFE_RELEASE(_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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -222,45 +188,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)
|
||||
{
|
||||
|
@ -285,9 +212,11 @@ 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)
|
||||
|
||||
auto alphaThreshold = this->getAlphaThreshold();
|
||||
if (alphaThreshold < 1)
|
||||
{
|
||||
#if CC_CLIPPING_NODE_OPENGLES
|
||||
// since glAlphaTest do not exists in OES, use a shader that writes
|
||||
|
@ -296,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);
|
||||
|
@ -307,7 +236,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;
|
||||
|
@ -339,7 +268,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();
|
||||
|
@ -374,196 +303,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
|
||||
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
|
||||
s_layer--;
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
@ -433,6 +433,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClCompile Include="..\base\ccFPSImages.c" />
|
||||
<ClCompile Include="..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="..\base\CCStencilStateManager.cpp" />
|
||||
<ClCompile Include="..\base\CCNS.cpp" />
|
||||
<ClCompile Include="..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="..\base\CCProperties.cpp" />
|
||||
|
@ -1015,6 +1016,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClInclude Include="..\base\ccMacros.h" />
|
||||
<ClInclude Include="..\base\CCMap.h" />
|
||||
<ClInclude Include="..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="..\base\CCStencilStateManager.h" />
|
||||
<ClInclude Include="..\base\CCNS.h" />
|
||||
<ClInclude Include="..\base\CCProfiling.h" />
|
||||
<ClInclude Include="..\base\CCProperties.h" />
|
||||
|
@ -1384,4 +1386,4 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="physics">
|
||||
|
@ -1896,6 +1896,9 @@
|
|||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\CCStencilStateManager.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="..\renderer\CCFrameBuffer.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
|
@ -3728,6 +3731,9 @@
|
|||
<ClInclude Include="..\base\CCNinePatchImageParser.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\CCStencilStateManager.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="..\renderer\CCFrameBuffer.h">
|
||||
<Filter>renderer</Filter>
|
||||
|
@ -3810,4 +3816,4 @@
|
|||
<Filter>3d</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
|
@ -286,6 +286,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccMacros.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCMap.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCStencilStateManager.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h" />
|
||||
|
@ -917,6 +918,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCStencilStateManager.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp" />
|
||||
|
@ -1286,4 +1288,4 @@
|
|||
<ItemGroup>
|
||||
<Text Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)targetver.h" />
|
||||
|
@ -1812,6 +1812,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCStencilStateManager.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DConstraint.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
|
@ -3525,6 +3528,9 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCStencilStateManager.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DDebugDrawer.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
|
@ -3979,4 +3985,4 @@
|
|||
<ItemGroup>
|
||||
<Text Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
|
@ -415,6 +415,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="..\..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="..\..\base\CCStencilStateManager.cpp" />
|
||||
<ClCompile Include="..\..\base\CCNS.cpp" />
|
||||
<ClCompile Include="..\..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="..\..\base\CCProperties.cpp" />
|
||||
|
@ -1013,6 +1014,7 @@
|
|||
<ClInclude Include="..\..\base\ccMacros.h" />
|
||||
<ClInclude Include="..\..\base\CCMap.h" />
|
||||
<ClInclude Include="..\..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="..\..\base\CCStencilStateManager.h" />
|
||||
<ClInclude Include="..\..\base\CCNS.h" />
|
||||
<ClInclude Include="..\..\base\CCProfiling.h" />
|
||||
<ClInclude Include="..\..\base\CCProperties.h" />
|
||||
|
@ -1673,4 +1675,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resource Files">
|
||||
|
@ -1767,6 +1767,9 @@
|
|||
<ClCompile Include="..\..\base\CCNinePatchImageParser.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\base\CCStencilStateManager.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\renderer\CCMaterial.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
|
@ -3635,6 +3638,9 @@
|
|||
<ClInclude Include="..\..\base\CCNinePatchImageParser.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\base\CCStencilStateManager.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\renderer\CCMaterial.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
|
@ -4017,4 +4023,4 @@
|
|||
<Filter>3d</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -107,6 +107,7 @@ math/Vec2.cpp \
|
|||
math/Vec3.cpp \
|
||||
math/Vec4.cpp \
|
||||
base/CCNinePatchImageParser.cpp \
|
||||
base/CCStencilStateManager.cpp \
|
||||
base/CCAsyncTaskPool.cpp \
|
||||
base/CCAutoreleasePool.cpp \
|
||||
base/CCConfiguration.cpp \
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
/****************************************************************************
|
||||
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 "CCStencilStateManager.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
|
||||
|
||||
GLint StencilStateManager::s_layer = -1;
|
||||
static GLint g_sStencilBits = -1;
|
||||
|
||||
StencilStateManager::StencilStateManager()
|
||||
: _alphaThreshold(1.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)
|
||||
|
||||
{
|
||||
// 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 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
|
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
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 StencilStateManager_hpp
|
||||
#define StencilStateManager_hpp
|
||||
#include "base/ccConfig.h"
|
||||
#include "platform/CCPlatformMacros.h"
|
||||
#include "platform/CCGL.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
NS_CC_BEGIN
|
||||
|
||||
class CC_DLL StencilStateManager
|
||||
{
|
||||
public:
|
||||
StencilStateManager();
|
||||
void onBeforeVisit();
|
||||
void onAfterDrawStencil();
|
||||
void onAfterVisit();
|
||||
void setAlphaThreshold(GLfloat alphaThreshold);
|
||||
void setInverted(bool inverted);
|
||||
bool isInverted()const;
|
||||
GLfloat getAlphaThreshold()const;
|
||||
private:
|
||||
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
|
||||
// end of base group
|
||||
/** @} */
|
||||
#endif /* StencilStateManager_hpp */
|
|
@ -45,6 +45,7 @@ set(COCOS_BASE_SRC
|
|||
base/CCUserDefault.cpp
|
||||
base/CCValue.cpp
|
||||
base/ObjectFactory.cpp
|
||||
base/CCStencilStateManager.cpp
|
||||
base/TGAlib.cpp
|
||||
base/ZipUtils.cpp
|
||||
base/allocator/CCAllocatorDiagnostics.cpp
|
||||
|
|
|
@ -37,6 +37,7 @@ THE SOFTWARE.
|
|||
#include "2d/CCLayer.h"
|
||||
#include "2d/CCSprite.h"
|
||||
#include "base/CCEventFocus.h"
|
||||
#include "base/CCStencilStateManager.hpp"
|
||||
#include "2d/CocosStudioExtension.h"
|
||||
|
||||
|
||||
|
@ -46,9 +47,6 @@ namespace ui {
|
|||
|
||||
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)
|
||||
|
||||
|
@ -76,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),
|
||||
|
@ -266,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
|
||||
|
@ -320,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();
|
||||
|
@ -328,136 +315,6 @@ void Layout::stencilClippingVisit(Renderer *renderer, const Mat4& parentTransfor
|
|||
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||
}
|
||||
|
||||
void Layout::onBeforeVisitStencil()
|
||||
{
|
||||
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);
|
||||
}
|
||||
s_layer--;
|
||||
}
|
||||
|
||||
void Layout::onBeforeVisitScissor()
|
||||
{
|
||||
auto glview = Director::getInstance()->getOpenGLView();
|
||||
|
@ -530,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)
|
||||
{
|
||||
|
|
|
@ -39,9 +39,9 @@ NS_CC_BEGIN
|
|||
class DrawNode;
|
||||
class LayerColor;
|
||||
class LayerGradient;
|
||||
class StencilStateManager;
|
||||
struct CC_DLL ResouceData;
|
||||
|
||||
|
||||
namespace ui {
|
||||
|
||||
class LayoutManager;
|
||||
|
@ -489,12 +489,6 @@ protected:
|
|||
virtual const Vector<Node*>& getLayoutElements()const override;
|
||||
|
||||
//clipping
|
||||
void onBeforeVisitStencil();
|
||||
void onAfterDrawStencil();
|
||||
void onAfterVisitStencil();
|
||||
/**draw fullscreen quad to clear stencil bits
|
||||
*/
|
||||
void drawFullScreenQuadClearStencil();
|
||||
|
||||
void onBeforeVisitScissor();
|
||||
void onAfterVisitScissor();
|
||||
|
@ -638,23 +632,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;
|
||||
|
|
|
@ -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<Widget*>& items = listView->getItems();
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 636129882b612b5fe6d1d21be1eec136a2b1340b
|
||||
Subproject commit e82bd71212e53e016bf5f262f8e4bc1c50b54203
|
|
@ -1 +1 @@
|
|||
Subproject commit a0fe326ea3d685d342ba2a61c0be6f9dee83f800
|
||||
Subproject commit 2318a1593d2d490a3860179acaf81a1bf867a36b
|
Loading…
Reference in New Issue