mirror of
https://gitee.com/nomat/lcc-ui-sorting-group-demo.git
synced 2025-01-13 22:51:03 +00:00
973434cd71
2、sortinggroup组件只在当前节点和其子节点有效,其他节点仍然使用节点树遍历
197 lines
5.3 KiB
TypeScript
197 lines
5.3 KiB
TypeScript
|
|
let _batcher;
|
|
let _cullingMask = 0;
|
|
|
|
/**
|
|
* 当前渲染层级
|
|
*/
|
|
let renderLevel = 0;
|
|
|
|
/**
|
|
* 当前渲染优先级
|
|
*/
|
|
let renderPriority = 0;
|
|
|
|
/**
|
|
* 渲染器缓存
|
|
*/
|
|
let rendererCache:cc.RenderComponent[] = [];
|
|
|
|
/**
|
|
* 渲染器排序
|
|
*/
|
|
let rendererOrder:boolean = false;
|
|
|
|
/**
|
|
* 刷新渲染缓存
|
|
*/
|
|
function flushRendererCache(){
|
|
if(rendererCache.length > 0){
|
|
if(rendererOrder){
|
|
rendererCache.sort((a, b)=>{ return a.renderPriority - b.renderPriority; });
|
|
}
|
|
for(let render of rendererCache){
|
|
// console.log(`${render.node.name} - ${render.renderPriority}`);
|
|
//@ts-ignore
|
|
render._checkBacth(_batcher, render.node._cullingMask);
|
|
//@ts-ignore
|
|
render._assembler.fillBuffers(render, _batcher);
|
|
}
|
|
rendererCache.length = 0;
|
|
}
|
|
rendererOrder = false;
|
|
}
|
|
|
|
//@ts-ignore
|
|
cc.RenderFlow.visitRootNode = function (rootNode){
|
|
renderLevel = 0;
|
|
renderPriority = 0;
|
|
rendererCache.length = 0;
|
|
rendererOrder = false;
|
|
|
|
//@ts-ignore
|
|
_batcher = cc.RenderFlow.getBachther();
|
|
|
|
//@ts-ignore
|
|
cc.RenderFlow.validateRenderers();
|
|
|
|
let preCullingMask = _cullingMask;
|
|
_cullingMask = rootNode._cullingMask;
|
|
|
|
//@ts-ignore
|
|
if (rootNode._renderFlag & cc.RenderFlow.FLAG_WORLD_TRANSFORM) {
|
|
_batcher.worldMatDirty ++;
|
|
rootNode._calculWorldMatrix();
|
|
//@ts-ignore
|
|
rootNode._renderFlag &= ~cc.RenderFlow.FLAG_WORLD_TRANSFORM;
|
|
|
|
//@ts-ignore
|
|
cc.RenderFlow.flows[rootNode._renderFlag]._func(rootNode);
|
|
flushRendererCache();
|
|
|
|
_batcher.worldMatDirty --;
|
|
}
|
|
else {
|
|
//@ts-ignore
|
|
cc.RenderFlow.flows[rootNode._renderFlag]._func(rootNode);
|
|
flushRendererCache();
|
|
}
|
|
|
|
_cullingMask = preCullingMask;
|
|
}
|
|
|
|
//@ts-ignore
|
|
cc.RenderFlow.prototype._render = function (node) {
|
|
let comp = node._renderComponent;
|
|
let preRenderPriority = renderPriority;
|
|
|
|
renderPriority = node._sortingEnabled ? node._sortingPriority : renderPriority;
|
|
|
|
if(node._sortingEnabled){
|
|
// cc.log(`++ ${node.name}`);
|
|
++renderLevel;
|
|
}
|
|
// cc.log(`${renderLevel} -> ${node.name}`);
|
|
if(renderLevel > 0){
|
|
if(comp instanceof cc.Mask){
|
|
flushRendererCache();
|
|
|
|
//@ts-ignore
|
|
comp._checkBacth(_batcher, node._cullingMask);
|
|
//@ts-ignore
|
|
comp._assembler.fillBuffers(comp, _batcher);
|
|
}else{
|
|
if (_batcher.worldMatDirty && comp._assembler.updateWorldVerts) {
|
|
comp._assembler.updateWorldVerts(comp);
|
|
}
|
|
if(comp instanceof sp.Skeleton){
|
|
_batcher.worldMatDirty++;
|
|
//@ts-ignore
|
|
comp.attachUtil._syncAttachedNode();
|
|
}
|
|
rendererCache.push(comp);
|
|
comp.renderPriority = node._sortingEnabled ? node._sortingPriority : renderPriority;
|
|
if(renderPriority != 0){
|
|
rendererOrder = true;
|
|
}
|
|
}
|
|
}else{
|
|
//@ts-ignore
|
|
comp._checkBacth(_batcher, node._cullingMask);
|
|
//@ts-ignore
|
|
comp._assembler.fillBuffers(comp, _batcher);
|
|
}
|
|
this._next._func(node);
|
|
|
|
if(node._sortingEnabled){
|
|
// cc.log(`-- ${node.name}`);
|
|
--renderLevel;
|
|
if(renderLevel <= 0){
|
|
flushRendererCache();
|
|
}
|
|
}
|
|
renderPriority = preRenderPriority;
|
|
|
|
};
|
|
|
|
//@ts-ignore
|
|
cc.RenderFlow.prototype._postRender = function (node) {
|
|
let comp = node._renderComponent;
|
|
if(comp instanceof cc.Mask){
|
|
flushRendererCache();
|
|
}
|
|
comp._checkBacth(_batcher, node._cullingMask);
|
|
comp._assembler.postFillBuffers(comp, _batcher);
|
|
this._next._func(node);
|
|
};
|
|
|
|
//@ts-ignore
|
|
cc.RenderFlow.prototype._children = function (node) {
|
|
let cullingMask = _cullingMask;
|
|
let batcher = _batcher;
|
|
|
|
let parentOpacity = batcher.parentOpacity;
|
|
let opacity = (batcher.parentOpacity *= (node._opacity / 255));
|
|
|
|
if(!node._renderComponent && node._sortingEnabled){
|
|
// cc.log(`++ ${node.name}`);
|
|
++renderLevel;
|
|
}
|
|
|
|
//@ts-ignore
|
|
let worldTransformFlag = batcher.worldMatDirty ? cc.RenderFlow.FLAG_WORLD_TRANSFORM : 0;
|
|
//@ts-ignore
|
|
let worldOpacityFlag = batcher.parentOpacityDirty ? cc.RenderFlow.FLAG_OPACITY_COLOR : 0;
|
|
let worldDirtyFlag = worldTransformFlag | worldOpacityFlag;
|
|
|
|
let children = node._children;
|
|
for (let i = 0, l = children.length; i < l; i++) {
|
|
let c = children[i];
|
|
|
|
// Advance the modification of the flag to avoid node attribute modification is invalid when opacity === 0.
|
|
c._renderFlag |= worldDirtyFlag;
|
|
if (!c._activeInHierarchy || c._opacity === 0) continue;
|
|
|
|
_cullingMask = c._cullingMask = c.groupIndex === 0 ? cullingMask : 1 << c.groupIndex;
|
|
|
|
// TODO: Maybe has better way to implement cascade opacity
|
|
let colorVal = c._color._val;
|
|
c._color._fastSetA(c._opacity * opacity);
|
|
// @ts-ignore
|
|
cc.RenderFlow.flows[c._renderFlag]._func(c);
|
|
c._color._val = colorVal;
|
|
}
|
|
|
|
batcher.parentOpacity = parentOpacity;
|
|
|
|
this._next._func(node);
|
|
|
|
if(!node._renderComponent && node._sortingEnabled){
|
|
// cc.log(`-- ${node.name}`);
|
|
--renderLevel;
|
|
if(renderLevel <= 0){
|
|
flushRendererCache();
|
|
}
|
|
}
|
|
};
|