SortingGroup组件可以应用于当前节点或者其子节点上的UI渲染器

This commit is contained in:
lujun
2023-02-08 00:33:52 +08:00
parent a120d33b79
commit d4658cabc6
17 changed files with 2597 additions and 239 deletions

View File

@@ -0,0 +1,71 @@
import { director, Layers, misc, utils } from "cc";
import { MeshRenderer } from "cc";
import { profiler } from "cc";
import { CCObject } from "cc";
import { game } from "cc";
import { Material } from "cc";
import { Profiler } from "cc";
import { Node } from "cc";
import { JSB } from "cc/env";
const _constants = {
fontSize: 23,
quadHeight: 0.4,
segmentsPerLine: 8,
textureWidth: 256,
textureHeight: 256,
};
if(JSB){
//@ts-ignore
const Node_ctor = Node.prototype._ctor;
//@ts-ignore
Node.prototype._ctor = function (name?: string) {
Node_ctor.call(this, name);
const sharedArrayBuffer = this._getSharedArrayBufferObject();
// Uint32Array with 3 elements: eventMask, layer, dirtyFlags
this._sharedUint32Arr = new Uint32Array(sharedArrayBuffer, 0, 3);
// Int32Array with 1 element: siblingIndex
this._sharedInt32Arr = new Int32Array(sharedArrayBuffer, 12, 1);
// uiSortingPriority
this._sharedFloatArr = new Float32Array(sharedArrayBuffer, 16, 1);
// Uint8Array with 3 elements: activeInHierarchy, active, static, uiSortingEnabled
this._sharedUint8Arr = new Uint8Array(sharedArrayBuffer, 20, 4);
this._sharedUint32Arr[1] = Layers.Enum.DEFAULT; // this._sharedUint32Arr[1] is layer
};
Object.defineProperty(Node.prototype, 'uiSortingEnabled', {
configurable: true,
enumerable: true,
get (): Readonly<Boolean> {
return this._sharedUint8Arr[3] != 0; // Uint8, 1: active
},
set (v) {
this._sharedUint8Arr[3] = (v ? 1 : 0); // Uint8, 1: active
},
});
Object.defineProperty(Node.prototype, 'uiSortingPriority', {
configurable: true,
enumerable: true,
get (): Readonly<number> {
return this._sharedFloatArr[0];
},
set (v) {
this._sharedFloatArr[0] = v;
},
});
// 左下角调试节点创建过早,重新创建
//@ts-ignore
if (profiler._rootNode && profiler._rootNode.isValid){
//@ts-ignore
profiler._rootNode.destroy();
//@ts-ignore
profiler._rootNode = null;
profiler.generateNode();
}
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fa9757e8-0812-47bb-b2cd-658d631f676a",
"uuid": "29c6a480-4d9e-413e-8a39-0f0f9a59a19c",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -1,141 +0,0 @@
/**
* 由于RenderEntity未暴露所以修改就只有另辟蹊径
*/
import { Graphics } from "cc";
import { UIRenderer } from "cc";
import { TiledLayer } from "cc";
import { UIMeshRenderer } from "cc";
import { __private,dragonBones,sp } from "cc";
import { JSB } from "cc/env";
import { DEFAULT_SORTING_PRIORITY } from "../sorting-define";
export enum RenderEntityFloatSharedBufferView {
localOpacity,
sortingPriority,
count,
}
export enum RenderEntityUInt8SharedBufferView {
colorR,
colorG,
colorB,
colorA,
maskMode,
count,
}
export enum RenderEntityBoolSharedBufferView {
colorDirty,
enabled,
useLocal,
count,
}
/**
* RenderEntity类
*/
let RenderEntityClass:typeof __private._cocos_2d_renderer_render_entity__RenderEntity = null;
/**
* 更新RenderEntity实体
*/
export function UpdateRenderEntity(renderEntity:__private._cocos_2d_renderer_render_entity__RenderEntity){
if(renderEntity && !RenderEntityClass){
RenderEntityClass = renderEntity.constructor as typeof __private._cocos_2d_renderer_render_entity__RenderEntity;
// @ts-ignore
RenderEntityClass.prototype.initSharedBuffer = function(){
this._sortingPriority = DEFAULT_SORTING_PRIORITY;
if (JSB) {
//this._sharedBuffer = new Float32Array(RenderEntitySharedBufferView.count);
const buffer = this._nativeObj.getEntitySharedBufferForJS();
let offset = 0;
this._floatSharedBuffer = new Float32Array(buffer, offset, RenderEntityFloatSharedBufferView.count);
offset += RenderEntityFloatSharedBufferView.count * 4;
this._uint8SharedBuffer = new Uint8Array(buffer, offset, RenderEntityUInt8SharedBufferView.count);
offset += RenderEntityUInt8SharedBufferView.count * 1;
this._boolSharedBuffer = new Uint8Array(buffer, offset, RenderEntityBoolSharedBufferView.count);
}
};
if(!('sortingPriority' in RenderEntityClass.prototype)){
Object.defineProperty(RenderEntityClass.prototype, 'sortingPriority', {
get: function() {
return this._sortingPriority;
},
set: function(value) {
this._sortingPriority = value;
// console.log(`JSB sortingPriority ${value}`);
if (JSB) {
this._floatSharedBuffer[RenderEntityFloatSharedBufferView.sortingPriority] = value;
}
},
enumerable: true
});
}
// @ts-ignore
renderEntity.initSharedBuffer();
console.log('Update RenderEntity Class');
}
}
// @ts-ignore
const Graphics_createRenderEntity = Graphics.prototype.createRenderEntity;
// @ts-ignore
Graphics.prototype.createRenderEntity = function(){
let entity = Graphics_createRenderEntity.call(this);
UpdateRenderEntity(entity);
return entity;
}
const UIMeshRenderer_onLoad = UIMeshRenderer.prototype.onLoad;
UIMeshRenderer.prototype.onLoad = function(){
UpdateRenderEntity(this._renderEntity);
return UIMeshRenderer_onLoad.call(this);
}
// @ts-ignore
const UIRenderer_createRenderEntity = UIRenderer.prototype.createRenderEntity;
// @ts-ignore
UIRenderer.prototype.createRenderEntity = function(){
let entity = UIRenderer_createRenderEntity.call(this);
UpdateRenderEntity(entity);
return entity;
}
if(dragonBones){
// @ts-ignore
const ArmatureDisplay_createRenderEntity = dragonBones.ArmatureDisplay.prototype.createRenderEntity;
// @ts-ignore
dragonBones.ArmatureDisplay.prototype.createRenderEntity = function(){
let entity = ArmatureDisplay_createRenderEntity.call(this);
UpdateRenderEntity(entity);
return entity;
}
}
if(sp){
// @ts-ignore
const Skeleton_createRenderEntity = sp.Skeleton.prototype.createRenderEntity;
// @ts-ignore
sp.Skeleton.prototype.createRenderEntity = function(){
let entity = Skeleton_createRenderEntity.call(this);
UpdateRenderEntity(entity);
return entity;
}
}
if(TiledLayer){
// @ts-ignore
const TiledLayer_createRenderEntity = TiledLayer.prototype.createRenderEntity;
// @ts-ignore
TiledLayer.prototype.createRenderEntity = function(){
let entity = TiledLayer_createRenderEntity.call(this);
UpdateRenderEntity(entity);
return entity;
}
}

View File

@@ -4,31 +4,13 @@ declare module 'cc' {
interface UIRenderer {
/**
* 排序优先级 - private
* 渲染优先级
*/
_sortingPriority:number;
renderPriority:number;
/**
* 排序优先级
* 渲染透明度
*/
sortingPriority:number;
/**
* 排序透明度
*/
sortingOpacity:number;
renderOpacity:number;
}
}
if(!('sortingPriority' in UIRenderer.prototype)){
Object.defineProperty(UIRenderer.prototype, 'sortingPriority', {
get: function() {
return this._sortingPriority;
},
set: function(value) {
this._sortingPriority = value;
this._renderEntity.sortingPriority = value;
},
enumerable: true
});
}

View File

@@ -0,0 +1,55 @@
import { UITransform } from "cc";
import { JSB } from "cc/env";
declare module 'cc' {
interface UITransform {
/**
* 排序优先级 - private
*/
_sortingPriority:number;
/**
* 排序优先级
*/
sortingPriority:number;
/**
* 排序优使能 - private
*/
_sortingEnabled:boolean;
/**
* 排序优使能
*/
sortingEnabled:boolean;
}
}
if(!('sortingPriority' in UITransform.prototype)){
Object.defineProperty(UITransform.prototype, 'sortingPriority', {
get: function() {
return this._sortingPriority;
},
set: function(value) {
this._sortingPriority = value;
if(JSB){
this.node.uiSortingPriority = value;
}
},
enumerable: true
});
Object.defineProperty(UITransform.prototype, 'sortingEnabled', {
get: function() {
return this._sortingEnabled;
},
set: function(value) {
this._sortingEnabled = value;
if(JSB){
this.node.uiSortingEnabled = value;
}
},
enumerable: true
});
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "421d8e4a-74d5-4851-a739-de22c13f87e3",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,6 +1,5 @@
import { clamp, gfx,Node,RenderData,UI,StencilManager,UIRenderer, renderer } from 'cc';
import { JSB } from 'cc/env';
import { DEFAULT_SORTING_PRIORITY } from '../sorting-define';
declare module 'cc' {
interface UI {
@@ -64,14 +63,14 @@ UI.prototype.flushRendererCache = function(){
const rendererCache = this.rendererCache;
if(rendererCache.length > 0){
if(this.rendererOrder){
rendererCache.sort((a, b)=>{ return a._sortingPriority - b._sortingPriority; });
rendererCache.sort((a, b)=>{ return a.renderPriority - b.renderPriority; });
}
// console.log(`flushRendererCache ${rendererCache.length}`);
for(let render of rendererCache){
// console.log(`${render.node.name} render hash ${render.renderData.dataHash}`);
render.fillBuffers(this);
if(render.sortingOpacity >= 0){
updateOpacity(render.renderData, render.sortingOpacity);
if(render.renderOpacity >= 0){
updateOpacity(render.renderData, render.renderOpacity);
const buffer = render.renderData.getMeshBuffer();
if (buffer) {
buffer.setDirty();
@@ -126,7 +125,7 @@ UI.prototype.update = function() {
}
}
UI.prototype.walk = function(node: Node, level = 0){
UI.prototype.walk = function(node: Node, level = 0, sortingPriority = 0){
if (!node.activeInHierarchy) {
return;
}
@@ -134,6 +133,8 @@ UI.prototype.walk = function(node: Node, level = 0){
const uiProps = node._uiProps;
const render = uiProps.uiComp as UIRenderer;
const stencilEnterLevel = render && (render.stencilStage === _cocos_2d_renderer_stencil_manager__Stage.ENTER_LEVEL || render.stencilStage === _cocos_2d_renderer_stencil_manager__Stage.ENTER_LEVEL_INVERTED);
const transform = uiProps.uiTransformComp;
sortingPriority = (transform && transform._sortingEnabled) ? transform._sortingPriority : sortingPriority;
// Save opacity
const parentOpacity = this._pOpacity;
@@ -167,14 +168,14 @@ UI.prototype.walk = function(node: Node, level = 0){
}
}else{
this.rendererCache.push(render);
render._sortingPriority = render._sortingPriority ?? DEFAULT_SORTING_PRIORITY;
if(render._sortingPriority != DEFAULT_SORTING_PRIORITY){
render.renderPriority = sortingPriority;
if(sortingPriority != 0){
this.rendererOrder = true;
}
if (this._opacityDirty && render && !render.useVertexOpacity && render.renderData && render.renderData.vertexCount > 0) {
render.sortingOpacity = opacity;
render.renderOpacity = opacity;
}else{
render.sortingOpacity = -1;
render.renderOpacity = -1;
}
}
}
@@ -182,7 +183,7 @@ UI.prototype.walk = function(node: Node, level = 0){
if (children.length > 0 && !node._static) {
for (let i = 0; i < children.length; ++i) {
const child = children[i];
this.walk(child, level);
this.walk(child, level, sortingPriority);
}
}