【cocos2dx】之RenderTexture实现截图
【cocos2dx】之RenderTexture实现截图
⼤家好,我是Lampard
今天与⼤家探讨⼀下cocos中实现截图所使⽤到的类RenderTexture
(⼀)使⽤RenderTexture实现截图功能
cocos实现截图可以通过两种⽅式。第⼀种就是今天将要介绍的使⽤renderTexture类去实现,第⼆种是利⽤cocos2dx在3.2版本之后给我们提供的utils:captureScreen()实现截图。两种⽅式互有优劣,前者就好像你去到了⼀个超市,看见呈现在屏幕上琳琅满⽬的商品,你可以挑选任意商品绘制到你的图⽚上,但如果这个商品⽐较复杂(如3d的精灵)那么你可能就得不到想要的效果,需要花更多的功夫。⽽第⼆助理医师技能考试
种使⽤起来就⽐较简单,就像⼩孩⼦才需要做选择,⼤⼈全都要。它能对屏幕直接进⾏截图,其实现原理有点⼿机截图,我不管你是怎么实现的,它直接把屏幕上的像素点记录下来再⽣成⼀个image保存,所以3d精灵对于第⼆种⽅式来说也不过是像素点⽽已,能够绘制出来,但它⽆法只画出你想要的内容
我们可以⽤上⽂的⽅法实现截图功能,⾸先创建⼀个renderTexture画布,设置画布的⼤⼩。然后调⽤begin函数去记录期间渲染的对象(调⽤endToLua结束之前),最后输出到磁盘中
(⼆)解读RenderTexture源码
create⽅法
我们通过查阅源码去了解上述⽅法的是如何实现截图的。在RenderTexture中,重载了好三个create⽅法,分别是:怎样对文件夹加密
我们是只传⼊了宽⾼,所以执⾏的是这⼀个函数。⾸先实例化了⼀个RenderTexture对象,然后调⽤了对象
的initWithWidthAndHeight⽅法对画布进⾏⼀个初始化,最后把这个⽣成的对象加⼊⾃动回收池中,对于我们没有传⼊的客户端的像素格式和深度模板缓冲格式默认使⽤了RGBA8888和0
像素格式和深度模板缓冲格式是什么
⾸先讲⼀下像素格式,像素格式常见的有4个通道,分别是:R红⾊通道,G绿⾊通道,B蓝⾊通道,A透明度通道。引擎默认是使⽤RGBA8888的格式,也就是每⼀个通道⽤8个位去记录值,所以⼀个像素就是需要32个位,也就是4个字节,如果⼀张1024*1024的图⽚就需要4M的空间去存储。所以常见的优化⽅式是把RGBA8888的像素格式修改成RGBA4444,对于精度要求没有那么⾼但是⼜需要透明通道的图⽚来说,能节省⼀半的空间。如果不需要透明通道,可以使⽤RGB565和RGB888等等,以下是官⽹像素格式的⽂档
然后说⼀下什么是深度模板缓冲,它其实是包含了两个东西,分别是深度缓冲和模板缓冲
深度缓冲区
深度缓冲区(或 z 缓冲区)存储像素的深度信息,以控制渲染哪些多边形区域。简单来说,就是当同⼀场景中,出现位置重叠的像素,那么GPU需要知道该显⽰哪⼀个像素信息,这时就可以通过深度缓存区中的值来⽐较,若⽐缓存区中的值⼩(更上层),颜⾊缓冲中记录下当前像素的信息,否则则不对此颜⾊进⾏记录
模板缓冲区
模板缓冲区⽤于遮罩图像中的像素,以产⽣特殊效果。特殊效果包括合成、贴纸、溶解、淡化、滑动、轮廓描绘和剪影,以及双⾯模板等。模板测试发⽣在透明度测试(alpha test)之后,深度测试(depth test)之前。如果模板测试通过,则相应的像素点更新,否则不更新
像上图中图⼀是颜⾊缓冲区,图⼆是模板缓冲区,图三就是最后最后渲染出的结果。cocos中深度模板缓冲格式给我们提供了三个选择
initWithWidthAndHeight⽅法
initWithWidthAndHeight⽅法主要是根据我们传⼊的宽⾼,客户端像素格式,深度模板格式对renderTexture对象进⾏⼀个初始化。若成功则返回true,不成功则返回false。它主要分以下⼏个步骤进⾏初始化
开辟空间传给纹理对象
根据是否⽀持宽⾼纹理的像素为⾮2的n次⽅来调整设定的宽⾼,然后根据最终的宽⾼申请内存,⼤⼩为powW * powH * 4
科幻电视剧把申请得来的内存⽤0来填充,然后⽣成⼀个texture2D的纹理对象,并把内存块,内存长度,宽⾼等信息传递给纹理对象使其进⾏初始化
描写让人看完会湿的句子把这个纹理绑定到帧缓冲
当把⼀个纹理附加到帧缓冲的时候,所有的渲染指令将会写⼊到这个纹理中,就想它是⼀个普通的颜⾊/深度或模板缓冲⼀样。使⽤纹理的优点是,所有渲染操作的结果将会被储存在⼀个纹理图像中。
创建帧缓冲对象⽤到了两个⽅法。glGenFramebuffers需要传⼊两个参数,第⼀个是要创建的帧缓存的数⽬,第⼆个是指向存储⼀个或者多个ID的变量或数组的指针。它返回未使⽤的FBO的ID。glBindFramebuffer第⼀个参数target是GL_FRAMEBUFFER,第⼆个参数是FBO的ID号从⽽⽣成FBO对象并把FBO对象绑定在上⾯,⼀旦FBO被绑定,之后的所有的OpenGL操作都会对当前所绑定的FBO造成影响。最后是帧缓冲绑定的颜⾊缓存到纹理中
如果使⽤了深度缓冲,再创建⼀个深度渲染缓冲对象
冬至是哪天深度缓冲与帧缓冲类似,同样需要⽣成渲染缓冲对象然后绑定到GL_RENDERBUFFER中去。并且需要把这个渲染缓冲对象绑定在帧缓冲对象的GL_DEPTH_ATTACHMENT深度关联点中,如果还有模板缓冲则把这个渲染缓冲对象绑定在帧缓冲对象的
GL_STENCIL_ATTACHMENT模板关联点中
个人资料简介把纹理数据作为参数,⽣成sprite绘制到屏幕帧缓冲中
最后⽣成⼀个sprite,会过程中绘制的内容呈现在屏幕上,并把帧缓冲还原成最初的状态
帧缓冲是什么
这个时候就会有朋友提问了,提了好⼏次帧缓冲,⼜得把深度模板的关联点绑定到上⾯去,那帧缓冲是什么东西呢?⾂妾也不会啊,这只能去官⽹点⽂档看了