转自:http://blog.ch-wind.com/cocos2d-x%E4%B8%ADmask%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8F%8A%E4%BC%98%E5%8C%96/

关于cocos2d-x内的Mask来做类似光点或者视野控制等功能的思路,最早是在一篇外文上看到的。拿来用过之后发现效果还是不错,于是直接放进了程序里。可是在实际运用时发现其运行效率不是那么理想,尤其是以pc平台为目标时由于配置不同造成的帧率下降比较明显。对代码进行分析之后发现,Mask的功能使用的是CCRenderTexture动态生成纹理并覆盖在目标层上的。在每一次绘制中,这个纹理都会重新生成一次,这就造成了极大的效率上的浪费。同时CCRenderTexture貌似使用了FBO,在某些旧的显卡上会引发极大的帧率丢失。

于是着手对其进行改造,事实上之所以要每次循环都重新生成纹理是因为mask本身的位置会不断更新。而如果打算单独使用sprite+glblencfunc来解决的话,由于绘制顺序的关系很难找到一个好的动态mask解决方案。当然准备一个大概四倍视口的mask图片是可以的,但是这样的话效率也比较低下,只能留作备选方案。

最终选择的解决方案是使用clippingnode,clippingnode是使用模板测试来实现的,这是gl的基础功能,不会对硬件有太大的需求。以一个CCColorlayer为Clipping的content,首先进行模板测试,然后再叠加作为遮罩的sprite就好了。

csb_st = CCSpriteBatchNode::create("Images/circle.png");

cp_board = CCClippingNode::create();
cp_board->setContentSize(visibleSize);
cp_board->setPosition(CCPointZero);
cp_board->setAnchorPoint(CCPointZero);
cp_board->setStencil(csb_st);
cp_board->setInverted(true); ////////////////////////////////////////////////////////////////////////// CCLayerColor* clc = CCLayerColor::create(ccc4BFromccc4F(m_renderColor),visibleSize.width,visibleSize.height);
clc->setAnchorPoint(CCPointZero);
clc->setPosition(CCPointZero);
cp_board->addChild(clc); //content
cn_borad->addChild(cp_board,m_iLaDep+); CC_BREAK_IF(!f_refresh_circles());

sprite的话使用传说中的经典地图遮罩blend就好了:

ccBlendFunc cbf = {GL_DST_COLOR, GL_ZERO};

cns_blocks = CCSpriteBatchNode::create("Images/circle.png");
cns_blocks->setBlendFunc(cbf);
cp_board->addChild(cns_blocks); ////////////////////////////////////////////////////////////////////////////
m_AkaruCircle = CCSprite::create("Images/circle.png");
m_AkaruCircle->setBlendFunc(cbf);
m_AkaruCircle->setPosition(ccp(,));
m_AkaruCircle->setScale();
m_Board->addChild(m_AkaruCircle,m_iLaDep);

当然,这样的话由于GLZERO的blend结果是(0,0,0,0),如果不是做纯黑的不透明遮罩,即便精心的准备遮罩图片,多少还是会有一些违和感存在,如果出现这种情况而无法从其他方面进行修正的话,还是必须使用rendertexture。由于rendertexture的效率因素,我们必须尽量减少其负担,只是对sprite进行处理,除非需要动态改变遮罩的背景色,我们都不会对sprite进行重新生成。

ccBlendFunc cbf = {GL_ZERO, GL_ONE_MINUS_SRC_ALPHA};

CCSprite* t_sp = CCSprite::create("Images/circle.png");
t_sp->setPosition(CCPointZero);
t_sp->setAnchorPoint(CCPointZero);
t_sp->setBlendFunc(cbf); CCSize vs = t_sp->getContentSize();
CCRenderTexture* t_crt = CCRenderTexture::create(vs.width, vs.height);
t_crt->beginWithClear(m_renderColor.r, m_renderColor.g, m_renderColor.b, m_renderColor.a); t_sp->visit(); t_crt->end(); m_AkaruCircle = CCSprite::createWithTexture(t_crt->getSprite()->getTexture());
//m_AkaruCircle->autorelease();
m_AkaruCircle->setScale();
m_Board->addChild(m_AkaruCircle,m_iLaDep);

这样一来Mask的总体效率就是一次模板测试加上两次spritebachnode的绘制,可以作为频繁使用CCRenderTexture的替代方案使用了。代码如下,由于目前的代码结构的关系,要测试的话spotlight类需要被继承,然后在适当的地方调用f_init才行。

cocos2d-x Mask的实现及优化的更多相关文章

  1. CVPR2019 | 超越Mask R-CNN!华科开源图像实例分割新方法MS R-CNN

    安妮 乾明 发自 凹非寺 本文转载自量子位(QbitAI) 实习生又立功了! 这一次,亮出好成绩的实习生来自地平线,是一名华中科技大学的硕士生. 他作为第一作者完成的研究Mask Scoring R- ...

  2. 论文阅读笔记二十三:Learning to Segment Instances in Videos with Spatial Propagation Network(CVPR2017)

    论文源址:https://arxiv.org/abs/1709.04609 摘要 该文提出了基于深度学习的实例分割框架,主要分为三步,(1)训练一个基于ResNet-101的通用模型,用于分割图像中的 ...

  3. 如何优化cocos2d程序的内存使用和程序大小

    在我完成第一个游戏项目的时候,我深切地意识到"使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰".而我刚开始接触cocos2d的时候,社区里面的人 ...

  4. (译)如何优化cocos2d程序的内存使用和程序大小:第二部分(完)

    前言:从上周发布教程的微博反应情况来看,cocos2der们对于游戏的内存问题还是非常关心的.本文是上一篇博文的续,旨在教大家如何减少cocos2d程序的大小. 全文如下: 减少你的程序的大小 把纹理 ...

  5. 如何优化cocos2d程序的内存使用和程序大小:第一部分

    译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...

  6. 在cocos2d里面如何使用Texture Packer和像素格式来优化spritesheet

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  7. cocos2d 如何优化内存使用

    如何优化内存使用 内存优化原理 为优化应用内存使用,开发人员首先应该知道什么最耗应用内存,答案就是纹理! 纹理几乎会占据90%应用内存.所以尽量最小化应用的纹理内存使用,否则应用很有可能会因为低内存而 ...

  8. 如何优化cocos2d程序的内存使用和程序大小:第一部分_(转)

    译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...

  9. 如何优化cocos2d/x内存使用和程序大小的程序

    从最初的:http://www.himigame.com/iphone-cocos2d/1043.html 译者: 在我完毕第一个游戏项目的时候.我深切地意识到"使用cocos2d来制作游戏 ...

随机推荐

  1. eclipse集承jboss服务器

    eclipse Kepler + Jboss7.1 参考引用文档: http://www.tekdigest.com/how-to-install-jboss-tools-in-eclipse.htm ...

  2. ECSHOP seo修改建议

    ECSHOP是一个非常优秀的商城程序,以丰富的模板.稳定开源.非常快的执行速度赢得广大网店主的青眯.可是新建站30多天,目前百度只收录了首页,而google收录正常.我检查了他的网站一切正常,没有任何 ...

  3. POJ 2136 Vertical Histogram

    题意:按样例那样模拟…… 解法:模拟…… 代码: #include<stdio.h> #include<iostream> #include<algorithm> ...

  4. 10、TV UI

     TV UI布局 1. 为大屏幕提供适当的布局源文件. 2. 确保UI在一定距离仍然可以看清. 3. 为高清电视提供高分辨率的图标和图像. 1. 把屏幕上的导航控制菜单放在屏幕的左边或者右边,并且将 ...

  5. 网站eurl.axd报错的解决方法

    网站eurl.axd报错的解决方法 错误发生的原因是当ASP.NET检测到Web站点配置为使用ASP.NET 4.0,本地ASP.NET 4.0 的组件会传递一个不能扩展的 URL到ASP.NET的管 ...

  6. poj 1651 http://poj.org/problem?id=1651

      http://poj.org/problem?id=1651Multiplication Puzzle   Time Limit: 1000MS   Memory Limit: 65536K To ...

  7. OpenGL超级宝典第5版&&缓冲区

    缓冲区有很多用途:可以保存顶点数据,像素数据,纹理数据,着色器处理的输入,不同着色器阶段的输出. 缓冲区保存在GPU内存中,提供高速有效的访问.   像素缓冲区对象: GLuint pixBuffer ...

  8. STM32F407 外扩SRAM

    字节控制功能.支持高/低字节控制. 看看实现 IS62WV51216 的访问,需要对 FSMC进行哪些配置. 这里就做一个概括性的讲解.步骤如下: 1)使能 FSMC 时钟,并配置 FSMC 相关的  ...

  9. BufferedReader和BufferedWriter读写文件(转载)

    http://375940084.blog.51cto.com/2581965/751040 1.创建Student类存储每个学生信息,属性(学号,姓名,出生日期,得分)2.从c:/test/stud ...

  10. bzoj 2095: [Poi2010]Bridges(二分法+混合图的欧拉回路)

    [题意] 给定n点m边的无向图,对于边u,v,从u到v边权为c,从v到u的边权为d,问能够经过每条边一次且仅一次,且最大权值最小的欧拉回路. [思路] 二分答案mid,然后切断权值大于mid的边,原图 ...