2013年(92)
分类: 信息化
2013-04-29 02:39:21
? ? ? ? ?我们好,好久没有再上课,我们是不是还牵挂红孩儿的博文呢?哈哈,对不住了,红孩儿迩来一直在忙着写新版的“红孩儿工具箱”,发展还算较快,新用工具箱做了一些动画特效,有喜好的同学可以点击查看: ? ? ? ?《大掌门》九阴白骨爪文字特效动画 ? ? ? ?色彩圈与咬人花 ? ? ? ? ?<3>将《名将》的刀手侵犯GIF导入工具箱转为关健帧动画 ? ? ? ? ? ? ? ?广告回来,话回正题。本节我们来学习一下2.1版另外新功用:ClippingNode。啥是“ClippingNode”?在我看来,“ClippingNode”可以定义为运用模版遮罩来完结对Node进行区域剪切的技术。我们来打个比方,在严寒的冬季,我们家里的窗户玻璃上常常凝集一层雾以致于我们无法看到玻璃外的现象,这时候我们常常会抹掉这层雾,当然,许多小朋友也会像红孩儿一样兴致勃勃的在抹这层雾时顺手写几笔“数风流人物,还看今朝!”,当雾被抹掉后,玻璃外的风景也就显露出来了。那么,如果我们把窗户玻璃作为闪现现象的层,则玻璃上的这层雾就可称为模版遮罩了,实际上,本节的技术无非就是怎样在这个模版遮罩上写出那几笔风流大字。 ? ? ? ? ? ? ? ? ? ? ? ? ?在Cocos2d-x中,关于Node进行模版遮罩功用的类被封装在一个称为“CCClippingNode”的类中。它是被放在libcocos2d中的misc_nodes中的。 ? ? ? ? 翻开CCClippingNode.h,看下源码: #ifndef __MISCNODE_CCCLIPPING_NODE_H__ #define __MISCNODE_CCCLIPPING_NODE_H__ //用到结点头文件与OPENGL深度缓冲定义头文件 #include "base_nodes/CCNode.h" #include "CCGL.h" //运用Cocos2d命名空间 NS_CC_BEGIN // CCClippingNode类,我们可以认为它就是那个窗户玻璃。 class CC_DLL CCClippingNode : public CCNode { protected: //所用的模版缓冲遮罩结点,也就是那层玻璃上的雾像。 CCNode* m_pStencil; //ALPHA的检验参考值,用于进行ALPHA检验比较所用,一般比较算法为小于此值的像素直接会被抛弃。这样就可以完结图像的镂空。 GLfloat m_fAlphaThreshold; //这个值其实是指的遮罩运算能否按取反设置。 bool m_bInverted; public: //静态创建函数,创建相应的结点。 static CCClippingNode* create(); //静态创建函数,参数指定所用的模版缓冲遮罩结点。 static CCClippingNode* create(CCNode *pStencil); //析构 virtual ~CCClippingNode(); //基础初始化函数。 virtual bool init(); //扩展初始化函数,参数指定所用的模版缓冲遮罩结点。 virtual bool init(CCNode *pStencil); //重载基类CCNode的相应函数。 virtual void onEnter(); virtual void onEnterTransitionDidFinish(); virtual void onExitTransitionDidStart(); virtual void onExit(); virtual void visit(); //取得模版缓冲遮罩结点。 CCNode* getStencil() const; //设置模版缓冲遮罩结点。 void setStencil(CCNode *pStencil); //取得ALPHA的检验参考值。 GLfloat getAlphaThreshold() const; //设置ALPHA的检验参考值。 void setAlphaThreshold(GLfloat fAlphaThreshold); //取得遮罩运算能否按取反设置。 bool isInverted() const; //设置遮罩运算能否按取反设置。 void setInverted(bool bInverted); private: //规划 CCClippingNode(); }; NS_CC_END #endif // __MISCNODE_CCCLIPPING_NODE_H__ ? ? ? ? 嗯,不错,这个类除了设置模版缓冲遮罩效果,还可以做ALPHA镂空和遮罩的取反运算。可以做出许多很棒的作用了。 继续看CPP: //包含头文件 #include "CCClippingNode.h" //运用数学库中的矩阵相关头文件,矩阵压栈要用。 #include "kazmath/GL/matrix.h" //运用Shader的相关头文件,ALPHA镂空要用。 #include "shaders/CCGLProgram.h" #include "shaders/CCShaderCache.h" //设备头文件。 #include "CCDirector.h" //方位点规划处置相关头文件 #include "support/CCPointExtension.h" //制造图形函数相关头文件 #include "draw_nodes/CCDrawingPrimitives.h" //运用Cocos2d命名空间 NS_CC_BEGIN //这里定义一个静态变量值,用于保管其时设备工作程序时模版缓冲的位数,这个位数由设备的深度缓冲区格式抉择,一般深度缓冲用D24S8,即24位深度缓冲 8位模版缓冲,所以这个值一般为8。 static GLint g_sStencilBits = -1; //静态函数,为一个结点设置所用的Shader代码片段。 static void setProgram(CCNode *n, CCGLProgram *p) { //调用相应的函数来为结点设置Shader。 n->setShaderProgram(p); //如果没有子结点直接回来。 if (!n->getChildren()) return; //如果有子结点,遍历子结点容器为每个子结点设置相应的Shader代码片段。 CCObject* pObj = NULL; CCARRAY_FOREACH(n->getChildren(), pObj) { setProgram((CCNode*)pObj, p); } } //私有规划函数,做些变量初始化作业。 CCClippingNode::CCClippingNode() : m_pStencil(NULL) , m_bInverted(false) , m_fAlphaThreshold(0.0f) {} //析构函数,已然要脱离这个世界了,那就别再占用人家外部创建的模版缓冲结点了,SO,对占用的模版缓冲结点的计数器减一, CCClippingNode::~CCClippingNode() { CC_SAFE_RELEASE(m_pStencil); } //静态创建函数。 CCClippingNode* CCClippingNode::create() { //new出一个新的CCClippingNode。然后初始化并设置交由内存处理器进行相应的计数器处理。 CCClippingNode *pRet = new CCClippingNode(); if (pRet