打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Cocos2d: Stencil buffer is not enabled.

各种表示无语啊,在家里的电脑写的文章没法切换源码与展示,明天早点去公司调整一下样式吧……,热死了,买只冰糕去,十点之前回家……

今天使用了ClippingNode来做一个手电筒效果,做ClippingNode的Demo的时候,出现了如题的错:Cocos2d: Stencil buffer is not enabled.原来引擎默认没有开启模版测试。郁闷,搜索了一番,没有找到结果,所以简单一写,记录一下,给大家留个捷径。
当时我就郁闷了,实例是可以的,怎么自己的Demo就不行呢?比较源码是最好的方法,这时候我看源码,结果也没有发现什么异常。郁闷,无语……
关于文理这一方面,有个朋友比我厉害多了,他熟。就和他交流了一会,他也是让我看源码【看来看源码是王道啊,呵呵】。。。
他给我截了个图貌似,如下;

EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]                                     pixelFormat: kEAGLColorFormatRGBA8                                     depthFormat: GL_DEPTH_COMPONENT16                              preserveBackbuffer: NO                                      sharegroup: nil                                   multiSampling: NO                                 numberOfSamples:0 ];

说你比较一下,我各种比较,在TestCpp里面全局搜索,结果没有__glView,郁闷了,无语了。。。
最终发现原因所在,原来我跑的例子是mac的,不是ios的。。。因为不能一起开启两个模拟器,所以我用了mac,可以例子和自己的demo一起看,结果……出来这个悲剧的事情。。。
好嘞,描述了这一戏剧之后进入正题,Cocos2d: Stencil buffer is not enabled.问题解决:
出现这一问题的主要原因是引擎默认不开始模板测试【也不能说是开启模板测试,其实我们设置开关深度测试是这样子的: CCDirector::sharedDirector()->setDepthTest(true);】,我们如果需要,需要自己开启,而开始需要处理depthFormat这个参数,在这里呢,多啰嗦一点深度。解释下之前模板测试、深度测试,加深一下印象。
关于深度测试,看了一篇文章是这么解释我,我感觉不错,在这里借用一下:【openGL 深度测试:http://blog.csdn.net/zhongjling/article/details/7573055 : 感谢网友的贡献】
(1)什么是深度?
深度其实就是该象素点在3d世界中距离摄象机的距离(绘制坐标),深度缓存中存储着每个象素点(绘制在屏幕上的)的深度值!
深度值(Z值)越大,则离摄像机越远。
深度值是存贮在深度缓存里面的,我们用深度缓存的位数来衡量深度缓存的精度。深度缓存位数越高,则精确度越高,目前的显卡一般都可支持16位的Z Buffer,一些高级的显卡已经可以支持32位的Z Buffer,但一般用24位Z Buffer就已经足够了。
(2)为什么需要深度?
在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的。而有了深度缓冲以后,绘制物体的顺序就不那么重要了,都能按照远近(Z值)正常显示,这很关键。
实际上,只要存在深度缓冲区,无论是否启用深度测试,OpenGL在像素被绘制时都会尝试将深度数据写入到缓冲区内,除非调用了glDepthMask(GL_FALSE)来禁止写入。这些深度数据除了用于常规的测试外,还可以有一些有趣的用途,比如绘制阴影等等。
(2)启用深度测试
使用 glEnable(GL_DEPTH_TEST);
在默认情况是将需要绘制的新像素的z值与深度缓冲区中对应位置的z值进行比较,如果比深度缓存中的值小,那么用新像素的颜色值更新帧缓存中对应像素的颜色值。
但是可以使用glDepthFunc(func)来对这种默认测试方式进行修改。
其中参数func的值可以为GL_NEVER(没有处理)、GL_ALWAYS(处理所有)、GL_LESS(小于)、GL_LEQUAL(小于等于)、GL_EQUAL(等于)、GL_GEQUAL(大于等于)、GL_GREATER(大于)或GL_NOTEQUAL(不等于),其中默认值是GL_LESS。
一般来将,使用glDepthFunc(GL_LEQUAL);来表达一般物体之间的遮挡关系。
(3)启用了深度测试,那么这就不适用于同时绘制不透明物体。
备注:
绘制半透明物体时,需注意:在绘制半透明物体时前,还需要利用glDepthMask(GL_FALSE)将深度缓冲区设置为只读形式,否则可能出现画面错误。为什么呢,因为画透明物体时,将使用混色,这时就不能继续使用深度模式,而是利用混色函数来进行混合。这一来,就可以使用混合函数绘制半透明物体了。
根据网友的讲解,启用深度测试,你是不是又想到了我们cocos2d-x开启深度测试呢,就是我之前提及的:

CCDirector::sharedDirector()->setDepthTest(true);

好,我们来跟踪一下代码:setDepthTest(bool bOn),实现如下;

void CCDirector::setDepthTest(bool bOn){    if (bOn)    {        glClearDepth(1.0f);        glEnable(GL_DEPTH_TEST);        glDepthFunc(GL_LEQUAL);//        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    }    else    {        glDisable(GL_DEPTH_TEST);    }    CHECK_GL_ERROR_DEBUG();}

打断下,简单说下这个glClearDepth
【glClearDepth (maxDepth);
参数maxDepth可以是0.0到1.0范围内的任意值。glClearDepth用maxDepth对深度缓存进行初始化,而默认情况下,深度缓存用1.0进行初始化。由于在进行深度测试中,大于深度缓存初始值的多边形都不会被绘制,因此glClearDepth函数可以用来加速深度测试处理。这里需要注意的是指定了深度缓存的初始化值之后,应调用:glClear(GL_DEPTH_BUFFER_BIT);完成深度缓存的初始化。】
看到其中的 glEnable(GL_DEPTH_TEST);了吗?正好吻合,哦也……我才疏学浅,也就能理解到这了,欢迎大神拍砖,多多指教。
关于这个深度测试之前提及的【目前的显卡一般都可支持16位的Z Buffer,一些高级的显卡已经可以支持32位的Z Buffer,但一般用24位Z Buffer就已经足够了】,有必要再解释一下,经过各种查阅之后,认为比较不错的解释是这样子的。上面表述不是一般用到24位就可以了吗?但是那8位做什么了呢?这就是关键。。。聚精会神了,同志们,关键点来了:
深度缓冲还包含stencile bits,所以深度缓冲又成depth-stencil缓冲。当我们的Z Buffer 为24位的时候,其余的8位给了stencil,所谓的模板缓冲。好,这时候再来解释下上文我们提及到的:depthFormat:深度格式,它表示深度缓冲的构造,深度缓冲重视32bits,但是可以使用不同的方式组合,就像纹理格式。一般使用32bits来存储深度信息,但是也用24bits深度信息,另外的8bits存储模板缓冲(stencil buffer)。也就是本文的关键点,解决问题的关键所在,想必看到这里,大家就能知道我们怎么解决问题了。
我们打开Testcpp的ios项目,查看ios文件夹下面的:testsAppDelegate.mm文件,那didfinish的

// Init the EAGLView    EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]                                     pixelFormat: kEAGLColorFormatRGB565                                     depthFormat: GL_DEPTH24_STENCIL8_OES                              preserveBackbuffer: NO                                      sharegroup: nil                                   multiSampling: NO                                 numberOfSamples: 0];    [__glView setMultipleTouchEnabled:YES];

和我之前贴的code对比,发现了吗?depthFormat:GL_DEPTH24_STENCIL8_OES,24bits的深度,8bits的模板缓冲。
哎,想想今天和我朋友戏剧性的对话就像笑,他贴了代码让我对比不同,我死活找不到,完后又对比目录,各种搞笑,呵呵,我二了……最终发现看的不是一个项目,我无语了,问题解决了,朋友对我的评价是:你终于开窍了……
我是怎么了?2了?是不是呀?二妹?不知道二妹能不能看到这篇文章……
哎,想起这戏剧性的对话,真怀念风信子的日子:玉龙、坡坡、大师、老薄、二妹等等,什么ruber、什么这茶叶看起来真香,如果大家对之前2的生活感兴趣,可以看看以前戏剧性的记录,【牛人经典语录:http://www.firedragonpzy.com.cn/index.php/archives/628】
突然想起个事情,之前记得写了篇博文还是帖子来,我提及到我这个朋友,他来了个评论说:他指的朋友是我。 如果我这个朋友看见了,记得给大家讲讲android的处理哈……

各种表示无语啊,在家里的电脑写的文章没法切换源码与展示,明天早点去公司调整一下样式吧……

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
如何在cocos2d-x实现高效的mask
蒙版缓存(Stencil buffer)
OpenGL 的渲染流水线
h_ OpenGL函数思考
Unity Shader
帧缓存操作 glClearColor,glClear,glClearDepth
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服