diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index 8066b135fd..164bb5b4b0 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -4,6 +4,7 @@ #include "CCNewDrawNode.h" +#include "QuadCommand.h" NS_CC_BEGIN @@ -39,7 +40,9 @@ bool NewDrawNode::init() void NewDrawNode::draw() { + updateTransform(); +// QuadCommand* quadCommand = new QuadCommand(0, _vertexZ, 0, _shaderProgram, _blendFunc, ) } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index fa248a283b..95a670a856 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -114,7 +114,7 @@ void NewSprite::draw(void) { updateTransform(); //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(0, _vertexZ,_texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/NewClippingNode.cpp b/cocos/2d/NewClippingNode.cpp index ee3271afc6..8e0a8151ca 100644 --- a/cocos/2d/NewClippingNode.cpp +++ b/cocos/2d/NewClippingNode.cpp @@ -72,7 +72,11 @@ NewClippingNode::NewClippingNode() currentStencilFail = GL_KEEP; currentStencilPassDepthFail = GL_KEEP; currentStencilPassDepthPass = GL_KEEP; - GLboolean currentDepthWriteMask = GL_TRUE; + currentDepthWriteMask = GL_TRUE; + + currentAlphaTestEnabled = GL_FALSE; + currentAlphaTestFunc = GL_ALWAYS; + currentAlphaTestRef = 1; } void NewClippingNode::visit() @@ -104,11 +108,6 @@ void NewClippingNode::visit() void NewClippingNode::beforeVisit() { - // 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 layer = -1; - /////////////////////////////////// // INIT @@ -182,22 +181,60 @@ void NewClippingNode::beforeVisit() glStencilFunc(GL_NEVER, mask_layer, mask_layer); glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP); - // since glAlphaTest do not exists in OES, use a shader that writes - // pixel only if greater than an alpha threshold - GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST); - GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); - // set our alphaThreshold - program->use(); - program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold); - // we need to recursively apply this shader to all the nodes in the stencil node - // XXX: we should have a way to apply shader to all nodes without having to do this - setProgram(_stencil, program); + // enable alpha test only if the alpha threshold < 1, + // indeed if alpha threshold == 1, every pixel will be drawn anyways +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) +// GLboolean currentAlphaTestEnabled = GL_FALSE; +// GLenum currentAlphaTestFunc = GL_ALWAYS; +// GLclampf currentAlphaTestRef = 1; +#endif + if (_alphaThreshold < 1) { +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) + // manually save the alpha test state + currentAlphaTestEnabled = glIsEnabled(GL_ALPHA_TEST); + glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint *)¤tAlphaTestFunc); + glGetFloatv(GL_ALPHA_TEST_REF, ¤tAlphaTestRef); + // 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); +#else + // since glAlphaTest do not exists in OES, use a shader that writes + // pixel only if greater than an alpha threshold + GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST); + GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); + // set our alphaThreshold + program->use(); + program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold); + // we need to recursively apply this shader to all the nodes in the stencil node + // XXX: we should have a way to apply shader to all nodes without having to do this + setProgram(_stencil, program); + +#endif + } //Draw _stencil } void NewClippingNode::afterDrawStencil() { + // restore alpha test state + if (_alphaThreshold < 1) + { +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) + // manually restore the alpha test state + glAlphaFunc(currentAlphaTestFunc, currentAlphaTestRef); + if (!currentAlphaTestEnabled) + { + glDisable(GL_ALPHA_TEST); + } +#else +// XXX: we need to find a way to restore the shaders of the stencil node and its childs +#endif + } + // restore the depth test state glDepthMask(currentDepthWriteMask); //if (currentDepthTestEnabled) { diff --git a/cocos/2d/NewClippingNode.h b/cocos/2d/NewClippingNode.h index 3ce20609ec..b064f5b5c5 100644 --- a/cocos/2d/NewClippingNode.h +++ b/cocos/2d/NewClippingNode.h @@ -21,7 +21,7 @@ public: virtual ~NewClippingNode(); - void visit(); + virtual void visit() override; protected: NewClippingNode(); @@ -41,6 +41,10 @@ protected: GLenum currentStencilPassDepthPass; GLboolean currentDepthWriteMask; + GLboolean currentAlphaTestEnabled; + GLenum currentAlphaTestFunc; + GLclampf currentAlphaTestRef; + GLint mask_layer_le; }; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 2b36284f79..85a231d5c4 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -171,7 +171,7 @@ void Renderer::render() { memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); _numQuads += cmd->getQuadCount(); - _renderStack.top().currentIndex = _lastCommand = i; + _lastCommand = i; } else { @@ -202,11 +202,15 @@ void Renderer::render() { flush(); } + + _renderStack.top().currentIndex = i; } //Draw the batched quads drawBatchedQuads(); + currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; + len = currRenderQueue.size(); //If pop the render stack if we already processed all the commands if(_renderStack.top().currentIndex + 1 >= len) { diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 9c8900e296..33b503c56e 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -271,20 +271,21 @@ NewClippingNodeTest::NewClippingNodeTest() clipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); this->addChild(clipper); - auto stencil = NewDrawNode::create(); - Point rectangle[4]; - rectangle[0] = Point(0, 0); - rectangle[1] = Point(clipper->getContentSize().width, 0); - rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height); - rectangle[3] = Point(0, clipper->getContentSize().height); - - Color4F white(1, 1, 1, 1); - stencil->drawPolygon(rectangle, 4, white, 1, white); - clipper->setStencil(stencil); - -// auto stencil = NewSprite::create("Images/background2.png"); +// auto stencil = NewDrawNode::create(); +// Point rectangle[4]; +// rectangle[0] = Point(0, 0); +// rectangle[1] = Point(clipper->getContentSize().width, 0); +// rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height); +// rectangle[3] = Point(0, clipper->getContentSize().height); +// +// Color4F white(1, 1, 1, 1); +// stencil->drawPolygon(rectangle, 4, white, 1, white); // clipper->setStencil(stencil); + auto stencil = NewSprite::create("Images/grossini.png"); + stencil->setPosition(s.width/2, s.height/2); + clipper->setStencil(stencil); + auto content = NewSprite::create("Images/background2.png"); content->setTag( kTagContentNode ); content->setAnchorPoint( Point(0.5, 0.5) );