123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- //*//
- import { BaseRenderData, Director, Game, Material, MotionStreak, Node, ParticleSystem2D, Sprite, SpriteFrame, StencilManager, TiledLayer, TransformBit, UIRenderer, VERSION, __private, assert, cclegacy, director, game, gfx, murmurhash2_32_gc, renderer, resources } from 'cc';
- import { DEBUG, EDITOR, JSB } from 'cc/env';
- export const MultBatch2D: any = {
- enable: false,
- parent: null,
- textures: [],
- incID:0,
- count:0,
- hash: 0,
- reset: function () {
- // this.textures.length = 0;
- this.incID+=this.count;
- this.count = 0;
- }
- };
- const loadMultTextures = function () {
- MultBatch2D.enable = false; //提前加载多纹理材质
- resources.load("multTextures/Mult-material", Material, (err, material) => {
- if (!err) {
- let mat = cclegacy.builtinResMgr.get('ui-sprite-material');
- if (mat) {
- MultBatch2D.hash = Material.getHash(mat);
- MultBatch2D.parent = material;
- MultBatch2D.enable = true;
- material.addRef();
- }
- }
- });
- }
- let _cacheUseCount: number = 0;
- let _cacheMaterials: Array<Material> = [];
- //@ts-ignore
- Material.prototype.isMultTextures = false;
- const getMultMaterial = function (oldMat: any) {
- MultBatch2D.reset();
- if (!MultBatch2D.enable ||
- !oldMat || !oldMat.isMultTextures) {
- return oldMat;
- }
- if (!MultBatch2D.parent
- || !MultBatch2D.parent.isValid) {
- loadMultTextures();
- return oldMat;
- }
- //if (!MultBatch2D.enable) return null;
- let newMat: any = _cacheMaterials[_cacheUseCount++];
- if (!newMat || !newMat.isValid) {
- const material = { parent: MultBatch2D.parent };
- newMat = new renderer.MaterialInstance(material);
- _cacheMaterials[_cacheUseCount - 1] = newMat;
- newMat['isMultTextures'] = true;
- newMat['cacheTextures'] = [-1];
- newMat.addRef();
- }
- return newMat;
- }
- //如果有异常组件,或者自定义组件,
- //在这进行添加排除,不参与多纹理合批
- const excludeMaterial = function (uir: UIRenderer, material: any) {
- if (!material) return;
- let enable: boolean = true;
- if (enable && TiledLayer) {
- enable = !(uir instanceof TiledLayer);
- }
- if (enable && MotionStreak) {
- enable = !(uir instanceof MotionStreak);
- }
- if (enable && ParticleSystem2D) {
- enable = !(uir instanceof ParticleSystem2D);
- }
- material['isMultTextures'] = false;
- if (enable && MultBatch2D.hash == material.hash) {
- material['isMultTextures'] = true;
- }
- }
- game.once(Game.EVENT_GAME_INITED, () => {
- if (EDITOR || JSB) return;
- loadMultTextures();
- const UIR: any = UIRenderer.prototype;
- const updateMaterial: any = UIR.updateMaterial;
- UIR.updateMaterial = function () {
- updateMaterial.call(this); //this.getSharedMaterial(0);
- excludeMaterial(this, this.customMaterial || this.material);
- }
- });
- game.once(Game.EVENT_ENGINE_INITED, () => {
- if (EDITOR || JSB) return;
- director.on(Director.EVENT_AFTER_DRAW, (dt) => {
- _cacheUseCount = 0;
- MultBatch2D.reset();
- });
- const RenderData = cclegacy.UI.RenderData.prototype;
- RenderData.texID = -1;
- RenderData.isSpr = false;
- RenderData.texDirty = true;
- RenderData.dataDirty = 0x0;
- RenderData.updateHash = function() {
- if(this.material && this.material.isMultTextures){
- const bid = this.chunk ? this.chunk.bufferId : 100000;
- this.dataHash = bid*1000000000 + this.layer;
- this.hashDirty = false;
- }else{
- const bid = this.chunk ? this.chunk.bufferId : -1;
- const hashString = `${bid}${this.layer} ${this.textureHash}`;
- this.dataHash = murmurhash2_32_gc(hashString, 666);
- this.hashDirty = false;
- }
- }
- Object.defineProperty(RenderData, "vertDirty", {
- get: function () {
- return this._vertDirty;
- },
- set: function (val: boolean) {
- this._vertDirty = val;
- if (val === true && !this.isSpr) {
- this.dataDirty |= 1;
- }
- if (this._renderDrawInfo && val) {
- this._renderDrawInfo.setVertDirty(val);
- }
- }
- });
- Object.defineProperty(RenderData, "textureDirty", {
- get: function () {
- return this.texDirty;
- },
- set: function (val: boolean) {
- this.texDirty = val;
- if (val === true) {
- this.texID = -1;
- }
- }
- });
- let str = (VERSION.concat());
- str = str.replace('.','').replace('.','');
- if( parseInt( str ) < 384) { //修复 renderManager
- const UIR: any = UIRenderer.prototype;
- const markForUpdateRenderData = UIR.markForUpdateRenderData;
- UIR.markForUpdateRenderData = function(enable = true){
- markForUpdateRenderData.call(this,enable);
- if(enable && this.renderData) {
- if(!this.renderData.isSpr)
- this.renderData.dataDirty |= 2;
- }
- }
- const updateRenderer = UIR.updateRenderer;
- UIR.updateRenderer = function(){
- updateRenderer.call(this);
- if(this.renderData){
- if(!this.renderData.isSpr)
- this.renderData.dataDirty &=(~2);
- }
-
- }
- }
- let SPRA: any = cclegacy.UI.spriteAssembler;
- if (SPRA) {
- const spriteAssembler = SPRA.getAssembler;
- SPRA.getAssembler = function (sprite: Sprite) {
- const spr = spriteAssembler.call(this, sprite);
- if(spr.changeUV == undefined){
- spr.changeUV = function(s:any){
- let rd = s.renderData;
- if(rd){
- rd.dataDirty = 1;
- rd.isSpr = true;
- }
- };
- const UVs = spr.updateUVs;
- if(UVs){
- if(sprite.type == Sprite.Type.FILLED &&
- sprite.fillType != Sprite.FillType.RADIAL){
- spr.updateUVs = function(s: any, f0: number, f1: number){
- UVs.call(this,s,f0,f1);
- this.changeUV(s);
- }
- }else{
- spr.updateUVs = function(s:any){
- UVs.call(this,s);
- this.changeUV(s);
- }
- }
-
- }
-
- const verUV = spr.updateWorldVertexAndUVData;
- if(verUV){
- spr.updateWorldVertexAndUVData = function(s:any, c:any){
- verUV.call(this,s, c);
- this.changeUV(s);
- }
- }
- }
-
- return spr;
- }
- }
- cclegacy.internal.Batcher2D.prototype.cacheTextures = [];
- cclegacy.internal.Batcher2D.prototype.currMaterial = null;
- cclegacy.internal.Batcher2D.prototype.isMultTextures = false;
- Object.defineProperty(cclegacy.internal.Batcher2D.prototype, "_currMaterial", {
- get: function () {
- return this.currMaterial;
- },
- set: function (metrial: any) {
- if (this.currMaterial === metrial) return;
- this.currMaterial = getMultMaterial(metrial);
- if (MultBatch2D.enable) {
- this.isMultTextures = false;
- if (this.currMaterial && this.currMaterial.isMultTextures) {
- this.cacheTextures = this.currMaterial.cacheTextures;
- this.isMultTextures = true;
- }
- }
- }
- });
- const MAX_TEX = 8;
- const _texture = {
- texture: new cclegacy.SimpleTexture(),
- defalut: new cclegacy.SimpleTexture(),
- setFrame(frame: any) {
- this.texture['_gfxSampler'] = frame.getGFXSampler();
- this.texture['_gfxTextureView'] = frame.getGFXTexture();
- }
- };
- //@ts-ignore
- gfx.Texture.prototype['texID'] = -1;
- const Stage_ENTER_LEVEL = 2;
- const Stage_ENTER_LEVEL_INVERTED = 6;
- //@ts-ignore
- type TextureBase = __private._cocos_asset_assets_texture_base__TextureBase;
- cclegacy.internal.Batcher2D.prototype.commitComp = function (comp: UIRenderer, renderData: BaseRenderData | null, frame: TextureBase | SpriteFrame | null, assembler: any, transform: Node | null) {
- let dataHash = 0;
- let mat: any;
- let bufferID = -1;
- if (renderData && renderData.chunk) {
- if (!renderData.isValid()) return;
- dataHash = renderData.dataHash;
- mat = renderData.material;
- bufferID = renderData.chunk.bufferId;
- }
- // Notice: A little hack, if it is for mask, not need update here, while control by stencilManger
- if (comp.stencilStage === Stage_ENTER_LEVEL || comp.stencilStage === Stage_ENTER_LEVEL_INVERTED) {
- this._insertMaskBatch(comp);
- } else {
- comp.stencilStage = StencilManager.sharedManager!.stage;
- }
- const depthStencilStateStage = comp.stencilStage;
- let texID = -1;
- let texture = null;
- let MB = MultBatch2D;
- let flushBatch = false;
- let isMultTextures = false;
- // let textures = MB.textures;
- if ( MB.enable && mat && mat.isMultTextures) {
- if(frame && frame.isValid)
- texture = frame.getGFXTexture();
- if (texture) {
- isMultTextures = true;
- //@ts-ignore
- texID = texture.texID - MB.incID;
- flushBatch = texID < 0 && MB.count >= MAX_TEX;
- if(this.isMultTextures) mat = this._currMaterial;
- }
- }
- if (flushBatch
- || this._currHash !== dataHash || dataHash === 0 || this._currMaterial !== mat
- || this._currDepthStencilStateStage !== depthStencilStateStage) {
- // Merge all previous data to a render batch, and update buffer for next render data
- this.autoMergeBatches(this._currComponent!);
- if (renderData && !renderData._isMeshBuffer) {
- this.updateBuffer(renderData.vertexFormat, bufferID);
- }
- texID = -1;
- this._currRenderData = renderData;
- this._currHash = renderData ? renderData.dataHash : 0;
- this._currComponent = comp;
- this._currTransform = transform;
- this._currMaterial = comp.getRenderMaterial(0)!;
- this._currDepthStencilStateStage = depthStencilStateStage;
- this._currLayer = comp.node.layer;
- if (frame) {
- if (DEBUG) {
- assert(frame.isValid, 'frame should not be invalid, it may have been released');
- }
- this._currTexture = frame.getGFXTexture();
- this._currSampler = frame.getGFXSampler();
- this._currTextureHash = frame.getHash();
- this._currSamplerHash = this._currSampler.hash;
- } else {
- this._currTexture = null;
- this._currSampler = null;
- this._currTextureHash = 0;
- this._currSamplerHash = 0;
- }
- }
- assembler.fillBuffers(comp, this);
- if (isMultTextures) {
- if (texID < 0 || MB.count === 0) { //|| MB.count === 0
-
- texID = MB.count++;
- //@ts-ignore
- let id = texture.objectID;
- //@ts-ignore
- texture.texID = texID + MB.incID;
- let caches = this.cacheTextures;
- if (texID > 0 && caches[texID] !== id) {
- caches[texID] = id;
- _texture.setFrame(frame);
- const name = "texture" + texID;
- this._currMaterial.setProperty(name, _texture.texture);
- }
- }
- this._fillDatas(renderData, texID);
- }
- }
- cclegacy.internal.Batcher2D.prototype["_fillDatas"] = function (renderData: any, texID: number) {
- if (!renderData) return;
- let uvX = 0;
- let vbuf = renderData.chunk.vb;
- if (renderData.dataDirty == 1) {
- renderData.dataDirty = 0;
- for (let i = 0, length = vbuf.length; i < length; i += 9) {
- uvX = ~~(vbuf[i + 3] * 100000);
- vbuf[i + 3] = uvX * 10 + texID;
- }
- } else {
- if (renderData.texID != texID) {
- for (let i = 0, length = vbuf.length; i < length; i += 9) {
- uvX = ~~(vbuf[i + 3] * 0.1);
- vbuf[i + 3] = uvX * 10 + texID;
- }
- }
- }
- renderData.texID = texID;
- };
- });
- //*/
|