CCClippingNode(Clip修剪 可以实现新手引导遮罩、滚动字幕。。渲染child时仅渲染模板透明度值大于透明度阀值的像素点.默认透明度阀值 =1)

本文主要是介绍CCClippingNode(Clip修剪 可以实现新手引导遮罩、滚动字幕。。渲染child时仅渲染模板透明度值大于透明度阀值的像素点.默认透明度阀值 =1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

http://blog.csdn.net/univcore/article/details/42149725

         Cocos2d-x开发--使用CCRenderTexture将矩形图片裁剪成圆形显示         

  CCNode* m_pStencil;//模板   简单的模板可以用CCDrawNode 、 CCLayerColor来做 。 复杂的可以通过ccsprite 使用图片做


cocos2d-x利用CCClippingNode实现滚动字幕 - 白白手游专栏(...

要实现文字在一定区域里滚动,首先用CCClippingNode做出一个剪裁区域,在这个区域内文字可以显示,出了这个区域之后文字就看不到。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bool TestLayer::init()
{
     CCSize size = CCDirector::sharedDirector()->getVisibleSize();
       
     //创建要显示的文字
     text = CCLabelTTF::create( "text\nbaibai\n白白\nbaibai\nhaha\nhaha\nahha\n" , "" , 30 );
     text->setPosition(ccp( 100 , - 120 ));
     
     //绘制裁剪区域
     CCDrawNode* shap = CCDrawNode::create();
     CCPoint point[ 4 ] = {ccp( 0 , 0 ), ccp( 200 , 0 ), ccp( 200 , 200 ), ccp( 0 , 200 )};
     shap->drawPolygon(point, 4 , ccc4f( 355 , 255 , 255 , 255 ), 2 , ccc4f( 255 , 255 , 255 , 255 ));
     CCClippingNode* cliper = CCClippingNode::create();
     cliper->setStencil(shap);
     cliper->setAnchorPoint(ccp(. 5 , . 5 ));
     cliper->setPosition(ccp( 100 , 20 ));
     addChild(cliper);
     //把要滚动的文字加入到裁剪区域
     cliper->addChild(text);
     
     //文字滚动,超出范围后从新开始
     schedule(schedule_selector(CTestLayer::rollText));
     return true ;
}
void TestLayer::rollText( float )
{
     text->getPositionY()> 300 ? text->setPositionY(- 150 ) : text->setPositionY(text->getPositionY()+ 2 );
}
cocos2d-x CCClippingNode遮罩实现手电筒效果         ( 通过移动模板实现

CCClippingNode遮罩解析 - shangguanyingqi的专栏 - 博客频道 - ...


#ifndef __MISCNODE_CCCLIPPING_NODE_H__

#define __MISCNODE_CCCLIPPING_NODE_H__


#include "base_nodes/CCNode.h"

#include "CCGL.h"  


NS_CC_BEGIN


/** CCClippingNode is a subclass of CCNode.

 It draws its content (childs) clipped using a stencil.  //绘制child时会先通过模板裁剪

 The stencil is an other CCNode that will not be drawn. //模板也是一个ccnode 但不会被渲染

 The clipping is done using the alpha part of the stencil (adjusted(调整) with an alphaThreshold).// 模板只是提供他的alpha 以实现裁剪的效果

 */

class CC_DLL CCClippingNode : public CCNode

{

protected:


// CCClippingNode 在渲染child时 仅渲染模板透明度值 大于 透明度阀值的 像素点 默认透明度阀值 =1 

    CCNode* m_pStencil;//模板   简单的模板可以用CCDrawNode 、 CCLayerColor来做 。 复杂的可以通过ccsprite 使用图片做

    GLfloat m_fAlphaThreshold;  //Alpha 透明度    Threshold 阀值工具

    bool    m_bInverted; //倒转的 反向的

        

private:

    CCClippingNode(); // 私有化构造函数 子类就不能new出此类了 这个类是不准备被派生了  

public:

    static CCClippingNode*create();  //无模板创建

    static CCClippingNode*create(CCNode *pStencil);//通过模板创建

    

    CCNode*getStencil() const;  //set get 模板

    voidsetStencil(CCNode *pStencil);

    

    GLfloatgetAlphaThreshold() const;   //set get AlphaThreshold

    voidsetAlphaThreshold(GLfloat fAlphaThreshold);

    

    /** Inverted. If this is set to YES,

     the stencil is inverted, so the content is drawn where the stencil is NOT drawn.

     This default to NO.

     */

    bool isInverted() const;

    voidsetInverted(bool bInverted);

    virtual ~CCClippingNode();

    virtual bool init();

    virtual boolinit(CCNode *pStencil);   

{

    CC_SAFE_RELEASE(m_pStencil);

    m_pStencil = pStencil;

    CC_SAFE_RETAIN(m_pStencil);

    

    m_fAlphaThreshold = 1;

    m_bInverted = 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;

}

    virtual void onEnter();

    virtual void onEnterTransitionDidFinish();

    virtual void onExitTransitionDidStart();

    virtual void onExit();

    virtual void visit();

};


void CCClippingNode::visit()

{

    // if stencil buffer disabled

    if (g_sStencilBits < 1)

    {

        // draw everything, as if there where no stencil

        CCNode::visit();

        return;

    }

    

    // return fast (draw nothing, or draw everything if in inverted mode) if:

    // - nil stencil node

    // - or stencil node invisible:

    if (!m_pStencil || !m_pStencil->isVisible())

    {

        if (m_bInverted)

        {

            // draw everything

            CCNode::visit();

        }

        return;

    }

    

    // store the current stencil layer (position in the stencil buffer),

    // this will allow nesting up to n CCClippingNode,

    // where n is the number of bits of the stencil buffer.

    static GLint layer = -1;

    

    // all the _stencilBits are in use?

    if (layer + 1 == g_sStencilBits)

    {

        // warn once

        static bool once = true;

        if (once)

        {

            char warning[200] = {0};

            snprintf(warning, sizeof(warning), "Nesting more than %d stencils is not supported. Everything will be drawn without stencil for this node and its childs.", g_sStencilBits);

            CCLOG("%s", warning);

            

            once = false;

        }

        // draw everything, as if there where no stencil

        CCNode::visit();

        return;

    }

    

    ///

    // INIT

    

    // increment the current layer

    layer++;

    

    // mask of the current layer (ie: for layer 3: 00000100)

    GLint mask_layer = 0x1 << 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)

    GLint mask_layer_le = mask_layer | mask_layer_l;

    

    // manually save the stencil state

    GLboolean currentStencilEnabled = GL_FALSE;

    GLuint currentStencilWriteMask = ~0;

    GLenum currentStencilFunc = GL_ALWAYS;

    GLint currentStencilRef = 0;

    GLuint currentStencilValueMask = ~0;

    GLenum currentStencilFail = GL_KEEP;

    GLenum currentStencilPassDepthFail = GL_KEEP;

    GLenum currentStencilPassDepthPass = GL_KEEP;

    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);

    // 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);

    

    // manually save the depth test state

    //GLboolean currentDepthTestEnabled = GL_TRUE;

    GLboolean currentDepthWriteMask = GL_TRUE;

    //currentDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST);

    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);

    

    ///

    // 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(!m_bInverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP);

    

    // draw a fullscreen solid rectangle to clear the stencil buffer

    //ccDrawSolidRect(CCPointZero, ccpFromSize([[CCDirector sharedDirector] winSize]), ccc4f(1, 1, 1, 1));

    ccDrawSolidRect(CCPointZero, ccpFromSize(CCDirector::sharedDirector()->getWinSize()), ccc4f(1, 1, 1, 1));

    

    ///

    // 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);

    glStencilOp(!m_bInverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP);

    

    // 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 (m_fAlphaThreshold < 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 *)&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, m_fAlphaThreshold);

#else

        // since glAlphaTest do not exists in OES, use a shader that writes

        // pixel only if greater than an alpha threshold

        CCGLProgram *program = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColorAlphaTest);

        GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), kCCUniformAlphaTestValue);

        // set our alphaThreshold

        program->setUniformLocationWith1f(alphaValueLocation, m_fAlphaThreshold);

        // 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(m_pStencil, program);

       

#endif

    }

    

    // draw the stencil node as if it was one of our child

    // (according to the stencil test func/op and alpha (or alpha shader) test)

    kmGLPushMatrix();

    transform();

    m_pStencil->visit();

    kmGLPopMatrix();

    

    // restore alpha test state

    if (m_fAlphaThreshold < 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) {

    //    glEnable(GL_DEPTH_TEST);

    //}

    

    ///

    // DRAW CONTENT

    

    // setup the stencil test func like this:

    // for each pixel of this node and its childs

    //     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);

    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    

    // draw (according to the stencil test func) this node and its childs

    CCNode::visit();

    

    ///

    // CLEANUP

    

    // manually restore the stencil state

    glStencilFunc(currentStencilFunc, currentStencilRef, currentStencilValueMask);

    glStencilOp(currentStencilFail, currentStencilPassDepthFail, currentStencilPassDepthPass);

    glStencilMask(currentStencilWriteMask);

    if (!currentStencilEnabled)

    {

        glDisable(GL_STENCIL_TEST);

    }

    

    // we are done using this layer, decrement

    layer--;

}



这篇关于CCClippingNode(Clip修剪 可以实现新手引导遮罩、滚动字幕。。渲染child时仅渲染模板透明度值大于透明度阀值的像素点.默认透明度阀值 =1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/661607

相关文章

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

在Golang中实现定时任务的几种高效方法

《在Golang中实现定时任务的几种高效方法》本文将详细介绍在Golang中实现定时任务的几种高效方法,包括time包中的Ticker和Timer、第三方库cron的使用,以及基于channel和go... 目录背景介绍目的和范围预期读者文档结构概述术语表核心概念与联系故事引入核心概念解释核心概念之间的关系