文档章节

cocos2d-x 3.x UILayout里的裁剪bug

 为往圣继绝学
发布于 2016/05/17 12:49
字数 503
阅读 80
收藏 0

我们项目有个需求,实行任意形状的遮罩,并且可能有多层叠加,嵌套,blendmode无法实现这么复杂的功能,而如果使用rendertexture呢,效率会变得很低,失帧严重,所以最终决定使用stencil这个opengl的功能。

这样的话跟UIListView里的stencil就有冲突了,然而,UIListView里的裁剪都是矩形,所以用stencil来实现未免大材小用,于是决定将UIListView里的裁剪修改为SCISSOR。

本以为直接将构造函数里的setClippingType改成ClippingType::SCISSOR就行了,可是,改完了发现两个问题,1位置不对,2,有时候多层嵌套,显示不对。

可能是官方默认用了stencil之后没有测试过SCISSOR的显示,其实修改Layout:getClippingRect()方法就行了,这里要考虑的是如果父节点或者更上层的节点也带了裁剪,那么计算时,这个rect就不能超出父节点的裁剪范围。

主要修改如下


const Rect& Layout::getClippingRect() 
{
    if (_clippingRectDirty)
    {
        Vec2 worldPos = convertToWorldSpace(Vec2::ZERO);
        AffineTransform t = getNodeToWorldAffineTransform();
        float scissorWidth = _contentSize.width*t.a;
        float scissorHeight = _contentSize.height*t.d;
        Rect parentClippingRect;
        Node* parent = this;//这里的原来是Layout* parent,当然这么改之后,Node也要改,加一个isClippingEnabled()函数

        while (parent)
        {
//这里原来是转换为Layout,这样的问题是如果中间有一个节点不是Layout的话,嵌套关系就会中断,裁剪区域就会有问题
            parent = dynamic_cast<Node*>(parent->getParent());

            if(parent && parent->isClippingEnabled())
			{
				Layout * layoutP = dynamic_cast<Layout*>(parent);
				if (layoutP != nullptr)
				{
					_clippingParent = layoutP;
					break;
				}
            }
        }
        
        if (_clippingParent)
        {
            parentClippingRect = _clippingParent->getClippingRect();
            //以下也是重写了的,原来的区域计算完全不对
			float finalX = worldPos.x;
			float finalY = worldPos.y;
			float finalWidth = scissorWidth;
			float finalHeight = scissorHeight;
			if (finalX < parentClippingRect.origin.x) finalX = parentClippingRect.origin.x;
			if (finalY < parentClippingRect.origin.y) finalY = parentClippingRect.origin.y;
			if (worldPos.x + scissorWidth>parentClippingRect.origin.x + parentClippingRect.size.width)
				finalWidth = parentClippingRect.origin.x + parentClippingRect.size.width - worldPos.x ;
			if (worldPos.y+scissorHeight>parentClippingRect.origin.x+parentClippingRect.size.height)
				finalHeight=parentClippingRect.origin.y+parentClippingRect.size.height-worldPos.y;

            _clippingRect.origin.x = finalX;
            _clippingRect.origin.y = finalY;
            _clippingRect.size.width = finalWidth;
            _clippingRect.size.height = finalHeight;
        }
        else
		{
			_clippingRect.origin.x = worldPos.x;
			_clippingRect.origin.y = worldPos.y;
            _clippingRect.size.width = scissorWidth;
            _clippingRect.size.height = scissorHeight;
        }
        _clippingRectDirty = false;
    }
    return _clippingRect;
}

 

© 著作权归作者所有

共有 人打赏支持
粉丝 0
博文 4
码字总数 2798
作品 0
朝阳
高级程序员
私信 提问
谈一谈Cocos2d-x中的某些“大小”

[Cocos2d-x相关教程来源于红孩儿的游戏编程之路 CSDN博客地址:http://blog.csdn.net/honghaier] 红孩儿Cocos2d-X学习园地QQ群:249941957加群写:Cocos2d-x 谈一谈Cocos2d-x中的某些“大小”...

长平狐
2013/03/19
191
0
谈一谈Cocos2d-x中的某些“大小”

[Cocos2d-x相关教程来源于红孩儿的游戏编程之路 CSDN博客地址:http://blog.csdn.net/honghaier] 红孩儿Cocos2d-X学习园地QQ群:249941957加群写:Cocos2d-x 谈一谈Cocos2d-x中的某些“大小”...

长平狐
2012/11/19
3.8K
1
移动应用和游戏开发两个阶段在线视频培训的未来计划

在51CTO学院开线上视频课程已经3个多月了,也上了不少课。不过发现还有很多课没有开。现在就将未来的开课计划公布一下。计划分为两个阶段。第一阶段主要是Cocos2d-x和Cocos2d-js的游戏开发培...

androidguy
06/29
0
0
游戏示例的源码有错误

我按《cocos2d-x 3.x 游戏开发之旅》这本书的一个游戏示例敲的代码,也从作者的网站上下了示例源码看了,没有发现代码的问题。 我是Xcode7.3,cocos2d-x3.x但是编译的时候出现了问题,开始的...

光明使者___
2016/06/05
311
0
Cocos2d-js中使用纹理对象创建Sprite对象

本节我们会通过一个实例介绍纹理对象创建Sprite对象使用,这个实例如图5-2所示,其中地面上的草是放在背景(如下图所示)中的,场景中的两棵树是从后图所示的“树”纹理图片中截取出来的,图...

智捷课堂
2015/03/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Go 使用channel控制并发

前言 channel一般用于协程之间的通信,channel也可以用于并发控制。比如主协程启动N个子协程,主协程等待所有子协程退出后再继续后续流程,这种场景下channel也可轻易实现。 场景示例 总结 ...

恋恋美食
21分钟前
1
0
Apache Flink 漫谈系列 - 持续查询(Continuous Queries)

摘要: 实际问题 我们知道在流计算场景中,数据是源源不断的流入的,数据流永远不会结束,那么计算就永远不会结束,如果计算永远不会结束的话,那么计算结果何时输出呢?本篇将介绍Apache Fl...

阿里云官方博客
25分钟前
3
0
斐波那契堆的理解,节点mark属性和势函数

斐波那契堆 看了好多博客,都是照搬算法导论的内容,没有自己的理解,比如为什么有mark属性,势函数的作用,以及为什么叫斐波那契堆,下面说说鄙人的理解。 势函数 势函数是根节点个数加上2...

杨喆
26分钟前
2
0
NIO源码详解

阻塞io和无阻塞io: 阻塞io是指jdk1.4之前版本面向流的io,服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒 ...

沉稳2018
30分钟前
0
0
如何把已经提交的commit, 从一个分支放到另一个分支

在本地master提交了一个commit(8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f),如何提交的test_2分之上? git checkout test_2git cherry-pick 8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f......

stephen_wu
34分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部