let _batcher; let _cullingMask = 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){ 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; 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); } rendererCache.push(comp); comp.renderPriority = node._sortingEnabled ? node._sortingPriority : renderPriority; if(renderPriority != 0){ rendererOrder = true; } } this._next._func(node); }; //@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 preRenderPriority = renderPriority; let parentOpacity = batcher.parentOpacity; let opacity = (batcher.parentOpacity *= (node._opacity / 255)); renderPriority = node._sortingEnabled ? node._sortingPriority : renderPriority; // console.log(`${node.name} ${renderPriority}`); //@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; renderPriority = preRenderPriority; this._next._func(node); };