cocos2d-x Mask的实现及优化

时间:2022-01-15 02:07:49

转自: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. console的花式用法

    1.百度的招聘启示 如图: 下面是输出代码: if(window.console){ var cons = console; if(cons){ cons.log("%c\n ", ...

  2. session跟cookie的区别

    这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪 ...

  3. 【erlang】IPv6格式转IPv4

    erlang里面的httpd模块保存的http请求头里面,其中remote_addr 保存的是IPv6的格式. 即使是IPv4,也会用IPv6的格式来保存.如 {remote_addr, " ...

  4. 应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题

    重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供 ...

  5. Ionic3 一些命令

    ionic start --help E:\Projects\ionic>ionic start --help ionic start - Create a new project This c ...

  6. C语言之最大公约数与最小公倍数

    #include<stdio.h>int main(){ int num1, num2,temp; scanf("%d%d",&num1,&num2); ...

  7. 运维笔记--docker高效查看后台日志

    场景描述: 应用程序运行在 Docker环境中,经常使用的查看后台日志的命令是:docker attach 容器名该命令优点:实时输出:不足之处:日志大量输出的时候,屏幕一闪而过,不便于调试,并且有一 ...

  8. &lbrack;XPath&rsqb; XPath 与 lxml (四)XPath 运算符

    XPath 中支持的运算符 # | 或: 返回所有 price 和 title 节点集合 >>> root.xpath('//price|//title') [<Element ...

  9. git 从远程仓克隆到本地新分支

    克隆远程仓代码到本地 git clone  http://******:8080/DEV1-WMALL_DQ/WMALL_DQ_Front.git    // git 库地址 当前分支是master ...

  10. Writing a device driver for Windows

    Writing a device driver for Windows        In order to write a device driver for windows, one needs ...