您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x3.1中ClippingNode的使用实例

2014-08-12 22:30 543 查看

1、ClippingNode说明

ClippingNode是利用模板遮罩来完成对Node区域裁剪的技术,如何理解ClippingNode的遮罩?看下图的例子吧。



所谓模板,就是一个形状,透过该形状可看到底板上的图层,如果底板上没有任何内容,则直接看到Layer上的内容,而底板上

的东西又不会妨碍Layer上的东西,即模板在底板之外的空间对于Layer来说是透明的。假如有个精灵在模板之外的底板上运动,我们

是看不到它的。除非它进入模板的区域,我们才能看到它。

2、ClippingNode源码

#include "2d/CCNode.h"//用到节点头文件和OPENGL深度缓冲定义头文件
#include "CCGL.h"
#include "renderer/CCGroupCommand.h"//用到GroupCommand和CustomCommand渲染
#include "renderer/CCCustomCommand.h"

NS_CC_BEGIN

/** ClippingNode is a subclass of Node.
It draws its content (childs) clipped using a stencil.
The stencil is an other Node that will not be drawn.
The clipping is done using the alpha part of the stencil (adjusted with an alphaThreshold).
*/
class CC_DLL ClippingNode : public Node
{
public:
/** Creates and initializes a clipping node without a stencil.
*/
static ClippingNode* create();//静态创建对象

/** Creates and initializes a clipping node with an other node as its stencil.
The stencil node will be retained.
*/
static ClippingNode* create(Node *stencil);//用模板创建裁剪节点

/** The Node to use as a stencil to do the clipping.
The stencil node will be retained.
This default to nil.
*/
Node* getStencil() const;//获取节点模板
void setStencil(Node *stencil);//设置节点模板

/** The alpha threshold.
The content is drawn only where the stencil have pixel with alpha greater than the alphaThreshold.
Should be a float between 0 and 1.
This default to 1 (so alpha test is disabled).
*///ALPHA测试参考值,用于进行ALPHA测试比较,一般比较算法为小于此值的像素会直接被舍弃,这样就实现了图像的镂空
GLfloat getAlphaThreshold() const;//获取ALPHT的测试参考值
void setAlphaThreshold(GLfloat alphaThreshold);//设置ALPHA的测试参考值

/** Inverted. If this is set to true,
the stencil is inverted, so the content is drawn where the stencil is NOT drawn.
This default to false.
*/
bool isInverted() const;//获取遮罩运算是否取反设置
void setInverted(bool inverted);//设置遮罩运算取反

// Overrides//继承的函数
/**
* @js NA
* @lua NA
*/
virtual void onEnter() override;
/**
* @js NA
* @lua NA
*/
virtual void onEnterTransitionDidFinish() override;
/**
* @js NA
* @lua NA
*/
virtual void onExitTransitionDidStart() override;
/**
* @js NA
* @lua NA
*/
virtual void onExit() override;
virtual void visit(Renderer *renderer, const Mat4 &parentTransform, bool parentTransformUpdated) override;

CC_CONSTRUCTOR_ACCESS:
ClippingNode();

/**
* @js NA
* @lua NA
*/
virtual ~ClippingNode();

/** Initializes a clipping node without a stencil.
*/
virtual bool init();

/** Initializes a clipping node with an other node as its stencil.
The stencil node will be retained, and its parent will be set to this clipping node.
*/
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;

GroupCommand _groupCommand;
CustomCommand _beforeVisitCmd;
CustomCommand _afterDrawStencilCmd;
CustomCommand _afterVisitCmd;

private:
CC_DISALLOW_COPY_AND_ASSIGN(ClippingNode);
};

NS_CC_END


3、使用实例

<pre name="code" class="cpp">class NewClippingNode : public Layer
{
public:
CREATE_FUNC(NewClippingNode);
virtual bool init();
};


bool NewClippingNode::init()
{

    auto s =Director::getInstance()->getWinSize();
   bool bRet =
false;
   do{
       CC_BREAK_IF(!Layer::init());

        
       auto clipper =
ClippingNode::create();
        clipper->setTag(kTagClipperNode);
        clipper->setContentSize(Size(200,200));//设置剪裁区域大小

        clipper->ignoreAnchorPointForPosition(false);
        clipper->setAnchorPoint(Vec2(0.5,0.5));//设置锚点
        clipper->setPosition(Vec2(s.width/2,
s.height/2));
       this->addChild(clipper);

        
        clipper->setAlphaThreshold(0.05f);//设置透明度的阈值ALPHA值

        //设置剪裁模板
       auto stencil =
Sprite::create("grossini.png");
        stencil->setScale(2);
        stencil->setPosition(Vec2(s.width/2,
s.height/2));
        clipper->setStencil(stencil);//设置剪裁模板

    //TODO Fix draw node as clip node

//    auto stencil = NewDrawNode::create();

//    Vec2 rectangle[4];

//    rectangle[0] = Vec2(0, 0);

//    rectangle[1] = Vec2(clipper->getContentSize().width, 0);

//    rectangle[2] = Vec2(clipper->getContentSize().width, clipper->getContentSize().height);

//    rectangle[3] = Vec2(0, clipper->getContentSize().height);

//

//    Color4F white(1, 1, 1, 1);

//    stencil->drawPolygon(rectangle, 4, white, 1, white);

//    clipper->setStencil(stencil);

        //设置剪裁节点内容
       auto content =
Sprite::create("background2.png");
        content->setTag(kTagContentNode);

        content->ignoreAnchorPointForPosition(false);
        content->setAnchorPoint(Vec2(0.5,0.5));
        content->setPosition(Vec2(s.width/2,200));
        clipper->addChild(content);

        
        bRet =true;
    }while(0);
   return bRet;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息