加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Cocos RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略

(2016-08-20 15:32:23)
标签:

it

cocos2d-x

rendertexture

橡皮擦

刮刮乐

分类: cocos2d-x·相关学习

版本:cocos2d-x 3.10     语言:C++

 

今天开始看《Windows游戏编程大师技巧》,以后可能穿插着cocos,主要开始更这本书相关的内容。

 

其中一句话让我感触良深,游戏程序员是最不喜欢写注释的。现在被当前项目折磨的想死,没有文档、没有注释、代码大家随意添加,策划功能改个不停,也是……够了。

 

今天把遗留下来的内容给解决了,就是橡皮擦效果,网上搜索到的文章都讲的不太清晰,只有一篇把原理给讲清楚了,后来我才把这个东西给做出来,使用简单的像素替换很简单,但是我想实现自定义画笔的效果。

 

首先定义两个类成员变量:

Sprite* eraserOther   //橡皮

RenderTexture* rTex   //画布

 

橡皮相当于是画图工具中的橡皮,可以把图片什么的擦掉。而画布可以进行渲染,将一些图片显示在上面,来看看init函数:

//创建一个橡皮擦

eraserOther = Sprite::create("eraser.png");

eraserOther->retain();

 

注意不要addChildlayer中,然后layer退出的时候不要忘记release,至于eraser.png,搞一张完全透明的图片的OK了,尺寸不要太大了。继续:

//创建画布,并显示

rTex = RenderTexture::create(visibleSize.width, visibleSize.height);

rTex->setPosition(visibleSize.width / 2, visibleSize.height / 2);

this->addChild(rTex);

 

//创建需要被擦除的内容

Sprite* spriteBG = Sprite::create("HelloWorld.png");

spriteBG->setPosition(visibleSize.width / 2, visibleSize.height / 2);

//this->addChild(spriteBG);

 

//将内容渲染到画布上

rTex->begin();

spriteBG->visit();

rTex->end();

 

创建画布后就将需要显示的图片内容给手动渲染到画布上了,因为需要被擦除内容的Sprite会在这一帧结束的时候被释放掉,所以不需要retain,用完就丢了!

 

运行一下之后,就是很普通的将图片显示出来了:

http://s4/mw690/005w9uaNzy74cjsT31N23&690RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" TITLE="Cocos RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" />

 

接下来是关键,触摸事件相关的代码就不说了,直接看onTouchMoved中的代码:

void GuaJiangScene::onTouchMoved(Touch *touch, Event *unused_event)

{

    //将橡皮设置到点击的位置

    Vec2 touchPoint = touch->getLocation();

    eraserOther->setPosition(touchPoint);

 

    //设置混合方式

    BlendFunc blendFunc = { GL_ONE, GL_ZERO };

    eraserOther->setBlendFunc(blendFunc);

 

    //开擦!

    rTex->begin();

    eraserOther->visit();

    rTex->end();

}

 

嗯,很简单对吧,就是设置了一下橡皮Sprite的混合模式后,直接渲染到画布上了,这是网上大多文章使用的方法。

 

运行一下:

http://s5/mw690/005w9uaNzy74cjtQB6sf4&690RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" TITLE="Cocos RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" />

 

这样就简单的实现了,但是我想需要一种自定义画笔的效果,比如有这么一块橡皮:

http://s10/mw690/005w9uaNzy74cjuA3KFb9&690RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" TITLE="Cocos RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" />

 

其中透明的部分还是一样会把画布上的内容给去除,但不透明黑色的部分则会保留画布上的内容。怎么做呢?肯定就是和混合模式设置相关的吧。我实验了好久,后来看了一篇文章后,终于意识到这个混合模式是什么意思了。

 

简而言之就是:源图 * 源图因子 目标图 * 目标因子。

 

举例而言,如果我们的混合方式为:

BlendFunc blendFunc = { GL_ONE, GL_ZERO };

 

那么我们的橡皮效果就是:橡皮Sprite * GL_ONE + 画布 * GL_ZEROGL_ONE就是1,完全保留像素,而GL_ZERO就是0,完全舍弃像素,效果就是橡皮的像素完全替换了画布的像素。

 

理解了之后,就很简单了,有这个一个参数:GL_SRC_ALPHA,这个是仅处理透明度,而使用的是源图的透明度作为因子。到这里,大家应该能把自定义画笔效果写出来了吧。

 

没错,只要把混合方式调成:

BlendFunc blendFunc = {GL_ZERO, GL_SRC_ALPHA };

 

完全忽略橡皮的像素,只取橡皮的透明度作为因子,来改变画布上的透明度。

 

最终效果:

http://s4/mw690/005w9uaNzy74cjvjI0Hd3&690RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" TITLE="Cocos RenderTexture 橡皮擦效果 自定义画笔 最简单、最清晰的完全攻略" />

 

至于要显示橡皮连续擦的效果,只要在前后两个移动点之间增加渲染次数就OK了,具体算法写的不好就不贴了。

 

大学里的时候不觉得自己时间少,现在工作了之后感觉真的没什么时间,昨天玩了一个小时的游戏感觉很难得了,又想做这个、又想做那个,究竟怎么样一下子能全部做好,也没有什么答案。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有