解决了一个cocos2dx 在部分 android手机上模板测试错误的问题

在android 手机上,大部分的机器模板测试都没问题。但是有一个奇葩的手机,小米2S, 当只有一层需要模板测试的时候 ,在cocos2dx 里具体地说就是 使用 CCClippingNode 的时候 ,是没问题的 。但是当一个  CCClippingNode 嵌套另外一个  CCClippingNode 时,就会出现各种显示不出来的问题。cocostudio 制作 GUI  里面许多面板,当开启剪裁功能后 ,比如 UIPageView UIScrollView 也都是靠  CCClippingNode 开启模板缓存来渲染的 。

原因没有具体弄明白,但是我用另外一个手段避开了这个问题。

因为是 模板测试 嵌套 模板测试 时,才会有问题 ,并且这种问题很多出现 在 GUI上 ,GUI 的大背景通常是一个长方形 ,所以就把 GUI 的 renderer ,也就是 RectClippingNode 剪裁时的渲染方式,从使用 模板测试,修改为 使用 剪裁测试,并根据剪裁区域设置 opengl 的剪裁区域,     渲染时从渲染 clipping node ,变为正常地渲染 普通 node .这样 就比较完美地避开了了这个问题。

渲染前保存好 scissor 相关的 参数,渲染后恢复即可。 cocos2dx 渲染其他 opengl 特性的 node 的做法,通常也就是这样子的。具体可以参考 cocos2dx CCClippingNode 的 visit() 方法。

剪裁测试相关的关键字主要是  GL_SCISSOR_TEST glScissor() 之类的 ,具体api 可以自行查阅  OpenGL 资料。

通过此问题,我进一步地了解了 opengl 渲染管线 几个测试的   的意义 和 顺序关系 ,也进一步知道了 这几个测试 都是发生在  fragment shader 之后。

并且还了解到了 Android  SDK 的一个 分析渲染性能和渲染错误的工具  Tracer for OpenGL es, eclipse 如果安装了插件,就可以在eclipse里开启它了。 虽然最后解决问题没用到它,但是感觉这是一个不错的工具 。

具体的用法 官方文档有介绍 。可是山炮 的 小米 2S 上也跑步起来这个工具。

解决了这个问题挺高兴,特此记录。

void RectClippingNode::visit()
{
    if (!m_bEnabled)
    {
        return;
    }
    if (m_bClippingEnabled)
    {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)		
		//	some android device , such as "mi 2s" do not support stencil test node in stencil test node
		//	so when load cocostudio GUI, do not use stencil test ,but use scissor test replace it.
		bool bEnabledScissorBefore = CCEGLView::sharedOpenGLView()->isScissorEnabled();
		CCRect scissorRectBefore = CCEGLView::sharedOpenGLView()->getScissorRect();

		//	try to use Scissor Test replace Stencil Test	
		glEnable(GL_SCISSOR_TEST);
		
		CCPoint worldPos = m_pParent->convertToWorldSpace(getPosition());
		CCPoint anchor = getAnchorPoint();

		CCPoint leftDownPos = ccp(worldPos.x - anchor.x * m_clippingSize.width ,worldPos.y - anchor.y * m_clippingSize.height);
		CCEGLView::sharedOpenGLView()->setScissorInPoints(leftDownPos.x,leftDownPos.y,m_clippingSize.width,m_clippingSize.height);	//	@temp 0,0

		CCNode::visit();

		//	restore opengl states
		bEnabledScissorBefore ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
		CCEGLView::sharedOpenGLView()->setScissorInPoints(scissorRectBefore.origin.x,scissorRectBefore.origin.y,scissorRectBefore.size.width,scissorRectBefore.size.height);
#else
		CCClippingNode::visit();
#endif
    }
    else
    {
        CCNode::visit();
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值