问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何在cocos2d-x实现高效的mask

发布网友 发布时间:2022-11-07 04:32

我来回答

1个回答

热心网友 时间:2023-10-31 18:05

先说下模板缓冲(stencil buffer),这在05年还算是一个比较普及的技术。cocos2d-x现在的版本是不支持stencil buffer的,但opengl es是支持的。
可以简单的动手改造一下:
创建stencil buffer。在ES1Renderer.m文件中找到resizeFromLayer方法,将if (depthFormat_){}大括号中的代码替换成以下内容:
if (depthFormat_)
{
if( ! depthBuffer_ )
glGenRenderbuffersOES(1, &depthBuffer_);

glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthBuffer_);
if( multiSampling_ )
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, samplesToUse_, depthFormat_,backingWidth_,
backingHeight_);
else
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depthFormat_, backingWidth_, backingHeight_);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES,
depthBuffer_);
// add by frankyang at 2012/5/8
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES,
depthBuffer_);
// bind color buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer_);
}

设置stencil buffer格式。在AppController.mm中找到的didFinishLaunchingWithOptions方法,将其中的depthFormat参数改为GL_DEPTH24_STENCIL8_OES,如下:
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
pixelFormat: kEAGLColorFormatRGBA8
//depthFormat: GL_DEPTH_COMPONENT16_OES
depthFormat:GL_DEPTH24_STENCIL8_OES
preserveBackbuffer: NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];

设置每帧渲染开始时清除stencil buffer。在CCDirector.cpp中找到drawScene方法,将其中
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
改成
glClear(GL_COLOR_BUFFER_BIT | GL_COLOR_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
这样就可以正确清除stencil buffer。
启动模板测试,设置模板函数。这里要用到三个函数:
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

第一个是启用模板测试,第二个是设置模板测试函数,第三个是设置模板缓冲操作方式。
模板测试简单来说就是先往模板缓冲中写入模板值,然后渲染时根据模板测试结果来决定像素是否写入color buffer。
具体解释大家可以看这个帖子深入了解OpenGL-模板测试
为了灵活的写入模板值,我借鉴了Quaz2D中maskLayer的概念,在要渲染的Layer前后插入MaskBeginLayer和MaskEndLayer。
用MaskBeginLayer来填充模板缓冲,并设定好之后需要的模板测试函数;用MaskEndLayer来恢复模板测试状态。

void MaskBeginLayer::visit()
{
if (getChildrenCount() != 0) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0);

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

CCLayer::visit();

glDisable(GL_ALPHA_TEST);
glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
}
}
void MaskEndLayer::visit()
{
glDisable(GL_STENCIL_TEST);

CCLayer::visit();
}

这里要注意透明像素也会写入stencil buffer,所有特别用了alphatest。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
导购什么字 店面导购员是什么意思 HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayer\SafeVersions... 无法安装adobeflashplayer,说无法注册ACTIVEX的控件 无法注册flash player的activex怎么办 omniverse create 他总说无法注册Flash player的Active控件 然后什么访问以下链接。不要... excel如何用进度条的形式表示完成率 买了件速干衣,北面的,求大神看一下真假。 秦皇岛银谷全城热恋是不是要预定票啊 UGUIDrawCall优化 什么叫屏蔽深度缓冲 Unity中的CommandBuffer 表白被拒绝后该怎么办? 公安交通管理警告处罚决定书影响 公安交通管理行政处罚决定书会留案底吗 我想问一下浦发ae白金卡申请攻略有哪些 车贷逾期六个月怎么协商? 双色球我买了16个红球16个蓝球。一共是128128注。25万6256元。红球没中。中了一个蓝球。请问是多少钱? 双色球里买8个蓝球,16个红球多少钱 车贷逾期6个月对自己影响大吗?恶意逾期影响很大! 128128÷3等于多少 128128显示模块上的两个10UF电容作用 EVGA正式宣布结束与英伟达的合作,这两家为何分道扬镳? 美味的菌菇鸡煲怎么做好吃又简单,做法图 菌菇鸡煲的做法步骤图,菌菇鸡煲怎么做好吃 scrm智能营销系统有啥用? c加加程序中使用set+w指定的域宽格式控制仅对紧跟在其后的输出数据向有效_百度问一问 300千克=几吨 三百千克等于多少吨 新春祝福语四字 新春祝福语四字有哪些 速腾usb接口在哪里? OPPO R17 Pro玩得起体感游戏吗? 微信拍一下是怎么回事 微信拍一拍是什么 农产品认证程序是怎样的,农产品认证的程序是怎样的,需要哪些步骤 汽车音响静音怎么恢复? 维京轮胎是马牌的吗,北欧维京是马牌轮胎吗 卡仕达汽车导航怎么样,合肥哪里安装 请问电脑散热风扇怎么安装 请问360借条款是怎么还款的? 初级会计证继续教育什么时候进行?怎么操作? 工控机电源灯亮黄灯不闪烁 OPPO Ace2机型隐私密码如何设置? 稳压电源和充电器有什么区别? 稳压电源和充电器有什么区别 充电器和稳压器有什么区别 6V稳压器和6V充电器有何区别 桐昆股份股票基本面分析?桐昆股份减持是利好还是利空?桐昆股份股票价是多少? 桐昆股份股历史高价?桐昆股份股票的历史行情?桐昆股份今天有什么利空跌了这么多? 桐昆股份这支股票怎么了?桐昆股份最高涨到多少?桐昆股份股票有年底分红么?