07-渲染流程-3-Sprite渲染-判断是否裁剪分析
来源:互联网 发布:火箭vs勇士数据 编辑:程序博客网 时间:2024/06/07 14:31
我们集中精力来看Sprite的draw()
_insideBounds = transformUpdated ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
正如注释所述,该步骤是判断该Sprite是否在显示的Bounds中,如果transformUpdated没有发生改变,则不需要计算,之前是显示与否,决定了此次的显示与否。
而如果transformUpdated改变了,比如
1.第一次刷新的时候
2.对该Sprite对象setPosition,或者其父对象某一个位置发生了改变,则需要重新计算。
在这里我们假定要计算需要裁减,那么我们看看是如何计算该Sprite是否需要渲染呢?
Sprite渲染裁减计算
renderer->checkVisibility(transform, _contentSize)
transform 是父层调用传入的内容,在HelloWorld中,是由Sprite自己传入的,因为scene传入的是
Mat4::IDENTITY
而layer没有改变其位置 缩放 旋转 错切,所以在此处传入的值依然是
Mat4::IDENTITY
而Sprite如果形态没有发生改变的话,传入的应该也是identity
_contentSize 代表了该Sprite的大小 (width,height)
1.首先我们要搞清楚, _contentSize 是从哪里来的
_contentSize 在Node中声明,并初始化为 Size::ZERO
在Node中定义了赋值的方法:
void Node::setContentSize(const Size & size)
{
if ( ! size.equals(_contentSize))
{
_contentSize = size;
_anchorPointInPoints = Vec2(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y );
_transformUpdated = _transformDirty = _inverseDirty = true;
}
}
浏览代码可以看到_contentSize的由来
A Sprite::create( file name)
B -> Sprite::initWithFile( file name )
获取了 Texture2D 对象,从而获取图像的 Rect
C -> Sprite::initWithTexture(texture,rect,not rotate)
D -> 最终来到了 Sprite::setTexureRect 中
于是我们知道了
renderer->checkVisibility(transform, _contentSize)
中的_contentSize 是图片的大小(在HelloWorld例子中)
2.对参数了解之后,我们该到checkVisibility 来看看了
这段代码主要是判断一个Sprite只要有部分在屏幕范围内就是true,否则false
判断Sprite矩形和屏幕矩形之间的关系,可以借鉴圆和圆的关系判断
如图所示,黑色边框代表的是屏幕,红色代表的是一个Sprite
在水平上判断过程:
1.屏幕中心点A所在世界坐标为(sw*0.5,sh*0.5)
2.sprite的中心点B所在世界坐标为 sprite的变换矩阵*(w*0.5,h*0.5)
3.计算两个矩形中心点之间的距离 AB
4.Sprite在世界坐标中的宽度和高度。BW BH
5.AB - BW/2 如果 <= SW/2 则说明水平方向上和屏幕的一条侧边有交集
6.但是要保证和屏幕有交集,则需要同时保证垂直方向上Sprite和屏幕的一条侧边有交集
否则如下图所示,也是不在屏幕内的
我们再回头看看代码:
1.获取了两个矩形中心点之间的距离
v4world的x y 的绝对值,代表了水平和垂直方向之间的距离
2.获得sprite在世界坐标系下的长度和宽度
这里猜测可能是为了处于效率的问题,直接将坐标和矩阵中对应的坐标进行了转换。矩阵中的 [0] [4] 和 [1] [5] 代表了在X轴和Y轴上的旋转 缩放 错切后的对应项,所以这里直接进行了转换
3.AB - BW/2 如果 <= SW/2 则说明水平方向上和屏幕的一条侧边有交集
但是要保证和屏幕有交集,则需要同时保证垂直方向上Sprite和屏幕的一条侧边有交集
在计算Sprite在世界矩阵中的长和宽的时候,我修改了如下的代码,可能看起来会更清晰些吧
在这里需要说明的是,如果Sprite本身,以及父对象没有放大、缩小、错切,那么其transform是
{ 1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1}
则 wshw = hSizeX wshh = hSizeY
但是如果父对象进行了刚体变换,则需要用Sprite本身图片大小,通过变换矩阵来换算出真实的大小
对于Sprite来说,通过transform变换成了变形后的样子,所以其中心点(hSizeX,hSizeY)的位置,通过transform就可以找到变形后的真实位置
所以修改的代码中可以不通过左下角和右上角的变换来计算大小,直接通过中心点(hSizeX,hSizeY)来计算变形中的坐标大小即可获取content大小的一半,也就是wshw wshh的坐标值 world sprite half width/height
- 07-渲染流程-3-Sprite渲染-判断是否裁剪分析
- 07-渲染流程-4-Sprite渲染-渲染命令分析
- 07-渲染流程-5-Sprite渲染-QuadCommand
- 07-渲染流程-2-HelloWorld分析
- cocos2d-x渲染流程分析
- 用Starling渲染Sprite
- 07-渲染流程-1-流程
- unity中判断渲染物体是否在摄像机内渲染
- 渲染流程
- 渲染流程
- 渲染流程
- 渲染流程
- 渲染流程
- 判断页面是否第一件渲染
- 【Unity】判断物体是否会被渲染
- AngularJS判断页面是否已经渲染结束
- 大型场景裁剪渲染
- Ogre内部渲染流程分析系列
- Divide Two Integers - Leetcode
- 在Docker容器中实现安全与隔离
- mybatis生成器
- Android_Handler
- NYOJ 数单词
- 07-渲染流程-3-Sprite渲染-判断是否裁剪分析
- <6> go select 和 switch
- 数组定义的三种方式
- 【HDU5411 2015 Multi-University Training Contest 10F】【矩阵快速幂 加一行构造法】CRB and Puzzle 矩阵的1次方到n次方的数值和
- 数组定义的三种方式
- csdn越来越卡了
- 十五个常用的jquery代码段
- iOS 抽奖转盘
- 3-5TeX中的引号