【一天亲测】cocos2dx在安卓真机上的一个渲染层级bug

在一个层上不停加精灵(16个左右),会出现渲染层级BUG

传不了图,我简单描述下:

创建一个层,先添加大图精灵、几个小图精灵 他们之间有些会相互遮挡

然后再建一个按钮,按钮点一下就在别的地方创建一个精灵 , 多点几下就会发现 ,之前的相互遮挡的精灵,他们的遮挡关系发生了变化,

原本在上面的会变到下面,总之是随机的。

后来我们老大跟源码发现,在安卓上,存放子节点的向量, 在每一帧渲染时排序会发生错乱。。。错乱原因不,不知大家是否遇到过?

版本:cocos2dx 3.1
安卓版本:我和我们老大的手机都试了,我的是米2 4.X版本

我的测试代码如下:

local layer = cc.Layer:create() 

local sp1 = cc.Sprite:create("res/StroeUI/stroe_bg.jpg") 
layer:addChild(sp1) 
sp1:setPosition(300,400) 
local sp = cc.Sprite:create("res/StroeUI/i3.jpg") 
layer:addChild(sp) 
sp:setPosition(300,400) 

local sp2 = cc.Sprite:create("res/crop.png") 
layer:addChild(sp2) 
sp2:setPosition(300,350) 

local sp3 = cc.Sprite:create("res/crop.png") 
layer:addChild(sp3) 
sp3:setPosition(300,360) 

local sp4 = cc.Sprite:create("res/dog.png") 
layer:addChild(sp4) 
sp4:setPosition(300,340) 
 
local sps = {} 
table.insert(sp1,sps) 
table.insert(sp2,sps) 
table.insert(sp3,sps) 
table.insert(sp4,sps) 

local function onItem() 
    local sp8 = cc.Sprite:create("res/land.png") 
    layer:addChild(sp8) 
    sp8:setPosition(800,340) 
    table.insert(sp8,sps) 
end 

local lab = cc.Label:create("add", "" , 50) 
local item = cc.MenuItemLabel:create(lab) 
local menu = cc.Menu:create(item) 
item:registerScriptTapHandler(onItem) 
menu:setPosition(800,300) 
layer:addChild(menu)

3.x的底层渲染优化成了多线程渲染 如果是同一层次的child 渲染的先后次序由线程执行先后决定 你addChild的时候没有指定zorder 所以渲染层级结果就是不确定的 试试addChild后面带上zorder参数

如果是多线程,那同一层次child渲染先后由线程执行先后决定,那不应该每次第一次都是正确的顺序,应该也是随机的才对吧?

跟源码的时候发现是向量排序发生了错误,貌似这BUG在ios上不会出现这种问题,难道是ndk的问题吗?用的是ndkr9b

经过各种测试,发现这个问题的原因出在Node的visit()函数。
在这个函数中会先把所有的子节点按zorder和_orderOfArrival进行排序,然后再调用子节点的visit()函数。
这个本身没有问题,出问题的是在函数的最后面把_orderOfArrival=0了。
所以下一次visit()的时候所有的子节点的_orderOfArriva都是0,然后在安卓下面_children的排序结果就不对了。
Node中子节点的排序代码如下:
bool nodeComparisonLess(Node* n1, Node* n2)
{
return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
这个代码在win下面排序的结果是正常的,zorder和_orderOfArriva都相同的部分会按照上一次的顺序。
在安卓下面zorder和_orderOfArriva都相同的部分的排列就不对劲了,好像是随机的(Vector的元素很少的时候也没有问题)。
是std::sort()函数的结果不对。
调查结果如上,求解决方案!!!!!!!!!!!!!!!!!!

:2::2:马克,关注后续

把visit里面的orderOfArrive(0)全部注释掉,记得全局搜索一下,所有的Node节点都需要这样修改。
v3.3beta版本已经修改了这个问题。

这个问题应该很普遍才对啊。。。。为什么以前没人提。。。。javascript://javascript://

同样遇到次问题