mirror of https://github.com/axmolengine/axmol.git
Fix Clipping Node
This commit is contained in:
parent
e5ebcb2845
commit
c288e5ef9c
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "CCNewDrawNode.h"
|
#include "CCNewDrawNode.h"
|
||||||
|
#include "QuadCommand.h"
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
|
||||||
|
@ -39,7 +40,9 @@ bool NewDrawNode::init()
|
||||||
|
|
||||||
void NewDrawNode::draw()
|
void NewDrawNode::draw()
|
||||||
{
|
{
|
||||||
|
updateTransform();
|
||||||
|
|
||||||
|
// QuadCommand* quadCommand = new QuadCommand(0, _vertexZ, 0, _shaderProgram, _blendFunc, )
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
|
@ -114,7 +114,7 @@ void NewSprite::draw(void)
|
||||||
{
|
{
|
||||||
updateTransform();
|
updateTransform();
|
||||||
//TODO implement z order
|
//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);
|
Renderer::getInstance()->addCommand(renderCommand);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,11 @@ NewClippingNode::NewClippingNode()
|
||||||
currentStencilFail = GL_KEEP;
|
currentStencilFail = GL_KEEP;
|
||||||
currentStencilPassDepthFail = GL_KEEP;
|
currentStencilPassDepthFail = GL_KEEP;
|
||||||
currentStencilPassDepthPass = GL_KEEP;
|
currentStencilPassDepthPass = GL_KEEP;
|
||||||
GLboolean currentDepthWriteMask = GL_TRUE;
|
currentDepthWriteMask = GL_TRUE;
|
||||||
|
|
||||||
|
currentAlphaTestEnabled = GL_FALSE;
|
||||||
|
currentAlphaTestFunc = GL_ALWAYS;
|
||||||
|
currentAlphaTestRef = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewClippingNode::visit()
|
void NewClippingNode::visit()
|
||||||
|
@ -104,11 +108,6 @@ void NewClippingNode::visit()
|
||||||
|
|
||||||
void NewClippingNode::beforeVisit()
|
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
|
// INIT
|
||||||
|
|
||||||
|
@ -182,22 +181,60 @@ void NewClippingNode::beforeVisit()
|
||||||
glStencilFunc(GL_NEVER, mask_layer, mask_layer);
|
glStencilFunc(GL_NEVER, mask_layer, mask_layer);
|
||||||
glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP);
|
glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP);
|
||||||
|
|
||||||
// since glAlphaTest do not exists in OES, use a shader that writes
|
// enable alpha test only if the alpha threshold < 1,
|
||||||
// pixel only if greater than an alpha threshold
|
// indeed if alpha threshold == 1, every pixel will be drawn anyways
|
||||||
GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST);
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||||
GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
|
// GLboolean currentAlphaTestEnabled = GL_FALSE;
|
||||||
// set our alphaThreshold
|
// GLenum currentAlphaTestFunc = GL_ALWAYS;
|
||||||
program->use();
|
// GLclampf currentAlphaTestRef = 1;
|
||||||
program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold);
|
#endif
|
||||||
// we need to recursively apply this shader to all the nodes in the stencil node
|
if (_alphaThreshold < 1) {
|
||||||
// XXX: we should have a way to apply shader to all nodes without having to do this
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||||
setProgram(_stencil, program);
|
// 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
|
//Draw _stencil
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewClippingNode::afterDrawStencil()
|
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
|
// restore the depth test state
|
||||||
glDepthMask(currentDepthWriteMask);
|
glDepthMask(currentDepthWriteMask);
|
||||||
//if (currentDepthTestEnabled) {
|
//if (currentDepthTestEnabled) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
|
|
||||||
virtual ~NewClippingNode();
|
virtual ~NewClippingNode();
|
||||||
|
|
||||||
void visit();
|
virtual void visit() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NewClippingNode();
|
NewClippingNode();
|
||||||
|
@ -41,6 +41,10 @@ protected:
|
||||||
GLenum currentStencilPassDepthPass;
|
GLenum currentStencilPassDepthPass;
|
||||||
GLboolean currentDepthWriteMask;
|
GLboolean currentDepthWriteMask;
|
||||||
|
|
||||||
|
GLboolean currentAlphaTestEnabled;
|
||||||
|
GLenum currentAlphaTestFunc;
|
||||||
|
GLclampf currentAlphaTestRef;
|
||||||
|
|
||||||
GLint mask_layer_le;
|
GLint mask_layer_le;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ void Renderer::render()
|
||||||
{
|
{
|
||||||
memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());
|
memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());
|
||||||
_numQuads += cmd->getQuadCount();
|
_numQuads += cmd->getQuadCount();
|
||||||
_renderStack.top().currentIndex = _lastCommand = i;
|
_lastCommand = i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -202,11 +202,15 @@ void Renderer::render()
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_renderStack.top().currentIndex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw the batched quads
|
//Draw the batched quads
|
||||||
drawBatchedQuads();
|
drawBatchedQuads();
|
||||||
|
|
||||||
|
currRenderQueue = _renderGroups[_renderStack.top().renderQueueID];
|
||||||
|
len = currRenderQueue.size();
|
||||||
//If pop the render stack if we already processed all the commands
|
//If pop the render stack if we already processed all the commands
|
||||||
if(_renderStack.top().currentIndex + 1 >= len)
|
if(_renderStack.top().currentIndex + 1 >= len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -271,20 +271,21 @@ NewClippingNodeTest::NewClippingNodeTest()
|
||||||
clipper->runAction(RepeatForever::create(RotateBy::create(1, 45)));
|
clipper->runAction(RepeatForever::create(RotateBy::create(1, 45)));
|
||||||
this->addChild(clipper);
|
this->addChild(clipper);
|
||||||
|
|
||||||
auto stencil = NewDrawNode::create();
|
// auto stencil = NewDrawNode::create();
|
||||||
Point rectangle[4];
|
// Point rectangle[4];
|
||||||
rectangle[0] = Point(0, 0);
|
// rectangle[0] = Point(0, 0);
|
||||||
rectangle[1] = Point(clipper->getContentSize().width, 0);
|
// rectangle[1] = Point(clipper->getContentSize().width, 0);
|
||||||
rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height);
|
// rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height);
|
||||||
rectangle[3] = Point(0, clipper->getContentSize().height);
|
// rectangle[3] = Point(0, clipper->getContentSize().height);
|
||||||
|
//
|
||||||
Color4F white(1, 1, 1, 1);
|
// Color4F white(1, 1, 1, 1);
|
||||||
stencil->drawPolygon(rectangle, 4, white, 1, white);
|
// stencil->drawPolygon(rectangle, 4, white, 1, white);
|
||||||
clipper->setStencil(stencil);
|
|
||||||
|
|
||||||
// auto stencil = NewSprite::create("Images/background2.png");
|
|
||||||
// clipper->setStencil(stencil);
|
// 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");
|
auto content = NewSprite::create("Images/background2.png");
|
||||||
content->setTag( kTagContentNode );
|
content->setTag( kTagContentNode );
|
||||||
content->setAnchorPoint( Point(0.5, 0.5) );
|
content->setAnchorPoint( Point(0.5, 0.5) );
|
||||||
|
|
Loading…
Reference in New Issue