不再将 patches 存到仓库

This commit is contained in:
SmallMain 2022-07-06 00:03:30 +08:00
parent 746d9ce5cd
commit 48dfcac341
17 changed files with 1 additions and 6299 deletions

View File

@ -18,7 +18,6 @@
- `extension` 引擎扩展
- `docs` 存放着文档网站源码,使用 Docusaurus 开发。
- `demo` 存放着 Cocos Creator 演示项目源码。
- `patches` 存放着所有引擎改动的 Git Patch。
## 发布新版本
@ -37,7 +36,7 @@
### 准备压缩包
1.将对 engine 的改动整合到 Git Patch然后将 Patch 按相应的引擎目录放置在仓库的 `patches` 目录中,并放在压缩包根目录内。
1.将对 engine 的改动整合到 Git Patch然后将 Patch 按相应的引擎目录放置在 `patches` 目录并放在压缩包根目录内。
2.编译 JavaScript 引擎和原生模拟器,再将三个引擎目录放到压缩包根目录内,包括类型提示文件。
3.将 `service-pack-support` 目录放在压缩包根目录内。
4.更新文档的更新日志。

View File

@ -1,24 +0,0 @@
From e18df36c0f2a9f01ea59ad82e927881a0ee6727f Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 10:09:44 +0800
Subject: [PATCH 01/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC?=
=?UTF-8?q?=E5=8F=B7=E8=AF=86=E5=88=AB=E6=96=87=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/VERSION | 1 +
1 file changed, 1 insertion(+)
create mode 100644 engine/VERSION
diff --git a/engine/VERSION b/engine/VERSION
new file mode 100644
index 0000000..3eefcb9
--- /dev/null
+++ b/engine/VERSION
@@ -0,0 +1 @@
+1.0.0
--
2.32.0 (Apple Git-132)

View File

@ -1,30 +0,0 @@
From 18ced62a549cad18aba00938d10a86d7ec06fc0d Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 10:16:01 +0800
Subject: [PATCH 02/16] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E8=BE=93?=
=?UTF-8?q?=E5=87=BA=E4=B8=AD=E5=A2=9E=E5=8A=A0=20=E2=80=9CSP=E2=80=9D=20?=
=?UTF-8?q?=E6=A0=87=E8=AF=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/CCGame.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/engine/cocos2d/core/CCGame.js b/engine/cocos2d/core/CCGame.js
index c7ca11e..dec82da 100644
--- a/engine/cocos2d/core/CCGame.js
+++ b/engine/cocos2d/core/CCGame.js
@@ -390,7 +390,7 @@ var game = {
this._setAnimFrame();
cc.assetManager.builtins.init(() => {
// Log engine version
- console.log('Cocos Creator v' + cc.ENGINE_VERSION);
+ console.log('Cocos Creator SP v' + cc.ENGINE_VERSION);
this._prepared = true;
this._runMainLoop();
--
2.32.0 (Apple Git-132)

View File

@ -1,111 +0,0 @@
From 5adb675810523f2c136f1e157bbdaf28d8bd3dfc Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 10:17:09 +0800
Subject: [PATCH 03/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Effect=20=E4=BF=AE?=
=?UTF-8?q?=E6=94=B9=E5=90=8E=EF=BC=8C=E5=85=B6=E5=8F=98=E4=BD=93=20hash?=
=?UTF-8?q?=20=E5=80=BC=E4=B8=8D=E4=BC=9A=E5=88=B7=E6=96=B0=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/assets/material/effect-base.ts | 7 +++++++
engine/cocos2d/core/assets/material/effect-variant.ts | 8 +++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/engine/cocos2d/core/assets/material/effect-base.ts b/engine/cocos2d/core/assets/material/effect-base.ts
index 578f27d..69c98fa 100644
--- a/engine/cocos2d/core/assets/material/effect-base.ts
+++ b/engine/cocos2d/core/assets/material/effect-base.ts
@@ -4,6 +4,7 @@ const gfx = cc.gfx;
export default class EffectBase {
_dirty = true;
+ _dirtyCode = 0;
_name = '';
get name () {
@@ -54,6 +55,7 @@ export default class EffectBase {
}
this._dirty = true;
+ this._dirtyCode++;
return Pass.prototype.setProperty.call(pass, name, value, directly);
}
@@ -132,6 +134,7 @@ export default class EffectBase {
passes[i].setCullMode(cullMode);
}
this._dirty = true;
+ this._dirtyCode++;
}
setDepth (depthTest, depthWrite, depthFunc, passIdx) {
@@ -144,6 +147,7 @@ export default class EffectBase {
passes[i].setDepth(depthTest, depthWrite, depthFunc);
}
this._dirty = true;
+ this._dirtyCode++;
}
setBlend (enabled, blendEq, blendSrc, blendDst, blendAlphaEq, blendSrcAlpha, blendDstAlpha, blendColor, passIdx) {
@@ -162,6 +166,7 @@ export default class EffectBase {
);
}
this._dirty = true;
+ this._dirtyCode++;
}
setStencilEnabled (stencilTest = gfx.STENCIL_INHERIT, passIdx) {
@@ -174,6 +179,7 @@ export default class EffectBase {
passes[i].setStencilEnabled(stencilTest);
}
this._dirty = true;
+ this._dirtyCode++;
}
setStencil (enabled, stencilFunc, stencilRef, stencilMask, stencilFailOp, stencilZFailOp, stencilZPassOp, stencilWriteMask, passIdx) {
@@ -188,6 +194,7 @@ export default class EffectBase {
pass.setStencilBack(enabled, stencilFunc, stencilRef, stencilMask, stencilFailOp, stencilZFailOp, stencilZPassOp, stencilWriteMask);
}
this._dirty = true;
+ this._dirtyCode++;
}
}
diff --git a/engine/cocos2d/core/assets/material/effect-variant.ts b/engine/cocos2d/core/assets/material/effect-variant.ts
index 5623ed1..1b4b134 100644
--- a/engine/cocos2d/core/assets/material/effect-variant.ts
+++ b/engine/cocos2d/core/assets/material/effect-variant.ts
@@ -11,6 +11,7 @@ export default class EffectVariant extends EffectBase {
_passes: Pass[] = [];
_stagePasses = {};
_hash = 0;
+ _effectDirtyCode = 0;
get effect () {
return this._effect;
@@ -66,15 +67,16 @@ export default class EffectVariant extends EffectBase {
}
- getHash () {
- if (!this._dirty) return this._hash;
+ getHash() {
+ let effect = this._effect;
+ if (!this._dirty && (!effect || this._effectDirtyCode === effect._dirtyCode)) return this._hash;
this._dirty = false;
let hash = '';
hash += utils.serializePasses(this._passes);
- let effect = this._effect;
if (effect) {
+ this._effectDirtyCode = effect._dirtyCode;
hash += utils.serializePasses(effect.passes);
}
--
2.32.0 (Apple Git-132)

View File

@ -1,568 +0,0 @@
From 6816546edb39321714e08ad5332995dfabdc6f03 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 10:31:13 +0800
Subject: [PATCH 04/16] =?UTF-8?q?sp=E3=80=81=E5=A4=9A=E7=BA=B9=E7=90=86?=
=?UTF-8?q?=E6=B8=B2=E6=9F=93=20-=20=E5=9F=BA=E7=A1=80=E6=A0=B8=E5=BF=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/asset-manager/builtins.js | 44 +++++-
engine/cocos2d/core/assets/CCTexture2D.js | 43 +++++-
.../core/assets/material/CCMaterial.js | 36 +++++
engine/cocos2d/core/index.js | 2 +
engine/cocos2d/core/sp/index.js | 3 +
engine/cocos2d/core/sp/multi-batcher.ts | 74 +++++++++
engine/cocos2d/core/sp/multi-handler.ts | 146 ++++++++++++++++++
engine/cocos2d/core/sp/sp.js | 86 +++++++++++
8 files changed, 432 insertions(+), 2 deletions(-)
create mode 100644 engine/cocos2d/core/sp/index.js
create mode 100644 engine/cocos2d/core/sp/multi-batcher.ts
create mode 100644 engine/cocos2d/core/sp/multi-handler.ts
create mode 100644 engine/cocos2d/core/sp/sp.js
diff --git a/engine/cocos2d/core/asset-manager/builtins.js b/engine/cocos2d/core/asset-manager/builtins.js
index ae8cca7..f794369 100644
--- a/engine/cocos2d/core/asset-manager/builtins.js
+++ b/engine/cocos2d/core/asset-manager/builtins.js
@@ -80,10 +80,52 @@ var builtins = {
}
this._loadBuiltins('effect', () => {
- this._loadBuiltins('material', cb);
+ this._loadBuiltins('material', () => {
+ this._loadBuiltinsSP(cb);
+ });
+ });
+ },
+
+ _loadBuiltinsSP(cb) {
+ cc.sp.MAX_MULTITEXTURE_NUM = 8;
+ // cc.renderer.device.caps.maxTextureUnits
+
+ this._loadMultiEffect('multi-2d-sprite', (effect) => {
+ cc.sp.multi2dSpriteEffectAsset = effect;
+ effect.addRef();
+ cc.sp.inited = true;
+ cc.sp.multiBatcher.init();
+
+ cb();
});
},
+ _loadMultiEffect(name, cb) {
+ if (CC_EDITOR) {
+ cc.assetManager.loadAny(Editor.assetdb.remote.urlToUuid('db://service-pack-resources/sp/effects/' + name + '.effect'), function (err, effect) {
+ if (err) {
+ return Editor.error(err);
+ } else {
+ cb(effect);
+ }
+ });
+ } else {
+ cc.assetManager.loadBundle('sp', (err, bundle) => {
+ if (err) {
+ cc.error(err);
+ } else {
+ bundle.load('effects/' + name, cc.EffectAsset, (err, effect) => {
+ if (err) {
+ cc.error(err);
+ } else {
+ cb(effect);
+ }
+ });
+ }
+ });
+ }
+ },
+
/**
* !#en
* Get the built-in asset using specific type and name.
diff --git a/engine/cocos2d/core/assets/CCTexture2D.js b/engine/cocos2d/core/assets/CCTexture2D.js
index 3863538..e823c45 100644
--- a/engine/cocos2d/core/assets/CCTexture2D.js
+++ b/engine/cocos2d/core/assets/CCTexture2D.js
@@ -470,6 +470,9 @@ var Texture2D = cc.Class({
if (CC_EDITOR) {
this._exportedExts = null;
}
+
+ // multi batcher
+ this._multiMaterial = null;
},
/**
@@ -688,6 +691,8 @@ var Texture2D = cc.Class({
}
this._packable && cc.dynamicAtlasManager && cc.dynamicAtlasManager.deleteAtlasTexture(this);
+ this.unlinkMaterial();
+
this._image = null;
this._texture && this._texture.destroy();
this._super();
@@ -1050,7 +1055,43 @@ var Texture2D = cc.Class({
else {
cb();
}
- }
+ },
+
+ linkMaterial(material, index) {
+ const handler = material.getMultiHandler();
+ if (handler) {
+ if (index == null) {
+ if (handler.autoSetTexture(this) === -1) {
+ return false;
+ }
+ } else {
+ handler.setTexture(index, this);
+ }
+ this.unlinkMaterial();
+ this._multiMaterial = material;
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ unlinkMaterial() {
+ if (this._multiMaterial) {
+ const handler = this._multiMaterial.getMultiHandler();
+ const _texture = this.getImpl();
+ handler.removeTexture(_texture);
+ this._multiMaterial = null;
+ }
+ },
+
+ getLinkedMaterial() {
+ return this._multiMaterial;
+ },
+
+ hasLinkedMaterial() {
+ return !!this._multiMaterial;
+ },
+
});
/**
diff --git a/engine/cocos2d/core/assets/material/CCMaterial.js b/engine/cocos2d/core/assets/material/CCMaterial.js
index e0249b3..2251347 100644
--- a/engine/cocos2d/core/assets/material/CCMaterial.js
+++ b/engine/cocos2d/core/assets/material/CCMaterial.js
@@ -72,6 +72,7 @@ let Material = cc.Class({
this._manualHash = false;
this._dirty = true;
this._effect = null;
+ this._multiHandler = null;
},
properties: {
@@ -124,6 +125,8 @@ let Material = cc.Class({
}
this._effect = this._effectAsset.getInstantiatedEffect();
+
+ this.updateMultiSupport();
}
},
@@ -140,6 +143,7 @@ let Material = cc.Class({
set (v) {
this._techniqueIndex = v;
this._effect.switchTechnique(v);
+ this.updateMultiSupport();
}
}
},
@@ -401,7 +405,39 @@ let Material = cc.Class({
}
}
+ this.updateMultiSupport();
+ if (this._multiHandler) this._multiHandler.syncTextures();
+ },
+
+ updateMultiSupport() {
+ const passes = this._effect.technique.passes;
+ if (passes.length > 0 && passes[0].getDefine("USE_MULTI_TEXTURE")) {
+ this.setMultiSupport(true);
+ } else {
+ this.setMultiSupport(false);
+ }
},
+
+ isMultiSupport() {
+ return !!this._multiHandler;
+ },
+
+ setMultiSupport(bool) {
+ if (bool) {
+ if (this._multiHandler) {
+ this._multiHandler.syncTextures();
+ } else {
+ this._multiHandler = new cc.sp.MultiHandler(this);
+ }
+ } else if (!bool) {
+ this._multiHandler = null;
+ }
+ },
+
+ getMultiHandler() {
+ return this._multiHandler;
+ },
+
});
export default Material;
diff --git a/engine/cocos2d/core/index.js b/engine/cocos2d/core/index.js
index d7e79d1..a0eda10 100644
--- a/engine/cocos2d/core/index.js
+++ b/engine/cocos2d/core/index.js
@@ -40,6 +40,8 @@ if (!CC_EDITOR || !Editor.isMainProcess) {
require('./physics');
require('./camera/CCCamera');
require('./geom-utils');
+
+ require('./sp');
}
require('./mesh');
diff --git a/engine/cocos2d/core/sp/index.js b/engine/cocos2d/core/sp/index.js
new file mode 100644
index 0000000..fa17f6f
--- /dev/null
+++ b/engine/cocos2d/core/sp/index.js
@@ -0,0 +1,3 @@
+require('./sp');
+require('./multi-handler');
+require('./multi-batcher');
diff --git a/engine/cocos2d/core/sp/multi-batcher.ts b/engine/cocos2d/core/sp/multi-batcher.ts
new file mode 100644
index 0000000..dd18ab2
--- /dev/null
+++ b/engine/cocos2d/core/sp/multi-batcher.ts
@@ -0,0 +1,74 @@
+import { MultiHandler } from "./multi-handler";
+
+
+/**
+ * 多纹理合批器
+ */
+export class MultiBatcher {
+
+ /**
+ * 多纹理材质管理器数组
+ */
+ handlers: MultiHandler[] = [];
+
+ /**
+ * 有空槽的材质
+ */
+ nextHandler!: MultiHandler;
+
+
+ /**
+ * 初始化
+ */
+ init() {
+ const handler = new MultiHandler();
+ this.handlers.push(handler);
+ this.nextHandler = handler;
+ }
+
+
+ /**
+ * 传入 cc.Texture2D会关联并返回一个多纹理材质如果已经有关联的材质则会返回已关联的材质
+ */
+ requsetMaterial(texture: any) {
+ if (!texture._multiMaterial) {
+ let handler = this.nextHandler;
+ let index = handler.getEmptyIndex();
+ if (index === -1) {
+ // 没有空位,尝试在已有 handlers 里查找
+ for (const _handler of this.handlers) {
+ index = _handler.getEmptyIndex();
+ if (index !== -1) {
+ handler = _handler;
+ this.nextHandler = handler;
+ break;
+ }
+ }
+
+ // 已有的没有空位,创建新材质
+ if (index === -1) {
+ handler = new MultiHandler();
+ this.handlers.push(handler);
+ this.nextHandler = handler;
+ index = 0;
+ }
+ }
+
+ texture.linkMaterial(handler.material, index);
+ }
+ return texture._multiMaterial;
+ }
+
+
+ /**
+ * 重置多纹理材质数组,再次使用请先初始化
+ */
+ reset() {
+ this.handlers.length = 0;
+ }
+
+}
+
+
+cc.sp.multiBatcher = new MultiBatcher();
+cc.sp.MultiBatcher = MultiBatcher;
diff --git a/engine/cocos2d/core/sp/multi-handler.ts b/engine/cocos2d/core/sp/multi-handler.ts
new file mode 100644
index 0000000..664876e
--- /dev/null
+++ b/engine/cocos2d/core/sp/multi-handler.ts
@@ -0,0 +1,146 @@
+/**
+ * 多纹理 Material 管理类
+ */
+export class MultiHandler {
+
+ /**
+ * 材质
+ */
+ material: any;
+
+ /**
+ * Texture 数组
+ *
+ * 注意:不是 cc.Texture2D
+ */
+ protected textures: any[] = [];
+
+ /**
+ * 有空槽(缓存值,并不是完全正确,只是为了降低当材质没有空槽时避免数组遍历的性能消耗)
+ */
+ protected hasEmptySlot: boolean = false;
+
+
+ constructor(material?) {
+ if (material) {
+ this.material = material;
+ } else {
+ this.material = (cc.Material as any).create(cc.sp.multi2dSpriteEffectAsset);
+ this.material.name = "multi-2d-sprite";
+ this.material.define('USE_TEXTURE', true);
+ this.material.define('USE_MULTI_TEXTURE', true);
+ }
+ this.material._multiHandler = this;
+ this.syncTextures();
+ }
+
+
+ /**
+ * 同步 Material 的纹理插槽数据
+ *
+ * 当自行设置插槽可调用此函数同步数组
+ */
+ syncTextures() {
+ const effect = this.material['effect'];
+ const properties = effect.passes[0]._properties;
+
+ this.textures[0] = properties.texture.value;
+ this.textures[1] = properties.texture2.value;
+ this.textures[2] = properties.texture3.value;
+ this.textures[3] = properties.texture4.value;
+ this.textures[4] = properties.texture5.value;
+ this.textures[5] = properties.texture6.value;
+ this.textures[6] = properties.texture7.value;
+ this.textures[7] = properties.texture8.value;
+
+ // refresh has empty slot state
+ this.hasEmptySlot = true;
+ this.getEmptyIndex();
+ }
+
+
+ /**
+ * 设置纹理插槽(提供 cc.Texture2D
+ */
+ setTexture(index: number, texture: any) {
+ this.textures[index] = texture ? texture.getImpl() : null;
+ this.material.setProperty(cc.sp.propertyIndex2Name(index), texture);
+ if (texture == null) this.hasEmptySlot = true;
+ }
+
+
+ /**
+ * 移除指定纹理
+ *
+ * 注意:不是 cc.Texture2D
+ */
+ removeTexture(texture: any) {
+ const index = this.getIndex(texture);
+ if (index !== -1) {
+ this.setTexture(index, null);
+ }
+ }
+
+
+ /**
+ * 纹理是否在插槽中
+ *
+ * 注意:不是 cc.Texture2D
+ */
+ hasTexture(texture: any) {
+ return this.textures.indexOf(texture) !== -1;
+ }
+
+
+ /**
+ * 获取纹理在插槽中的 Index没有返回 -1
+ *
+ * 注意:不是 cc.Texture2D
+ */
+ getIndex(texture: any) {
+ return this.textures.indexOf(texture);
+ }
+
+
+ /**
+ * 获取指定 index 中的纹理
+ *
+ * 注意:不是 cc.Texture2D
+ */
+ getTexture(index: number) {
+ return this.textures[index];
+ }
+
+
+ /**
+ * 获取空插槽 Index没有返回 -1
+ */
+ getEmptyIndex() {
+ if (!this.hasEmptySlot) return -1;
+ const index = this.textures.indexOf(null);
+ if (index !== -1) {
+ return index;
+ } else {
+ this.hasEmptySlot = false;
+ return -1;
+ }
+ }
+
+
+ /**
+ * 自动设置纹理到空插槽,返回插槽下标,失败返回 -1提供 cc.Texture2D
+ */
+ autoSetTexture(texture: any) {
+ const index = this.getEmptyIndex();
+ if (index === -1) {
+ return -1;
+ }
+
+ this.setTexture(index, texture);
+ return index;
+ }
+
+}
+
+
+cc.sp.MultiHandler = MultiHandler;
diff --git a/engine/cocos2d/core/sp/sp.js b/engine/cocos2d/core/sp/sp.js
new file mode 100644
index 0000000..956a003
--- /dev/null
+++ b/engine/cocos2d/core/sp/sp.js
@@ -0,0 +1,86 @@
+cc.sp = {
+
+ /**
+ * 是否初始化完成
+ */
+ inited: false,
+
+ /**
+ * 版本号
+ */
+ version: "1.0.0",
+
+ /**
+ * 最大纹理插槽数量
+ *
+ * 固定为 8
+ */
+ MAX_MULTITEXTURE_NUM: -1,
+
+ /**
+ * 渲染组件是否默认自动切换至贴图关联的材质
+ */
+ autoSwitchMaterial: true,
+
+ /**
+ * 渲染组件是否默认参与动态合图
+ */
+ allowDynamicAtlas: true,
+
+ /**
+ * Label 组件是否默认启用渲染时进行缩放以适配高 DPI 屏幕
+ */
+ enableLabelRetina: true,
+
+ /**
+ * Label 组件渲染时进行缩放的缩放比例
+ */
+ labelRetinaScale: 1,
+
+ /**
+ * Char 图集会进行自动多纹理合批的数量
+ */
+ charAtlasAutoBatchCount: 1,
+
+ /**
+ * Char 图集是否在场景切换时清空
+ */
+ charAtlasAutoResetBeforeSceneLoad: true,
+
+ /**
+ * 内置的多纹理合批 Effect Asset
+ */
+ multi2dSpriteEffectAsset: null,
+
+ /**
+ * property index to name map
+ */
+ i2nMap: ['texture'],
+
+ /**
+ * property name to index map
+ */
+ n2iMap: { texture: 0 },
+
+ /**
+ * property index to name
+ */
+ propertyIndex2Name(index) {
+ return this.i2nMap[index];
+ },
+
+ /**
+ * property name to index
+ */
+ propertyName2Index(name) {
+ return this.n2iMap[name];
+ },
+
+};
+
+// 初始化
+for (let i = 1; i < 8; i++) {
+ const name = "texture" + (i + 1);
+ cc.sp.i2nMap[i] = name;
+ cc.sp.n2iMap[name] = i;
+}
--
2.32.0 (Apple Git-132)

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +0,0 @@
From a5b45a75b5507abc8c7a7c48bea9587fd7ef4f00 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 11:42:39 +0800
Subject: [PATCH 07/16] =?UTF-8?q?RichText=20=E6=94=AF=E6=8C=81=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=9D=90=E8=B4=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/components/CCRichText.js | 62 ++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/engine/cocos2d/core/components/CCRichText.js b/engine/cocos2d/core/components/CCRichText.js
index 160184a..cc13266 100644
--- a/engine/cocos2d/core/components/CCRichText.js
+++ b/engine/cocos2d/core/components/CCRichText.js
@@ -351,6 +351,46 @@ let RichText = cc.Class({
}
},
+ /**
+ * 自定义内部使用的材质
+ */
+ customMaterial: {
+ default: null,
+ type: cc.Material,
+ notify: function (oldValue) {
+ if (this.customMaterial === oldValue) return;
+ const material = this.customMaterial == null ? this._getDefaultMaterial() : this.customMaterial;
+ for (let i = 0; i < this._labelSegments.length; i++) {
+ const labelComponent = this._labelSegments[i].getComponent(cc.Label);
+ if (labelComponent) {
+ if (labelComponent._materials.length === 0) {
+ labelComponent._materials[0] = MaterialVariant.create(material, labelComponent);
+ } else {
+ labelComponent.setMaterial(0, material);
+ }
+ }
+ const spriteComponent = this._labelSegments[i].getComponent(cc.Sprite);
+ if (spriteComponent) {
+ if (spriteComponent._materials.length === 0) {
+ spriteComponent._materials[0] = MaterialVariant.create(material, spriteComponent);
+ } else {
+ spriteComponent.setMaterial(0, material);
+ }
+ }
+ }
+ for (let i = 0; i < this._labelSegmentsCache.length; i++) {
+ const labelComponent = this._labelSegmentsCache[i].getComponent(cc.Label);
+ if (labelComponent) {
+ if (labelComponent._materials.length === 0) {
+ labelComponent._materials[0] = MaterialVariant.create(material, labelComponent);
+ } else {
+ labelComponent.setMaterial(0, material);
+ }
+ }
+ }
+ }
+ },
+
autoSwitchMaterial: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
@@ -711,6 +751,17 @@ let RichText = cc.Class({
spriteComponent.autoSwitchMaterial = this.autoSwitchMaterial;
spriteComponent.allowDynamicAtlas = this.allowDynamicAtlas;
+ // 更新材质
+ if (this.customMaterial) {
+ if (spriteComponent._materials.length === 0) {
+ spriteComponent._materials[0] = MaterialVariant.create(this.customMaterial, spriteComponent);
+ } else {
+ if (spriteComponent._materials[0].material !== this.customMaterial) {
+ spriteComponent.setMaterial(0, this.customMaterial);
+ }
+ }
+ }
+
switch (richTextElement.style.imageAlign)
{
case 'top':
@@ -1006,6 +1057,17 @@ let RichText = cc.Class({
labelComponent.autoSwitchMaterial = this.autoSwitchMaterial;
labelComponent.allowDynamicAtlas = this.allowDynamicAtlas;
+ // 更新材质
+ if (this.customMaterial) {
+ if (labelComponent._materials.length === 0) {
+ labelComponent._materials[0] = MaterialVariant.create(this.customMaterial, labelComponent);
+ } else {
+ if (labelComponent._materials[0].material !== this.customMaterial) {
+ labelComponent.setMaterial(0, this.customMaterial);
+ }
+ }
+ }
+
let isAsset = this.font instanceof cc.Font;
if (isAsset && !this._isSystemFontUsed) {
labelComponent.font = this.font;
--
2.32.0 (Apple Git-132)

View File

@ -1,275 +0,0 @@
From f73ec2f9660d3bdf6bc809bccf42c1ebbb132778 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 11:45:33 +0800
Subject: [PATCH 08/16] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=AB=98=20DPI=20?=
=?UTF-8?q?=E6=B8=B2=E6=9F=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/components/CCLabel.js | 7 +++
engine/cocos2d/core/components/CCRichText.js | 21 +++++++++
.../core/renderer/utils/label/bmfont.js | 25 ++++++++++-
.../cocos2d/core/renderer/utils/label/ttf.js | 43 +++++++++++++++----
.../webgl/assemblers/label/2d/bmfont.js | 5 +++
.../renderer/webgl/assemblers/label/2d/ttf.js | 7 +--
6 files changed, 96 insertions(+), 12 deletions(-)
diff --git a/engine/cocos2d/core/components/CCLabel.js b/engine/cocos2d/core/components/CCLabel.js
index 013968b..d5116cc 100644
--- a/engine/cocos2d/core/components/CCLabel.js
+++ b/engine/cocos2d/core/components/CCLabel.js
@@ -587,6 +587,13 @@ let Label = cc.Class({
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
},
+ enableRetina: {
+ type: RenderComponent.EnableType,
+ default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ this.setVertsDirty();
+ }
+ },
},
statics: {
diff --git a/engine/cocos2d/core/components/CCRichText.js b/engine/cocos2d/core/components/CCRichText.js
index cc13266..7e0c254 100644
--- a/engine/cocos2d/core/components/CCRichText.js
+++ b/engine/cocos2d/core/components/CCRichText.js
@@ -438,6 +438,26 @@ let RichText = cc.Class({
}
}
},
+
+ enableRetina: {
+ type: RenderComponent.EnableType,
+ default: RenderComponent.EnableType.GLOBAL,
+ notify: function (oldValue) {
+ if (this.enableRetina === oldValue) return;
+ for (let i = 0; i < this._labelSegments.length; i++) {
+ const labelComponent = this._labelSegments[i].getComponent(cc.Label);
+ if (labelComponent) {
+ labelComponent.enableRetina = this.enableRetina;
+ }
+ }
+ for (let i = 0; i < this._labelSegmentsCache.length; i++) {
+ const labelComponent = this._labelSegmentsCache[i].getComponent(cc.Label);
+ if (labelComponent) {
+ labelComponent.enableRetina = this.enableRetina;
+ }
+ }
+ }
+ },
},
statics: {
@@ -1056,6 +1076,7 @@ let RichText = cc.Class({
labelComponent.autoSwitchMaterial = this.autoSwitchMaterial;
labelComponent.allowDynamicAtlas = this.allowDynamicAtlas;
+ labelComponent.enableRetina = this.enableRetina;
// 更新材质
if (this.customMaterial) {
diff --git a/engine/cocos2d/core/renderer/utils/label/bmfont.js b/engine/cocos2d/core/renderer/utils/label/bmfont.js
index 57951a5..9568825 100644
--- a/engine/cocos2d/core/renderer/utils/label/bmfont.js
+++ b/engine/cocos2d/core/renderer/utils/label/bmfont.js
@@ -75,6 +75,8 @@ let _isWrapText = false;
let _labelWidth = 0;
let _labelHeight = 0;
let _maxLineWidth = 0;
+let _isRetina = false;
+let _retinaScale = 1;
export default class BmfontAssembler extends Assembler2D {
updateRenderData (comp) {
@@ -110,6 +112,12 @@ export default class BmfontAssembler extends Assembler2D {
this._updateContent();
this.updateWorldVerts(comp);
+ if (_isRetina) {
+ _contentSize.width /= _retinaScale;
+ _contentSize.height /= _retinaScale;
+ _fontSize /= _retinaScale;
+ }
+
_comp._actualFontSize = _fontSize;
_comp.node.setContentSize(_contentSize);
@@ -137,8 +145,14 @@ export default class BmfontAssembler extends Assembler2D {
shareLabelInfo.margin = 0;
}
+ getTTFTextureSizeScale() {
+ return _isRetina ? _retinaScale : 1;
+ }
+
_updateProperties (comp) {
_string = comp.string.toString();
+ _isRetina = !(comp.font instanceof cc.BitmapFont) && (cc.sp.enableLabelRetina && comp.enableRetina === 0) || comp.enableRetina === 1;
+ _retinaScale = cc.sp.labelRetinaScale;
_fontSize = comp.fontSize;
_originFontSize = _fntConfig ? _fntConfig.fontSize : comp.fontSize;
_hAlign = comp.horizontalAlign;
@@ -150,6 +164,15 @@ export default class BmfontAssembler extends Assembler2D {
_contentSize.width = comp.node.width;
_contentSize.height = comp.node.height;
+ if (_isRetina) {
+ _fontSize *= _retinaScale;
+ if (!_fntConfig) _originFontSize *= _retinaScale;
+ _contentSize.width *= _retinaScale;
+ _contentSize.height *= _retinaScale;
+ _lineHeight *= _retinaScale;
+ shareLabelInfo.margin *= _retinaScale;
+ }
+
// should wrap text
if (_overflow === Overflow.NONE) {
_isWrapText = false;
@@ -706,4 +729,4 @@ export default class BmfontAssembler extends Assembler2D {
_quadsUpdated (comp) {}
_reserveQuads () {}
-}
\ No newline at end of file
+}
diff --git a/engine/cocos2d/core/renderer/utils/label/ttf.js b/engine/cocos2d/core/renderer/utils/label/ttf.js
index 49d90fa..f5f8232 100644
--- a/engine/cocos2d/core/renderer/utils/label/ttf.js
+++ b/engine/cocos2d/core/renderer/utils/label/ttf.js
@@ -55,6 +55,8 @@ let _fontFamily = '';
let _overflow = Overflow.NONE;
let _isWrapText = false;
let _premultiply = false;
+let _isRetina = false;
+let _retinaScale = 1;
// outline
let _outlineComp = null;
@@ -115,6 +117,12 @@ export default class TTFAssembler extends Assembler2D {
}
_updateRenderData(comp) {
+ if (_isRetina) {
+ _fontSize /= _retinaScale;
+ _nodeContentSize.width /= _retinaScale;
+ _nodeContentSize.height /= _retinaScale;
+ }
+
comp._actualFontSize = _fontSize;
comp.node.setContentSize(_nodeContentSize);
@@ -127,6 +135,10 @@ export default class TTFAssembler extends Assembler2D {
_texture = null;
}
+ getTTFTextureSizeScale() {
+ return _isRetina ? _retinaScale : 1;
+ }
+
updateVerts () {
}
@@ -136,6 +148,9 @@ export default class TTFAssembler extends Assembler2D {
_contentSizeExtend.width = _contentSizeExtend.height = 0;
if (_outlineComp) {
outlineWidth = _outlineComp.width;
+ if (_isRetina) {
+ outlineWidth *= _retinaScale;
+ }
top = bottom = left = right = outlineWidth;
_contentSizeExtend.width = _contentSizeExtend.height = outlineWidth * 2;
}
@@ -164,15 +179,27 @@ export default class TTFAssembler extends Assembler2D {
_canvas = assemblerData.canvas;
_texture = comp._frame._original ? comp._frame._original._texture : comp._frame._texture;
+ _isRetina = (cc.sp.enableLabelRetina && comp.enableRetina === 0) || comp.enableRetina === 1;
+ _retinaScale = cc.sp.labelRetinaScale;
_string = comp.string.toString();
_fontSize = comp._fontSize;
+ _nodeContentSize = comp.node.getContentSize();
+ _lineHeight = comp._lineHeight;
_drawFontSize = _fontSize;
_underlineThickness = comp.underlineHeight || _drawFontSize / 8;
+
+ if (_isRetina) {
+ _fontSize *= _retinaScale;
+ _nodeContentSize.width *= _retinaScale;
+ _nodeContentSize.height *= _retinaScale;
+ _lineHeight *= _retinaScale;
+ if (comp.underlineHeight) _underlineThickness *= _retinaScale;
+ _drawFontSize = _fontSize;
+ }
+
_overflow = comp.overflow;
- _canvasSize.width = comp.node.width;
- _canvasSize.height = comp.node.height;
- _nodeContentSize = comp.node.getContentSize();
- _lineHeight = comp._lineHeight;
+ _canvasSize.width = _nodeContentSize.width;
+ _canvasSize.height = _nodeContentSize.height;
_hAlign = comp.horizontalAlign;
_vAlign = comp.verticalAlign;
_color = comp.node.color;
@@ -248,14 +275,14 @@ export default class TTFAssembler extends Assembler2D {
_setupOutline () {
_context.strokeStyle = `rgba(${_outlineColor.r}, ${_outlineColor.g}, ${_outlineColor.b}, ${_outlineColor.a / 255})`;
- _context.lineWidth = _outlineComp.width * 2;
+ _context.lineWidth = _outlineComp.width * 2 * (_isRetina ? _retinaScale : 1);
}
_setupShadow () {
_context.shadowColor = `rgba(${_shadowColor.r}, ${_shadowColor.g}, ${_shadowColor.b}, ${_shadowColor.a / 255})`;
- _context.shadowBlur = _shadowComp.blur;
- _context.shadowOffsetX = _shadowComp.offset.x;
- _context.shadowOffsetY = -_shadowComp.offset.y;
+ _context.shadowBlur = _shadowComp.blur * (_isRetina ? _retinaScale : 1);
+ _context.shadowOffsetX = _shadowComp.offset.x * (_isRetina ? _retinaScale : 1);
+ _context.shadowOffsetY = -_shadowComp.offset.y * (_isRetina ? _retinaScale : 1);
}
_drawTextEffect (startPosition, lineHeight) {
diff --git a/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js b/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js
index ac90d01..be7d330 100644
--- a/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js
+++ b/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js
@@ -121,6 +121,11 @@ export default class WebglBmfontAssembler extends BmfontAssembler {
// positions
+ const retinaScale = this.getTTFTextureSizeScale();
+ x /= retinaScale;
+ y /= retinaScale;
+ rectWidth /= retinaScale;
+ rectHeight /= retinaScale;
l = x;
r = x + rectWidth * scale;
b = y - rectHeight * scale;
diff --git a/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/ttf.js b/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/ttf.js
index e073440..e34d1f6 100644
--- a/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/ttf.js
+++ b/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/ttf.js
@@ -49,10 +49,11 @@ export default class WebglTTFAssembler extends TTFAssembler {
super.updateColor(comp, color);
}
- updateVerts (comp) {
+ updateVerts(comp) {
+ const scale = this.getTTFTextureSizeScale();
let node = comp.node,
- canvasWidth = comp._ttfTexture.width,
- canvasHeight = comp._ttfTexture.height,
+ canvasWidth = comp._ttfTexture.width / scale,
+ canvasHeight = comp._ttfTexture.height / scale,
appx = node.anchorX * node.width,
appy = node.anchorY * node.height;
--
2.32.0 (Apple Git-132)

View File

@ -1,619 +0,0 @@
From 29ab0105fffc4316b06eab3e4834e5675b730259 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 11:55:32 +0800
Subject: [PATCH 09/16] =?UTF-8?q?=E6=96=B0=E7=9A=84=20Char=20=E7=BC=93?=
=?UTF-8?q?=E5=AD=98=E6=A8=A1=E5=BC=8F=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/asset-manager/builtins.js | 2 +-
engine/cocos2d/core/components/CCLabel.js | 4 +
.../core/renderer/utils/label/bmfont.js | 7 +-
.../core/renderer/utils/label/letter-font.js | 397 ++++++++++++++++--
.../webgl/assemblers/label/2d/bmfont.js | 6 +-
5 files changed, 366 insertions(+), 50 deletions(-)
diff --git a/engine/cocos2d/core/asset-manager/builtins.js b/engine/cocos2d/core/asset-manager/builtins.js
index ea87ebe..668ca0f 100644
--- a/engine/cocos2d/core/asset-manager/builtins.js
+++ b/engine/cocos2d/core/asset-manager/builtins.js
@@ -95,7 +95,7 @@ var builtins = {
effect.addRef();
cc.sp.inited = true;
cc.sp.multiBatcher.init();
- if (cc.dynamicAtlasManager.maxAtlasCount === -1) cc.dynamicAtlasManager.maxAtlasCount = cc.sp.MAX_MULTITEXTURE_NUM;
+ if (cc.dynamicAtlasManager.maxAtlasCount === -1) cc.dynamicAtlasManager.maxAtlasCount = Math.max(0, cc.sp.MAX_MULTITEXTURE_NUM - cc.sp.charAtlasAutoBatchCount);
cb();
});
},
diff --git a/engine/cocos2d/core/components/CCLabel.js b/engine/cocos2d/core/components/CCLabel.js
index d5116cc..b672f23 100644
--- a/engine/cocos2d/core/components/CCLabel.js
+++ b/engine/cocos2d/core/components/CCLabel.js
@@ -483,6 +483,10 @@ let Label = cc.Class({
if (oldValue === CacheMode.CHAR) {
this._ttfTexture = null;
+ const material = this._materials[0];
+ if (material && material.material && cc.Label._shareAtlas.material === material.material) {
+ this.setMaterial(0, this._getDefaultMaterial());
+ }
}
if (!this.enabledInHierarchy) return;
diff --git a/engine/cocos2d/core/renderer/utils/label/bmfont.js b/engine/cocos2d/core/renderer/utils/label/bmfont.js
index 9568825..900c08a 100644
--- a/engine/cocos2d/core/renderer/utils/label/bmfont.js
+++ b/engine/cocos2d/core/renderer/utils/label/bmfont.js
@@ -337,6 +337,8 @@ export default class BmfontAssembler extends Assembler2D {
index += tokenLen;
} //end of for loop
+ this._finishMultilineTextWrap();
+
_linesWidth.push(letterRight);
_numberOfLines = lineIndex + 1;
@@ -636,7 +638,7 @@ export default class BmfontAssembler extends Assembler2D {
if (_tmpRect.height > 0 && _tmpRect.width > 0) {
let isRotated = this._determineRect(_tmpRect);
let letterPositionX = letterInfo.x + _linesOffsetX[letterInfo.line];
- this.appendQuad(_comp, texture, _tmpRect, isRotated, letterPositionX - appx, py - appy, _bmfontScale);
+ this.appendQuad(_comp, texture, _tmpRect, isRotated, letterPositionX - appx, py - appy, _bmfontScale, letterDef);
}
}
this._quadsUpdated(_comp);
@@ -725,8 +727,9 @@ export default class BmfontAssembler extends Assembler2D {
updateWorldVerts() {}
- appendQuad (comp, texture, rect, rotated, x, y, scale) {}
+ appendQuad(comp, texture, rect, rotated, x, y, scale, letter) {}
_quadsUpdated (comp) {}
_reserveQuads () {}
+ _finishMultilineTextWrap() { }
}
diff --git a/engine/cocos2d/core/renderer/utils/label/letter-font.js b/engine/cocos2d/core/renderer/utils/label/letter-font.js
index 5e46af0..0e7aaae 100644
--- a/engine/cocos2d/core/renderer/utils/label/letter-font.js
+++ b/engine/cocos2d/core/renderer/utils/label/letter-font.js
@@ -24,6 +24,7 @@
****************************************************************************/
import WebglBmfontAssembler from '../../webgl/assemblers/label/2d/bmfont';
+import { vfmtPosUvColorTexId } from '../../webgl/vertex-format';
const Label = require('../../../components/CCLabel');
const LabelOutline = require('../../../components/CCLabelOutline');
@@ -125,29 +126,82 @@ LetterTexture.prototype = {
},
}
-function LetterAtlas (width, height) {
+function LetterAtlas(atlases, width, height) {
let texture = new RenderTexture();
texture.initWithSize(width, height);
texture.update();
- this._fontDefDictionary = new FontAtlas(texture);
-
+ this._atlases = atlases;
+ this._texture = texture;
+ this._id = 0;
+ this._tmpId = -1;
+
this._x = space;
this._y = space;
this._nexty = space;
+ this.frees = [];
+ this.waitCleans = [];
+
this._width = width;
this._height = height;
-
- cc.director.on(cc.Director.EVENT_BEFORE_SCENE_LAUNCH, this.beforeSceneLoad, this);
}
cc.js.mixin(LetterAtlas.prototype, {
- insertLetterTexture (letterTexture) {
+ insertLetterTexture(letterTexture) {
let texture = letterTexture._texture;
- let width = texture.width, height = texture.height;
+ let width = texture.width, height = texture.height;
+
+ // 先寻找是否有可用的被回收的区域
+ if (this.frees.length > 0) {
+ let score = Number.MAX_VALUE;
+ let areaFit = 0;
+ let original = null;
+ let originalIndex = 0;
+
+ for (let i = 0; i < this.frees.length; i++) {
+ const freeLetter = this.frees[i];
+ if (freeLetter._width === width && freeLetter._height === height) {
+ areaFit = freeLetter._width * freeLetter._height - width * height;
+ if (areaFit < score) {
+ original = freeLetter;
+ originalIndex = i;
+ score = areaFit;
+ }
+ }
+ }
+
+ if (original) {
+ original._hash = letterTexture._hash;
+ original.w = letterTexture._width - bleed;
+ original.h = letterTexture._height - bleed;
+ original.xAdvance = original.w;
+ original.offsetY = letterTexture._offsetY;
+
+ this._texture.drawTextureAt(texture, original.u - bleed / 2, original.v - bleed / 2);
+
+ this._dirty = true;
+
+ this.removeFreeLetter(originalIndex);
+
+ this._atlases._fontDefDictionary.addLetterDefinitions(letterTexture._hash, original);
+ return original;
+ }
+ }
+
+ // 有 bleed 问题,暂时不能复用不同高宽的空间
+ // 矫正宽度为三档: <0.75x height <1x height >1x height
+ // if (width <= height * 0.75) {
+ // width = height * 0.75;
+ // } else if (width <= height) {
+ // width = height;
+ // }
+
+ // 没有可用的被回收区域,尝试直接插入
+ const oldx = this._x, oldy = this._y, oldnexty = this._nexty;
if ((this._x + width + space) > this._width) {
+ // TODO 跳到下一行之前将这行的剩余区域切成多个正方形并放入 frees避免浪费
this._x = space;
this._y = this._nexty;
}
@@ -157,33 +211,69 @@ cc.js.mixin(LetterAtlas.prototype, {
}
if (this._nexty > this._height) {
- return null;
+ this._x = oldx;
+ this._y = oldy;
+ this._nexty = oldnexty;
+
+ // 回收 waitCleans
+ if (this.waitCleans.length > 0) {
+ for (const letter of this.waitCleans) {
+ letter._inCleans = false;
+ if (letter.ref === 0) {
+ delete this._atlases._fontDefDictionary._letterDefinitions[letter._hash];
+ this.frees.push(letter);
+ }
+ }
+ this.waitCleans.length = 0;
+ return this.insertLetterTexture(letterTexture);
+ } else {
+ return null;
+ }
}
- this._fontDefDictionary._texture.drawTextureAt(texture, this._x, this._y);
+ this._texture.drawTextureAt(texture, this._x, this._y);
this._dirty = true;
let letter = new FontLetterDefinition();
- letter.u = this._x + bleed/2;
- letter.v = this._y + bleed/2;
- letter.texture = this._fontDefDictionary._texture;
+ letter.u = this._x + bleed / 2;
+ letter.v = this._y + bleed / 2;
+ letter.texture = this._texture;
+ letter.atlas = this;
+ letter.ref = 0;
letter.valid = true;
letter.w = letterTexture._width - bleed;
letter.h = letterTexture._height - bleed;
+ letter._inCleans = false;
+ letter._hash = letterTexture._hash;
+ letter._width = width;
+ letter._height = height;
letter.xAdvance = letter.w;
letter.offsetY = letterTexture._offsetY;
this._x += width + space;
- this._fontDefDictionary.addLetterDefinitions(letterTexture._hash, letter);
+ this._atlases._fontDefDictionary.addLetterDefinitions(letterTexture._hash, letter);
return letter
},
+ pushFreeLetter(letter) {
+ const i = this.frees.push(letter) - 1;
+ },
+
+ removeFreeLetter(index) {
+ const temp = this.frees[index];
+ const temp2 = this.frees[this.frees.length - 1];
+ // temp2.cacheIndex = index;
+ // temp.cacheIndex = -1;
+ this.frees[index] = temp2;
+ this.frees.pop();
+ },
+
update () {
if (!this._dirty) return;
- this._fontDefDictionary._texture.update();
+ this._texture.update();
this._dirty = false;
},
@@ -192,47 +282,148 @@ cc.js.mixin(LetterAtlas.prototype, {
this._y = space;
this._nexty = space;
- let chars = this._fontDefDictionary._letterDefinitions;
- for (let i = 0, l = chars.length; i < l; i++) {
- let char = chars[i];
- if (!char.isValid) {
- continue;
+ const defs = this._atlases._fontDefDictionary._letterDefinitions;
+ for (const key in defs) {
+ const def = defs[key];
+ if (def.atlas === this) {
+ delete defs[key];
}
- char.destroy();
}
- this._fontDefDictionary.clear();
+ this.frees.length = 0;
+ this.waitCleans.length = 0;
},
destroy () {
this.reset();
- this._fontDefDictionary._texture.destroy();
- this._fontDefDictionary._texture = null;
+ const handler = this._atlases.material.getMultiHandler();
+ handler.removeTexture(this._texture);
+ this._texture.destroy();
+ this._texture = null;
},
- beforeSceneLoad () {
- this.clearAllCache();
- },
+});
- clearAllCache () {
- this.destroy();
+class LetterAtlases {
+
+ /**
+ * 图集数组
+ */
+ atlases = [];
+
+ /**
+ * Char 多纹理材质
+ */
+ material = null;
+
+ /**
+ * Fake MaterialVariant
+ */
+ fakeMaterial = { material: null };
+
+ /**
+ * 抽象图集
+ */
+ _fontDefDictionary = new FontAtlas(null);
- let texture = new RenderTexture();
- texture.initWithSize(this._width, this._height);
- texture.update();
-
- this._fontDefDictionary._texture = texture;
- },
- getLetter (key) {
+ constructor() {
+ const handler = new cc.sp.MultiHandler();
+ this.material = handler.material;
+ this.fakeMaterial.material = this.material;
+
+ cc.director.on(cc.Director.EVENT_BEFORE_SCENE_LAUNCH, this.beforeSceneLoad, this);
+ }
+
+
+ insertLetterTexture(letterTexture) {
+ for (const atlas of this.atlases) {
+ const letter = atlas.insertLetterTexture(letterTexture);
+ if (letter) {
+ return letter;
+ }
+ }
+
+ if (this.atlases.length >= 8) {
+ return null;
+ } else {
+ const atlas = new LetterAtlas(this, _atlasWidth, _atlasHeight);
+ const len = this.atlases.push(atlas);
+ atlas._id = len - 1;
+ const handler = this.material.getMultiHandler();
+ handler.setTexture(atlas._id, atlas._texture);
+ if (!CC_EDITOR && cc.sp.charAtlasAutoBatchCount >= len) {
+ cc.sp.multiBatcher.requsetMaterial(atlas._texture);
+ }
+ return atlas.insertLetterTexture(letterTexture);
+ }
+ }
+
+
+ deleteLetter(letter) {
+ letter.ref--;
+ if (letter.ref === 0 && !letter._inCleans) {
+ letter._inCleans = true;
+ letter.atlas.waitCleans.push(letter);
+ }
+ }
+
+
+ update() {
+ for (const atlas of this.atlases) {
+ atlas.update();
+ }
+ }
+
+
+ reset() {
+ this._fontDefDictionary.clear();
+
+ for (const atlas of this.atlases) {
+ atlas.reset();
+ }
+ }
+
+
+ destroy() {
+ this._fontDefDictionary.clear();
+
+ for (const atlas of this.atlases) {
+ atlas.destroy();
+ }
+
+ this.atlases.length = 0;
+ }
+
+
+ beforeSceneLoad() {
+ if (cc.sp.charAtlasAutoResetBeforeSceneLoad) {
+ this.clearAllCache();
+ }
+ }
+
+
+ clearAllCache() {
+ this.reset();
+ }
+
+
+ getTexture() {
+ if (!_emptyTexture) {
+ _emptyTexture = new RenderTexture();
+ _emptyTexture.initWithSize(_atlasWidth, _atlasHeight);
+ _emptyTexture.update();
+ }
+ return _emptyTexture;
+ }
+
+
+ getLetter(key) {
return this._fontDefDictionary._letterDefinitions[key];
- },
+ }
- getTexture () {
- return this._fontDefDictionary.getTexture();
- },
- getLetterDefinitionForChar: function(char, labelInfo) {
+ getLetterDefinitionForChar(char, labelInfo) {
let hash = char.charCodeAt(0) + labelInfo.hash;
let letter = this._fontDefDictionary._letterDefinitions[hash];
if (!letter) {
@@ -242,12 +433,50 @@ cc.js.mixin(LetterAtlas.prototype, {
temp.destroy();
}
+ if (letter && _firstTraverse) {
+ letter.ref++;
+ _assembler._letterRefs.push(letter);
+ this.checkMaterialAndUpdateTexId(letter);
+ }
+
return letter;
}
-});
+
+
+ checkMaterialAndUpdateTexId(letter) {
+ const atlas = letter.atlas;
+ const comp = _assembler._renderComp;
+
+ // 检查是否需要自动切换材质
+ if (_needCheckMaterial) {
+ _needCheckMaterial = false;
+ if (_usedMaterial.material !== _shareAtlas.material) {
+ _assembler.checkAndSwitchMaterial(comp, atlas._texture, _usedMaterial);
+ _usedMaterial = comp._materials[0];
+ }
+ }
+
+ // 检查是否需要更新 atlas tmpId使用内置材质则不检查
+ if (_usedMaterial.material !== _shareAtlas.material && atlas._tmpId === -1) {
+ const handler = _usedMaterial.material.getMultiHandler();
+ if (handler) {
+ const index = handler.getIndex(atlas._texture.getImpl());
+ if (index !== -1) {
+ atlas._tmpId = index;
+ return;
+ }
+ }
+
+ // 如果无法在材质中找到 texture则切换至内置材质
+ comp.setMaterial(0, _shareAtlas.material);
+ _usedMaterial = _shareAtlas.fakeMaterial;
+ }
+ }
+
+}
function computeHash (labelInfo) {
- let hashData = '';
+ let hashData = '|';
let color = labelInfo.color.toHEX();
let out = '';
if (labelInfo.isOutlined && labelInfo.margin > 0) {
@@ -262,11 +491,31 @@ let _shareAtlas = null;
let _atlasWidth = 2048;
let _atlasHeight = 2048;
let _isBold = false;
+let _usedMaterial = null;
+let _needCheckMaterial = false;
+let _firstTraverse = false;
+let _assembler = null;
+let _emptyTexture = null;
export default class LetterFontAssembler extends WebglBmfontAssembler {
+ _letterRefs = [];
+
+ initData() {
+ let data = this._renderData;
+ data.createFlexData(0, this.verticesCount, this.indicesCount, this.getVfmt());
+ }
+
+ getVfmt() {
+ return vfmtPosUvColorTexId;
+ }
+
+ getBuffer() {
+ return cc.renderer._handle.getBuffer("mesh", this.getVfmt());
+ }
+
_getAssemblerData () {
if (!_shareAtlas) {
- _shareAtlas = new LetterAtlas(_atlasWidth, _atlasHeight);
+ _shareAtlas = new LetterAtlases();
cc.Label._shareAtlas = _shareAtlas;
}
@@ -310,4 +559,64 @@ export default class LetterFontAssembler extends WebglBmfontAssembler {
_determineRect (tempRect) {
return false;
}
-}
\ No newline at end of file
+
+ _updateRenderData(comp) {
+ // 还原 tex id 与当前使用材质
+ _assembler = this;
+ _usedMaterial = _assembler._renderComp._materials[0];
+ _needCheckMaterial = true;
+ _firstTraverse = true;
+ for (const atlas of _shareAtlas.atlases) {
+ atlas._tmpId = -1;
+ }
+
+ // 还原 letterRef
+ this._recycleLetterRef();
+
+ super._updateRenderData(comp);
+
+ _usedMaterial = null;
+ _assembler = null;
+ }
+
+ _finishMultilineTextWrap() {
+ _firstTraverse = false;
+ }
+
+ _recycleLetterRef() {
+ for (const letter of this._letterRefs) {
+ _shareAtlas.deleteLetter(letter);
+ }
+ this._letterRefs.length = 0;
+ }
+
+ _resetAssemblerData(assemblerData) {
+ if (this._letterRefs.length !== 0) {
+ this._recycleLetterRef();
+ }
+ }
+
+ appendVerts(comp, offset, l, r, b, t, letter) {
+ super.appendVerts(comp, offset, l, r, b, t, letter);
+
+ // update texId
+ const renderData = this._renderData;
+ const verts = renderData.vDatas[0];
+ const floatsPerVert = this.floatsPerVert;
+ let texIdOffset = offset + this.texIdOffset;
+ const id = _usedMaterial.material !== _shareAtlas.material ? letter.atlas._tmpId : letter.atlas._id;
+
+ verts[texIdOffset] = id;
+ texIdOffset += floatsPerVert;
+ verts[texIdOffset] = id;
+ texIdOffset += floatsPerVert;
+ verts[texIdOffset] = id;
+ texIdOffset += floatsPerVert;
+ verts[texIdOffset] = id;
+ }
+
+}
+
+LetterFontAssembler.prototype.floatsPerVert = 6;
+LetterFontAssembler.prototype.texIdOffset = 5;
+LetterFontAssembler.prototype.isMulti = true;
diff --git a/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js b/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js
index be7d330..db1904a 100644
--- a/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js
+++ b/engine/cocos2d/core/renderer/webgl/assemblers/label/2d/bmfont.js
@@ -65,7 +65,7 @@ export default class WebglBmfontAssembler extends BmfontAssembler {
return comp.node._color._val;
}
- appendQuad (comp, texture, rect, rotated, x, y, scale) {
+ appendQuad(comp, texture, rect, rotated, x, y, scale, letter) {
let renderData = this._renderData;
let verts = renderData.vDatas[0],
uintVerts = renderData.uintVDatas[0];
@@ -131,7 +131,7 @@ export default class WebglBmfontAssembler extends BmfontAssembler {
b = y - rectHeight * scale;
t = y;
- this.appendVerts(comp, _dataOffset, l, r, b, t);
+ this.appendVerts(comp, _dataOffset, l, r, b, t, letter);
// colors
let colorOffset = _dataOffset + this.colorOffset;
@@ -143,7 +143,7 @@ export default class WebglBmfontAssembler extends BmfontAssembler {
_dataOffset += this.floatsPerVert * 4;
}
- appendVerts (comp, offset, l, r, b, t) {
+ appendVerts(comp, offset, l, r, b, t, letter) {
let local = this._local;
let floatsPerVert = this.floatsPerVert;
--
2.32.0 (Apple Git-132)

View File

@ -1,799 +0,0 @@
From 311adb9248bd23ed8fe5d282b8c1aa02b5d0cfba Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 12:01:39 +0800
Subject: [PATCH 10/16] =?UTF-8?q?Spine=20=E7=BB=84=E4=BB=B6=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E5=A4=9A=E7=BA=B9=E7=90=86=E6=B8=B2=E6=9F=93=E3=80=81?=
=?UTF-8?q?=E5=8A=A8=E6=80=81=E5=9B=BE=E9=9B=86=E3=80=81=E4=B8=8E=E5=85=B6?=
=?UTF-8?q?=E5=AE=83=E7=BB=84=E4=BB=B6=E5=90=88=E6=89=B9=E3=80=81region=20?=
=?UTF-8?q?=E6=8D=A2=E8=A3=85=E5=B9=B6=E5=A2=9E=E5=8A=A0=E6=8D=A2=E8=A3=85?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=20API=20=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/assets/CCSpriteFrame.js | 1 +
.../core/renderer/webgl/mesh-buffer.js | 46 +++
engine/extensions/spine/Skeleton.js | 68 ++++-
engine/extensions/spine/lib/spine.js | 14 +-
engine/extensions/spine/skeleton-data.js | 114 ++++++-
engine/extensions/spine/spine-assembler.js | 278 ++++++++++++++----
6 files changed, 455 insertions(+), 66 deletions(-)
diff --git a/engine/cocos2d/core/assets/CCSpriteFrame.js b/engine/cocos2d/core/assets/CCSpriteFrame.js
index 37837bd..7038378 100644
--- a/engine/cocos2d/core/assets/CCSpriteFrame.js
+++ b/engine/cocos2d/core/assets/CCSpriteFrame.js
@@ -651,6 +651,7 @@ let SpriteFrame = cc.Class(/** @lends cc.SpriteFrame# */{
this._texture = this._original._texture;
this._original = null;
this._calculateUV();
+ this.emit("_resetDynamicAtlasFrame");
},
_calculateUV () {
diff --git a/engine/cocos2d/core/renderer/webgl/mesh-buffer.js b/engine/cocos2d/core/renderer/webgl/mesh-buffer.js
index f8d300f..d0a998f 100644
--- a/engine/cocos2d/core/renderer/webgl/mesh-buffer.js
+++ b/engine/cocos2d/core/renderer/webgl/mesh-buffer.js
@@ -187,6 +187,52 @@ let MeshBuffer = cc.Class({
this.requestStatic(vertexCount, indiceCount);
return this._offsetInfo;
},
+
+ requestForSpine(vertexCount, indiceCount) {
+ if (this._batcher._buffer !== this) {
+ this._batcher._flush();
+ this._batcher._buffer = this;
+ }
+
+ this.requestStaticForSpine(vertexCount, indiceCount);
+ return this._offsetInfo;
+ },
+
+ requestStaticForSpine(vertexCount, indiceCount) {
+
+ this.checkAndSwitchBuffer(vertexCount);
+
+ let byteOffset = this.byteOffset + vertexCount * this._vertexBytes;
+ let indiceOffset = this.indiceOffset + indiceCount;
+
+ let byteLength = this._vData.byteLength;
+ let indiceLength = this._iData.length;
+ if (byteOffset > byteLength || indiceOffset > indiceLength) {
+ while (byteLength < byteOffset || indiceLength < indiceOffset) {
+ this._initVDataCount *= 2;
+ this._initIDataCount *= 2;
+
+ byteLength = this._initVDataCount * 4;
+ indiceLength = this._initIDataCount;
+ }
+
+ this._reallocBuffer();
+ }
+
+ let offsetInfo = this._offsetInfo;
+ offsetInfo.vertexOffset = this.vertexOffset;
+ offsetInfo.indiceOffset = this.indiceOffset;
+ offsetInfo.byteOffset = this.byteOffset;
+ },
+
+ adjustForSpine(vertexCount, indiceCount) {
+ this.vertexOffset += vertexCount;
+ this.indiceOffset += indiceCount;
+
+ this.byteOffset = this.byteOffset + vertexCount * this._vertexBytes;
+
+ this._dirty = true;
+ },
_reallocBuffer () {
this._reallocVData(true);
diff --git a/engine/extensions/spine/Skeleton.js b/engine/extensions/spine/Skeleton.js
index da54c8c..42046fc 100644
--- a/engine/extensions/spine/Skeleton.js
+++ b/engine/extensions/spine/Skeleton.js
@@ -427,7 +427,16 @@ sp.Skeleton = cc.Class({
// Play times
_playTimes : 0,
// Is animation complete.
- _isAniComplete : true,
+ _isAniComplete: true,
+
+ autoSwitchMaterial: {
+ type: RenderComponent.EnableType,
+ default: RenderComponent.EnableType.GLOBAL,
+ },
+ allowDynamicAtlas: {
+ type: RenderComponent.EnableType,
+ default: RenderComponent.EnableType.GLOBAL,
+ },
},
// CONSTRUCTOR
@@ -443,6 +452,7 @@ sp.Skeleton = cc.Class({
this._startEntry = {animation : {name : ""}, trackIndex : 0};
this._endEntry = {animation : {name : ""}, trackIndex : 0};
this.attachUtil = new AttachUtil();
+ this._dataDirty = true;
},
// override base class _getDefaultMaterial to modify default material
@@ -455,8 +465,11 @@ sp.Skeleton = cc.Class({
let useTint = this.useTint || (this.isAnimationCached() && !CC_NATIVERENDERER);
let baseMaterial = this.getMaterial(0);
if (baseMaterial) {
- baseMaterial.define('USE_TINT', useTint);
- baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
+ const isMultiSupport = baseMaterial.material.isMultiSupport();
+ if (!isMultiSupport) {
+ baseMaterial.define('USE_TINT', useTint);
+ baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
+ }
let srcBlendFactor = this.premultipliedAlpha ? cc.gfx.BLEND_ONE : cc.gfx.BLEND_SRC_ALPHA;
let dstBlendFactor = cc.gfx.BLEND_ONE_MINUS_SRC_ALPHA;
@@ -468,6 +481,11 @@ sp.Skeleton = cc.Class({
cc.gfx.BLEND_FUNC_ADD,
dstBlendFactor, dstBlendFactor
);
+
+ if (isMultiSupport) {
+ if (this.useTint) this.useTint = false;
+ if (!this.enableBatch) this.enableBatch = true;
+ }
}
this._materialCache = {};
},
@@ -493,7 +511,11 @@ sp.Skeleton = cc.Class({
let baseMaterial = this.getMaterial(0);
if (baseMaterial) {
let useTint = this.useTint || (this.isAnimationCached() && !CC_NATIVERENDERER);
- baseMaterial.define('USE_TINT', useTint);
+ if (!baseMaterial.material.isMultiSupport()) {
+ baseMaterial.define('USE_TINT', useTint);
+ } else {
+ if (this.useTint) this.useTint = false;
+ }
}
this._materialCache = {};
},
@@ -502,7 +524,11 @@ sp.Skeleton = cc.Class({
_updateBatch () {
let baseMaterial = this.getMaterial(0);
if (baseMaterial) {
- baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
+ if (!baseMaterial.material.isMultiSupport()) {
+ baseMaterial.define('CC_USE_MODEL', !this.enableBatch);
+ } else {
+ if (!this.enableBatch) this.enableBatch = true;
+ }
}
this._materialCache = {};
},
@@ -955,6 +981,37 @@ sp.Skeleton = cc.Class({
this.invalidAnimationCache();
},
+ /**
+ * 获取 attachment 的 region
+ */
+ getRegion(slotName, attachmentName) {
+ const attachment = this.getAttachment(slotName, attachmentName);
+ if (attachment) {
+ return attachment.region;
+ }
+ return null;
+ },
+
+ /**
+ * 修改 attachment 的 region
+ */
+ setRegion(slotName, attachmentName, region) {
+ const attachment = this.getAttachment(slotName, attachmentName);
+ if (attachment) {
+ attachment.region = region;
+ if (attachment instanceof sp.spine.MeshAttachment) {
+ attachment.updateUVs();
+ } else if (attachment instanceof sp.spine.RegionAttachment) {
+ attachment.setRegion(region);
+ attachment.updateOffset();
+ }
+ this._dataDirty = true;
+ this.invalidAnimationCache();
+ return true;
+ }
+ return false;
+ },
+
/**
* Return the renderer of attachment.
* @method getTextureAtlas
@@ -1335,6 +1392,7 @@ sp.Skeleton = cc.Class({
this.attachUtil._associateAttachedNode();
this._preCacheMode = this._cacheMode;
this.animation = this.defaultAnimation;
+ this._dataDirty = true;
},
_refreshInspector () {
diff --git a/engine/extensions/spine/lib/spine.js b/engine/extensions/spine/lib/spine.js
index 857b433..fa12640 100644
--- a/engine/extensions/spine/lib/spine.js
+++ b/engine/extensions/spine/lib/spine.js
@@ -8004,7 +8004,7 @@ var spine;
RegionAttachment.prototype.setRegion = function (region) {
this.region = region;
var uvs = this.uvs;
- if (region.rotate) {
+ if (region.degrees === 90) {
uvs[2] = region.u;
uvs[3] = region.v2;
uvs[4] = region.u;
@@ -8013,8 +8013,16 @@ var spine;
uvs[7] = region.v;
uvs[0] = region.u2;
uvs[1] = region.v2;
- }
- else {
+ } else if (region.degrees === 270) {
+ uvs[6] = region.u;
+ uvs[7] = region.v2;
+ uvs[0] = region.u;
+ uvs[1] = region.v;
+ uvs[2] = region.u2;
+ uvs[3] = region.v;
+ uvs[4] = region.u2;
+ uvs[5] = region.v2;
+ } else {
uvs[0] = region.u;
uvs[1] = region.v2;
uvs[2] = region.u;
diff --git a/engine/extensions/spine/skeleton-data.js b/engine/extensions/spine/skeleton-data.js
index a7bdb10..9f233ed 100644
--- a/engine/extensions/spine/skeleton-data.js
+++ b/engine/extensions/spine/skeleton-data.js
@@ -139,6 +139,74 @@ let SkeletonData = cc.Class({
statics: {
preventDeferredLoadDependents: true,
+
+ createRegion(spriteFrame, original = undefined) {
+ const region = new sp.spine.TextureAtlasRegion();
+
+ const texture = spriteFrame.getTexture();
+ const rect = spriteFrame.getRect();
+ const origSize = spriteFrame.getOriginalSize();
+ const _offset = spriteFrame.getOffset();
+ const rotate = spriteFrame.isRotated();
+ const offset = cc.v2(
+ (origSize.width - rect.width) * 0.5 + _offset.x,
+ (origSize.height - rect.height) * 0.5 + _offset.y,
+ );
+ const degrees = rotate ? 270 : 0;
+
+ if (original) {
+ region.name = original.name;
+ region.page = original.page;
+ }
+
+ region.x = rect.x;
+ region.y = rect.y;
+ region.width = rect.width;
+ region.height = rect.height;
+ region.originalWidth = origSize.width;
+ region.originalHeight = origSize.height;
+ region.offsetX = offset.x;
+ region.offsetY = offset.y;
+ region.rotate = degrees != 0;
+ region.degrees = degrees;
+
+ const skelTex = new sp.SkeletonTexture({
+ width: texture.width,
+ height: texture.height,
+ });
+ skelTex.setRealTexture(texture);
+ region.texture = skelTex;
+
+ this.updateRegionUV(region);
+
+ return region;
+ },
+
+ updateRegionUV(region) {
+ const texture = region.texture._texture;
+ if (region.rotate) {
+ region.u = region.x / texture.width;
+ region.v = region.y / texture.height;
+ region.u2 = (region.x + region.height) / texture.width;
+ region.v2 = (region.y + region.width) / texture.height;
+ } else {
+ region.u = region.x / texture.width;
+ region.v = region.y / texture.height;
+ region.u2 = (region.x + region.width) / texture.width;
+ region.v2 = (region.y + region.height) / texture.height;
+ }
+ },
+
+ createSpriteFrame(region) {
+ const frame = new cc.SpriteFrame(
+ region.texture._texture,
+ cc.rect(region.x, region.y, region.width, region.height),
+ region.rotate, // 如果 region 不是 0 或 270 则会出现问题
+ cc.v2(region.offsetX - (region.originalWidth - region.width) * 0.5, region.offsetY - (region.originalHeight - region.height) * 0.5),
+ cc.size(region.originalWidth, region.originalHeight),
+ );
+ return frame;
+ },
},
// PUBLIC
@@ -166,6 +234,7 @@ let SkeletonData = cc.Class({
this._skinsEnum = null;
this._animsEnum = null;
}
+ this._cloneId = 0;
},
ensureTexturesLoaded (loaded, caller) {
@@ -322,7 +391,50 @@ let SkeletonData = cc.Class({
return this._atlasCache = new sp.spine.TextureAtlas(this.atlasText, this._getTexture.bind(this));
},
- destroy () {
+ /**
+ * 克隆 SkeletonData
+ */
+ clone: function () {
+ const cloned = new SkeletonData();
+ cloned._cloneId = this._cloneId + 1;
+ const suffix = '(clone ' + String(cloned._cloneId) + ')';
+ cloned._uuid = this._uuid + suffix;
+ cloned.name = this.name + suffix;
+ cloned.scale = this.scale;
+ cloned.textureNames = this.textureNames;
+ cloned.textures = this.textures;
+ cloned._atlasText = this._atlasText;
+ cloned._skeletonJson = this._skeletonJson;
+ cloned._buffer = this._buffer;
+
+ return cloned;
+ },
+
+ destroy() {
+ // 删除动态图集
+ if (this._atlasCache) {
+ const regions = this._atlasCache.regions;
+ for (const region of regions) {
+ if (region._spriteFrame) {
+ region._spriteFrame.destroy();
+ region._spriteFrame = null;
+ }
+ }
+ }
+ if (this._skeletonCache) {
+ const skins = this._skeletonCache.skins;
+ for (const skin of skins) {
+ for (const attachments of skin.attachments) {
+ for (const key in attachments) {
+ const region = attachments[key].region;
+ if (region && region._spriteFrame) {
+ region._spriteFrame.destroy();
+ region._spriteFrame = null;
+ }
+ }
+ }
+ }
+ }
SkeletonCache.removeSkeleton(this._uuid);
this._super();
},
diff --git a/engine/extensions/spine/spine-assembler.js b/engine/extensions/spine/spine-assembler.js
index 652af54..36c91f0 100644
--- a/engine/extensions/spine/spine-assembler.js
+++ b/engine/extensions/spine/spine-assembler.js
@@ -30,6 +30,7 @@ const spine = require('./lib/spine');
const RenderFlow = require('../../cocos2d/core/renderer/render-flow');
const VertexFormat = require('../../cocos2d/core/renderer/webgl/vertex-format')
const VFOneColor = VertexFormat.vfmtPosUvColor;
+const VFOneColorTexId = VertexFormat.vfmtPosUvColorTexId;
const VFTwoColor = VertexFormat.vfmtPosUvTwoColor;
const gfx = cc.gfx;
@@ -58,6 +59,8 @@ let _multiplier;
let _slotRangeStart;
let _slotRangeEnd;
let _useTint;
+let _useMulti;
+let _texId;
let _debugSlots;
let _debugBones;
let _debugMesh;
@@ -105,34 +108,67 @@ function _getSlotMaterial (tex, blendMode) {
let baseMaterial = _comp._materials[0];
if (!baseMaterial) return null;
- // The key use to find corresponding material
- let key = tex.getId() + src + dst + _useTint + useModel;
- let materialCache = _comp._materialCache;
- let material = materialCache[key];
- if (!material) {
- if (!materialCache.baseMaterial) {
- material = baseMaterial;
- materialCache.baseMaterial = baseMaterial;
- } else {
- material = cc.MaterialVariant.create(baseMaterial);
+ if (_useMulti) {
+ let key = tex.getId() + src + dst;
+ let materialCache = _comp._materialCache;
+ let materialInfo = materialCache[key];
+ if (!materialInfo) {
+ let texId = baseMaterial.material.getMultiHandler().getIndex(tex.getImpl());
+ if (!materialCache.baseMaterial) {
+ materialInfo = { material: baseMaterial, texId: texId };
+ materialCache.baseMaterial = materialInfo;
+ } else {
+ materialInfo = { material: cc.MaterialVariant.create(baseMaterial), texId: texId };
+ }
+
+ if (texId === -1) {
+ materialInfo.material.setProperty('texture', tex);
+ materialInfo.texId = 0;
+ }
+
+ // update blend function
+ materialInfo.material.setBlend(
+ true,
+ gfx.BLEND_FUNC_ADD,
+ src, dst,
+ gfx.BLEND_FUNC_ADD,
+ src, dst
+ );
+ materialCache[key] = materialInfo;
}
-
- material.define('CC_USE_MODEL', useModel);
- material.define('USE_TINT', _useTint);
- // update texture
- material.setProperty('texture', tex);
-
- // update blend function
- material.setBlend(
- true,
- gfx.BLEND_FUNC_ADD,
- src, dst,
- gfx.BLEND_FUNC_ADD,
- src, dst
- );
- materialCache[key] = material;
+ _texId = materialInfo.texId;
+ return materialInfo.material;
+ } else {
+ // The key use to find corresponding material
+ let key = tex.getId() + src + dst + _useTint + useModel;
+ let materialCache = _comp._materialCache;
+ let material = materialCache[key];
+ if (!material) {
+ if (!materialCache.baseMaterial) {
+ material = baseMaterial;
+ materialCache.baseMaterial = baseMaterial;
+ } else {
+ material = cc.MaterialVariant.create(baseMaterial);
+ }
+
+ material.define('CC_USE_MODEL', useModel);
+ material.define('USE_TINT', _useTint);
+ // update texture
+ material.setProperty('texture', tex);
+
+ // update blend function
+ material.setBlend(
+ true,
+ gfx.BLEND_FUNC_ADD,
+ src, dst,
+ gfx.BLEND_FUNC_ADD,
+ src, dst
+ );
+ materialCache[key] = material;
+ }
+
+ return material;
}
- return material;
}
function _handleColor (color) {
@@ -162,12 +198,112 @@ function _spineColorToInt32 (spineColor) {
export default class SpineAssembler extends Assembler {
updateRenderData (comp) {
if (comp.isAnimationCached()) return;
+
+ if (comp._dataDirty) {
+ // 自动合图
+ this.packDynamicAtlasForSpine(comp);
+
+ // 自动切换材质
+ const autoSwitchMaterial = comp.autoSwitchMaterial;
+ if ((cc.sp.autoSwitchMaterial && autoSwitchMaterial === 0) || autoSwitchMaterial === 1) {
+ const material = comp._materials[0];
+ if (!material) return false;
+
+ const skins = comp.skeletonData._skeletonCache.skins;
+ for (const skin of skins) {
+ for (const attachment of skin.attachments) {
+ for (const key in attachment) {
+ const region = attachment[key].region;
+ if (region && region.texture) {
+ this.checkAndSwitchMaterial(comp, region.texture._texture, material);
+ break;
+ }
+ }
+ }
+ }
+ }
+ comp._dataDirty = false;
+ }
+
let skeleton = comp._skeleton;
if (skeleton) {
skeleton.updateWorldTransform();
}
}
+ packDynamicAtlasForSpine(comp) {
+ if (CC_TEST) return false;
+
+ const allowDynamicAtlas = comp.allowDynamicAtlas;
+ if ((cc.sp.allowDynamicAtlas && allowDynamicAtlas === 0) || allowDynamicAtlas === 1) {
+ if (cc.dynamicAtlasManager) {
+ const skins = comp.skeletonData._skeletonCache.skins;
+ for (const skin of skins) {
+ for (const attachments of skin.attachments) {
+ for (const key in attachments) {
+ const attachment = attachments[key];
+ const region = attachment.region;
+ if (region && !region._original && region.texture && region.texture._texture.packable) {
+ if (region._spriteFrame) {
+ region._spriteFrame.destroy();
+ region._spriteFrame = null;
+ }
+ const frame = sp.SkeletonData.createSpriteFrame(region);
+ const packedFrame = cc.dynamicAtlasManager.insertSpriteFrame(frame);
+ if (packedFrame) {
+ frame._setDynamicAtlasFrame(packedFrame);
+
+ region._original = {
+ _texture: region.texture,
+ _x: region.x,
+ _y: region.y,
+ };
+
+ region.texture = new sp.SkeletonTexture({
+ width: packedFrame.texture.width,
+ height: packedFrame.texture.height,
+ });
+ region.texture.setRealTexture(packedFrame.texture);
+
+ region.x = packedFrame.x;
+ region.y = packedFrame.y;
+
+ // update uv
+ sp.SkeletonData.updateRegionUV(region);
+ if (attachment instanceof sp.spine.MeshAttachment) {
+ attachment.updateUVs();
+ } else {
+ attachment.setRegion(region);
+ attachment.updateOffset();
+ }
+
+ frame.once("_resetDynamicAtlasFrame", () => {
+ region.x = region._original._x;
+ region.y = region._original._y;
+ region.texture = region._original._texture;
+ region._original = null;
+
+ // update uv
+ sp.SkeletonData.updateRegionUV(region);
+ if (attachment instanceof sp.spine.MeshAttachment) {
+ attachment.updateUVs();
+ } else {
+ attachment.setRegion(region);
+ attachment.updateOffset();
+ }
+ });
+ region._spriteFrame = frame;
+ } else {
+ frame.destroy();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
fillVertices (skeletonColor, attachmentColor, slotColor, clipper, slot) {
let vbuf = _buffer._vData,
@@ -207,16 +343,24 @@ export default class SpineAssembler extends Assembler {
vbuf[v + 1] = _tempPos.y; // y
vbuf[v + 2] = _tempUv.x; // u
vbuf[v + 3] = _tempUv.y; // v
- uintVData[v + 4] = _spineColorToInt32(_finalColor); // light color
- _useTint && (uintVData[v + 5] = _spineColorToInt32(_darkColor)); // dark color
+ uintVData[v + 4] = _spineColorToInt32(_finalColor); // light color
+ if (_useMulti) {
+ vbuf[v + 5] = _texId;
+ } else {
+ _useTint && (uintVData[v + 5] = _spineColorToInt32(_darkColor)); // dark color
+ }
}
} else {
_finalColor32 = _spineColorToInt32(_finalColor);
_darkColor32 = _spineColorToInt32(_darkColor);
for (let v = _vertexFloatOffset, n = _vertexFloatOffset + _vertexFloatCount; v < n; v += _perVertexSize) {
- uintVData[v + 4] = _finalColor32; // light color
- _useTint && (uintVData[v + 5] = _darkColor32); // dark color
+ uintVData[v + 4] = _finalColor32; // light color
+ if (_useMulti) {
+ vbuf[v + 5] = _texId;
+ } else {
+ _useTint && (uintVData[v + 5] = _darkColor32); // dark color
+ }
}
}
} else {
@@ -229,7 +373,7 @@ export default class SpineAssembler extends Assembler {
_indexCount = clippedTriangles.length;
_vertexFloatCount = clippedVertices.length / _perClipVertexSize * _perVertexSize;
- offsetInfo = _buffer.request(_vertexFloatCount / _perVertexSize, _indexCount);
+ offsetInfo = _buffer.requestForSpine(_vertexFloatCount / _perVertexSize, _indexCount);
_indexOffset = offsetInfo.indiceOffset,
_vertexOffset = offsetInfo.vertexOffset,
_vertexFloatOffset = offsetInfo.byteOffset >> 2;
@@ -260,8 +404,12 @@ export default class SpineAssembler extends Assembler {
vbuf[offset + 2] = _tempUv.x; // u
vbuf[offset + 3] = _tempUv.y; // v
uintVData[offset + 4] = _spineColorToInt32(_finalColor);
- if (_useTint) {
- uintVData[offset + 5] = _spineColorToInt32(_darkColor);
+ if (_useMulti) {
+ vbuf[offset + 5] = _texId;
+ } else {
+ if (_useTint) {
+ uintVData[offset + 5] = _spineColorToInt32(_darkColor);
+ }
}
}
} else {
@@ -273,10 +421,13 @@ export default class SpineAssembler extends Assembler {
_finalColor32 = ((clippedVertices[v + 5]<<24) >>> 0) + (clippedVertices[v + 4]<<16) + (clippedVertices[v + 3]<<8) + clippedVertices[v + 2];
uintVData[offset + 4] = _finalColor32;
-
- if (_useTint) {
- _darkColor32 = ((clippedVertices[v + 11]<<24) >>> 0) + (clippedVertices[v + 10]<<16) + (clippedVertices[v + 9]<<8) + clippedVertices[v + 8];
- uintVData[offset + 5] = _darkColor32;
+ if (_useMulti) {
+ vbuf[offset + 5] = _texId;
+ } else {
+ if (_useTint) {
+ _darkColor32 = ((clippedVertices[v + 11] << 24) >>> 0) + (clippedVertices[v + 10] << 16) + (clippedVertices[v + 9] << 8) + clippedVertices[v + 8];
+ uintVData[offset + 5] = _darkColor32;
+ }
}
}
}
@@ -312,7 +463,7 @@ export default class SpineAssembler extends Assembler {
}
// x y u v r1 g1 b1 a1 r2 g2 b2 a2 or x y u v r g b a
- _perClipVertexSize = _useTint ? 12 : 8;
+ _perClipVertexSize = _useMulti ? 12 : (_useTint ? 12 : 8);
_vertexFloatCount = 0;
_vertexFloatOffset = 0;
@@ -384,7 +535,7 @@ export default class SpineAssembler extends Assembler {
_vertexFloatCount = 4 * _perVertexSize;
_indexCount = 6;
- offsetInfo = _buffer.request(4, 6);
+ offsetInfo = _buffer.requestForSpine(4, 6);
_indexOffset = offsetInfo.indiceOffset,
_vertexOffset = offsetInfo.vertexOffset,
_vertexFloatOffset = offsetInfo.byteOffset >> 2;
@@ -413,7 +564,7 @@ export default class SpineAssembler extends Assembler {
_vertexFloatCount = (attachment.worldVerticesLength >> 1) * _perVertexSize;
_indexCount = triangles.length;
- offsetInfo = _buffer.request(_vertexFloatCount / _perVertexSize, _indexCount);
+ offsetInfo = _buffer.requestForSpine(_vertexFloatCount / _perVertexSize, _indexCount);
_indexOffset = offsetInfo.indiceOffset,
_vertexOffset = offsetInfo.vertexOffset,
_vertexFloatOffset = offsetInfo.byteOffset >> 2;
@@ -485,7 +636,7 @@ export default class SpineAssembler extends Assembler {
vbuf[ii + 1] = _x * _m01 + _y * _m05 + _m13;
}
}
- _buffer.adjust(_vertexFloatCount / _perVertexSize, _indexCount);
+ _buffer.adjustForSpine(_vertexFloatCount / _perVertexSize, _indexCount);
}
clipper.clipEndWithSlot(slot);
@@ -569,7 +720,7 @@ export default class SpineAssembler extends Assembler {
_vertexCount = segInfo.vertexCount;
_indexCount = segInfo.indexCount;
- offsetInfo = _buffer.request(_vertexCount, _indexCount);
+ offsetInfo = _buffer.requestForSpine(_vertexCount, _indexCount);
_indexOffset = offsetInfo.indiceOffset;
_vertexOffset = offsetInfo.vertexOffset;
_vfOffset = offsetInfo.byteOffset >> 2;
@@ -599,19 +750,28 @@ export default class SpineAssembler extends Assembler {
}
}
- _buffer.adjust(_vertexCount, _indexCount);
- if ( !_needColor ) continue;
+ _buffer.adjustForSpine(_vertexCount, _indexCount);
- // handle color
- let frameColorOffset = frameVFOffset - segVFCount;
- for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 6, frameColorOffset += 6) {
- if (frameColorOffset >= maxVFOffset) {
- nowColor = colors[colorOffset++];
- _handleColor(nowColor);
- maxVFOffset = nowColor.vfOffset;
+ if (_needColor) {
+ // handle color
+ let frameColorOffset = frameVFOffset - segVFCount;
+ for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 6, frameColorOffset += 6) {
+ if (frameColorOffset >= maxVFOffset) {
+ nowColor = colors[colorOffset++];
+ _handleColor(nowColor);
+ maxVFOffset = nowColor.vfOffset;
+ }
+ uintbuf[ii] = _finalColor32;
+ if (_useMulti) {
+ vbuf[ii + 1] = _texId;
+ } else {
+ uintbuf[ii + 1] = _darkColor32;
+ }
+ }
+ } else if (_useMulti) {
+ for (let ii = _vfOffset + 4, il = _vfOffset + 4 + segVFCount; ii < il; ii += 6) {
+ vbuf[ii + 1] = _texId;
}
- uintbuf[ii] = _finalColor32;
- uintbuf[ii + 1] = _darkColor32;
}
}
}
@@ -628,13 +788,17 @@ export default class SpineAssembler extends Assembler {
_nodeB = nodeColor.b / 255;
_nodeA = nodeColor.a / 255;
- _useTint = comp.useTint || comp.isAnimationCached();
- _vertexFormat = _useTint? VFTwoColor : VFOneColor;
+ let baseMaterial = comp._materials[0];
+ if (!baseMaterial) return;
+
+ _useMulti = baseMaterial.material.isMultiSupport();
+ _useTint = !_useMulti && (comp.useTint || comp.isAnimationCached());
+ _vertexFormat = _useMulti ? VFOneColorTexId : (_useTint ? VFTwoColor : VFOneColor);
// x y u v color1 color2 or x y u v color
- _perVertexSize = _useTint ? 6 : 5;
+ _perVertexSize = _useMulti ? 6 :(_useTint ? 6 : 5);
_node = comp.node;
- _buffer = renderer.getBuffer('spine', _vertexFormat);
+ _buffer = renderer.getBuffer('mesh', _vertexFormat);
_renderer = renderer;
_comp = comp;
--
2.32.0 (Apple Git-132)

View File

@ -1,146 +0,0 @@
From 25a82582da7f743d769fbfb136bb4c5c9713e3e2 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 15:36:05 +0800
Subject: [PATCH 11/16] =?UTF-8?q?=E5=A4=9A=E7=BA=B9=E7=90=86=E6=B8=B2?=
=?UTF-8?q?=E6=9F=93=E3=80=81=E5=8A=A8=E6=80=81=E5=9B=BE=E9=9B=86=E5=BC=80?=
=?UTF-8?q?=E5=85=B3=E6=97=B6=E4=B8=BB=E5=8A=A8=E5=88=B7=E6=96=B0=E6=B8=B2?=
=?UTF-8?q?=E6=9F=93=E7=8A=B6=E6=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/components/CCLabel.js | 9 +++++++++
.../cocos2d/core/components/CCMotionStreak.js | 12 ++++++++++++
engine/cocos2d/core/components/CCSprite.js | 8 ++++++++
engine/extensions/spine/Skeleton.js | 18 ++++++++++++++++--
4 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/engine/cocos2d/core/components/CCLabel.js b/engine/cocos2d/core/components/CCLabel.js
index b672f23..6cbfe1b 100644
--- a/engine/cocos2d/core/components/CCLabel.js
+++ b/engine/cocos2d/core/components/CCLabel.js
@@ -586,15 +586,24 @@ let Label = cc.Class({
autoSwitchMaterial: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.autoSwitchMaterial === oldValue) return;
+ this.setVertsDirty();
+ },
},
allowDynamicAtlas: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.allowDynamicAtlas === oldValue) return;
+ this.setVertsDirty();
+ },
},
enableRetina: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
notify(oldValue) {
+ if (this.enableRetina === oldValue) return;
this.setVertsDirty();
}
},
diff --git a/engine/cocos2d/core/components/CCMotionStreak.js b/engine/cocos2d/core/components/CCMotionStreak.js
index 545c03f..7205e94 100644
--- a/engine/cocos2d/core/components/CCMotionStreak.js
+++ b/engine/cocos2d/core/components/CCMotionStreak.js
@@ -218,9 +218,21 @@ var MotionStreak = cc.Class({
autoSwitchMaterial: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.autoSwitchMaterial === oldValue) return;
+ this.setVertsDirty();
+ },
},
},
+ setVertsDirty() {
+ // 自动切换材质
+ this._checkSwitchMaterial();
+
+ this._updateMaterial();
+ this._super();
+ },
+
__preload() {
this._super();
this._checkSwitchMaterial();
diff --git a/engine/cocos2d/core/components/CCSprite.js b/engine/cocos2d/core/components/CCSprite.js
index 806a50d..45debb3 100644
--- a/engine/cocos2d/core/components/CCSprite.js
+++ b/engine/cocos2d/core/components/CCSprite.js
@@ -388,10 +388,18 @@ var Sprite = cc.Class({
autoSwitchMaterial: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.autoSwitchMaterial === oldValue) return;
+ this.setVertsDirty();
+ },
},
allowDynamicAtlas: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.allowDynamicAtlas === oldValue) return;
+ this.setVertsDirty();
+ },
},
},
diff --git a/engine/extensions/spine/Skeleton.js b/engine/extensions/spine/Skeleton.js
index 42046fc..61cde65 100644
--- a/engine/extensions/spine/Skeleton.js
+++ b/engine/extensions/spine/Skeleton.js
@@ -432,10 +432,18 @@ sp.Skeleton = cc.Class({
autoSwitchMaterial: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.autoSwitchMaterial === oldValue) return;
+ this.setVertsDirty();
+ },
},
allowDynamicAtlas: {
type: RenderComponent.EnableType,
default: RenderComponent.EnableType.GLOBAL,
+ notify(oldValue) {
+ if (this.allowDynamicAtlas === oldValue) return;
+ this.setVertsDirty();
+ },
},
},
@@ -455,6 +463,13 @@ sp.Skeleton = cc.Class({
this._dataDirty = true;
},
+ setVertsDirty() {
+ this.invalidAnimationCache();
+ this._dataDirty = true;
+ this._materialCache = {};
+ this._super();
+ },
+
// override base class _getDefaultMaterial to modify default material
_getDefaultMaterial () {
return cc.Material.getBuiltinMaterial('2d-spine');
@@ -1005,8 +1020,7 @@ sp.Skeleton = cc.Class({
attachment.setRegion(region);
attachment.updateOffset();
}
- this._dataDirty = true;
- this.invalidAnimationCache();
+ this.setVertsDirty();
return true;
}
return false;
--
2.32.0 (Apple Git-132)

View File

@ -1,47 +0,0 @@
From a0f89c84b0bfcaf32d81a621e863461eb83ace8b Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 15:36:10 +0800
Subject: [PATCH 12/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20cc.MotionStreak=20?=
=?UTF-8?q?=E9=83=A8=E5=88=86=E6=83=85=E5=86=B5=E4=B8=8B=E5=8D=A1=E6=AD=BB?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/components/CCMotionStreak.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/engine/cocos2d/core/components/CCMotionStreak.js b/engine/cocos2d/core/components/CCMotionStreak.js
index 7205e94..6e0eb3b 100644
--- a/engine/cocos2d/core/components/CCMotionStreak.js
+++ b/engine/cocos2d/core/components/CCMotionStreak.js
@@ -242,6 +242,7 @@ var MotionStreak = cc.Class({
if (this._assembler) {
const material = this._materials[0];
if (!material) return;
+ if (!this._texture) return;
this._assembler.checkAndSwitchMaterial(this, this._texture, material);
}
},
@@ -257,6 +258,7 @@ var MotionStreak = cc.Class({
// 根据材质更新 uniform
const isMultiMaterial = material.material.isMultiSupport();
if (isMultiMaterial) {
+ if (!this._texture) return;
this._updateMultiTexId(material, this._texture);
} else {
if (material.getProperty('texture') !== this._texture) {
@@ -272,7 +274,8 @@ var MotionStreak = cc.Class({
}
// texId
- if (isMultiMaterial && this._texIdDirty) {
+ if (isMultiMaterial && this._texIdDirty && this._assembler) {
+ if (!this._texture) return;
this._assembler.updateTexId(this);
this._texIdDirty = false;
}
--
2.32.0 (Apple Git-132)

View File

@ -1,134 +0,0 @@
From 6c742a9c7298f6c48d31c33c0407039a72903547 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 15:37:22 +0800
Subject: [PATCH 13/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Spine=20=E5=8D=95?=
=?UTF-8?q?=E5=8A=A8=E7=94=BB=E7=94=A8=E4=BA=86=E5=A4=9A=E4=B8=AA=E7=BA=B9?=
=?UTF-8?q?=E7=90=86=E6=97=B6=EF=BC=8C=E7=BC=93=E5=AD=98=E6=A8=A1=E5=BC=8F?=
=?UTF-8?q?=E4=B8=8B=E6=98=BE=E7=A4=BA=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE?=
=?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/extensions/spine/Skeleton.js | 10 +++++++---
engine/extensions/spine/skeleton-cache.js | 4 ++--
engine/extensions/spine/spine-assembler.js | 18 +++++++++++-------
3 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/engine/extensions/spine/Skeleton.js b/engine/extensions/spine/Skeleton.js
index 61cde65..b1eda9c 100644
--- a/engine/extensions/spine/Skeleton.js
+++ b/engine/extensions/spine/Skeleton.js
@@ -464,8 +464,8 @@ sp.Skeleton = cc.Class({
},
setVertsDirty() {
- this.invalidAnimationCache();
this._dataDirty = true;
+ this.invalidAnimationCache();
this._materialCache = {};
this._super();
},
@@ -702,6 +702,8 @@ sp.Skeleton = cc.Class({
if (this.isAnimationCached()) {
+ this._assembler.handleDynamicAtlasAndSwitchMaterial(this);
+
// Cache mode and has animation queue.
if (this._isAniComplete) {
if (this._animationQueue.length === 0 && !this._headAniInfo) {
@@ -1086,6 +1088,7 @@ sp.Skeleton = cc.Class({
if (this.attachUtil._hasAttachedNode()) {
this._frameCache.enableCacheAttachedInfo();
}
+ this._assembler.handleDynamicAtlasAndSwitchMaterial(this);
this._frameCache.updateToFrame(0);
this._curFrame = this._frameCache.frames[0];
}
@@ -1379,7 +1382,9 @@ sp.Skeleton = cc.Class({
}
},
- _updateSkeletonData () {
+ _updateSkeletonData() {
+ this._dataDirty = true;
+
if (!this.skeletonData) {
this.disableRender();
return;
@@ -1406,7 +1411,6 @@ sp.Skeleton = cc.Class({
this.attachUtil._associateAttachedNode();
this._preCacheMode = this._cacheMode;
this.animation = this.defaultAnimation;
- this._dataDirty = true;
},
_refreshInspector () {
diff --git a/engine/extensions/spine/skeleton-cache.js b/engine/extensions/spine/skeleton-cache.js
index c0ef822..5a26e01 100644
--- a/engine/extensions/spine/skeleton-cache.js
+++ b/engine/extensions/spine/skeleton-cache.js
@@ -423,8 +423,8 @@ let AnimationCache = cc.Class({
}
blendMode = slot.data.blendMode;
- if (_preTexUrl !== texture.nativeUrl || _preBlendMode !== blendMode) {
- _preTexUrl = texture.nativeUrl;
+ if (_preTexUrl !== texture._texture._id || _preBlendMode !== blendMode) {
+ _preTexUrl = texture._texture._id;
_preBlendMode = blendMode;
// Handle pre segment.
preSegOffset = _segOffset - 1;
diff --git a/engine/extensions/spine/spine-assembler.js b/engine/extensions/spine/spine-assembler.js
index 36c91f0..2744684 100644
--- a/engine/extensions/spine/spine-assembler.js
+++ b/engine/extensions/spine/spine-assembler.js
@@ -199,6 +199,15 @@ export default class SpineAssembler extends Assembler {
updateRenderData (comp) {
if (comp.isAnimationCached()) return;
+ this.handleDynamicAtlasAndSwitchMaterial(comp);
+
+ let skeleton = comp._skeleton;
+ if (skeleton) {
+ skeleton.updateWorldTransform();
+ }
+ }
+
+ handleDynamicAtlasAndSwitchMaterial(comp) {
if (comp._dataDirty) {
// 自动合图
this.packDynamicAtlasForSpine(comp);
@@ -210,13 +219,13 @@ export default class SpineAssembler extends Assembler {
if (!material) return false;
const skins = comp.skeletonData._skeletonCache.skins;
- for (const skin of skins) {
+ root: for (const skin of skins) {
for (const attachment of skin.attachments) {
for (const key in attachment) {
const region = attachment[key].region;
if (region && region.texture) {
this.checkAndSwitchMaterial(comp, region.texture._texture, material);
- break;
+ break root;
}
}
}
@@ -224,11 +233,6 @@ export default class SpineAssembler extends Assembler {
}
comp._dataDirty = false;
}
-
- let skeleton = comp._skeleton;
- if (skeleton) {
- skeleton.updateWorldTransform();
- }
}
packDynamicAtlasForSpine(comp) {
--
2.32.0 (Apple Git-132)

View File

@ -1,33 +0,0 @@
From 44d365d4a46347fb179d12f1f53848deb2c4a336 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 22:36:31 +0800
Subject: [PATCH 14/16] =?UTF-8?q?=E4=BC=98=E5=8C=96=20Char=20=E7=BC=93?=
=?UTF-8?q?=E5=AD=98=E6=A8=A1=E5=BC=8F=E7=9A=84=E6=80=A7=E8=83=BD=EF=BC=88?=
=?UTF-8?q?=E7=BA=B9=E7=90=86=E4=B8=8D=E9=9C=80=E8=A6=81=E5=88=A4=E6=96=AD?=
=?UTF-8?q?=E6=98=AF=E5=90=A6=E8=A6=81=E8=BF=98=E5=8E=9F=E5=8A=A8=E6=80=81?=
=?UTF-8?q?=E5=90=88=E5=9B=BE=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/renderer/utils/label/letter-font.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/engine/cocos2d/core/renderer/utils/label/letter-font.js b/engine/cocos2d/core/renderer/utils/label/letter-font.js
index 0e7aaae..5e19af4 100644
--- a/engine/cocos2d/core/renderer/utils/label/letter-font.js
+++ b/engine/cocos2d/core/renderer/utils/label/letter-font.js
@@ -119,7 +119,8 @@ LetterTexture.prototype = {
this._texture.handleLoadedTexture();
},
- destroy () {
+ destroy() {
+ this._texture._packable = false;
this._texture.destroy();
this._texture = null;
Label._canvasPool.put(this._data);
--
2.32.0 (Apple Git-132)

View File

@ -1,55 +0,0 @@
From a4decd86188d65dbabd49aeeaaccc8713968d51a Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Tue, 21 Jun 2022 22:37:35 +0800
Subject: [PATCH 15/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Bitmap=20=E7=BC=93?=
=?UTF-8?q?=E5=AD=98=E6=A8=A1=E5=BC=8F=E5=A4=8D=E7=94=A8=E5=90=8E=E5=87=BA?=
=?UTF-8?q?=E7=8E=B0=E7=9A=84=E5=90=8C=20uuid=20=E5=AF=BC=E8=87=B4?=
=?UTF-8?q?=E6=AD=A3=E5=9C=A8=E4=BD=BF=E7=94=A8=E7=9A=84=E5=8A=A8=E6=80=81?=
=?UTF-8?q?=E5=9B=BE=E9=9B=86=E5=8C=BA=E5=9F=9F=E8=A2=AB=E9=94=80=E6=AF=81?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/cocos2d/core/components/CCLabel.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/engine/cocos2d/core/components/CCLabel.js b/engine/cocos2d/core/components/CCLabel.js
index 6cbfe1b..9d22219 100644
--- a/engine/cocos2d/core/components/CCLabel.js
+++ b/engine/cocos2d/core/components/CCLabel.js
@@ -478,7 +478,7 @@ let Label = cc.Class({
if (this.cacheMode === oldValue) return;
if (oldValue === CacheMode.BITMAP && !(this.font instanceof cc.BitmapFont)) {
- this._frame && this._frame._resetDynamicAtlasFrame();
+ deleteFromDynamicAtlas(this, this._frame);
}
if (oldValue === CacheMode.CHAR) {
@@ -665,9 +665,12 @@ let Label = cc.Class({
this._assemblerData = null;
this._letterTexture = null;
if (this._ttfTexture) {
+ // HACK 由于会出现多个 uuid 一样的情况,销毁时会将动态图集中的区域直接销毁,导致其它使用该区域的 Label 显示错误,所以先将 packable = false不走销毁逻辑在下方走 frame 的回收逻辑
+ this._ttfTexture._packable = false;
this._ttfTexture.destroy();
this._ttfTexture = null;
}
+ this._resetFrame();
this._super();
},
@@ -784,7 +787,7 @@ let Label = cc.Class({
}
if (this.cacheMode !== CacheMode.CHAR) {
- this._frame._resetDynamicAtlasFrame();
+ deleteFromDynamicAtlas(this, this._frame);
this._frame._refreshTexture(this._ttfTexture);
if (this._srcBlendFactor === cc.macro.BlendFactor.ONE && !CC_NATIVERENDERER) {
this._ttfTexture.setPremultiplyAlpha(true);
--
2.32.0 (Apple Git-132)

View File

@ -1,39 +0,0 @@
From fcca26d142f2ccab5330dc079fad45aa3f92fec9 Mon Sep 17 00:00:00 2001
From: SmallMain <smallmain@outlook.com>
Date: Wed, 22 Jun 2022 00:54:12 +0800
Subject: [PATCH 16/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Spine=20=E6=B2=A1?=
=?UTF-8?q?=E6=9C=89=20assembler=20=E6=97=B6=E6=8A=A5=E9=94=99=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
engine/extensions/spine/Skeleton.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/engine/extensions/spine/Skeleton.js b/engine/extensions/spine/Skeleton.js
index b1eda9c..49a7605 100644
--- a/engine/extensions/spine/Skeleton.js
+++ b/engine/extensions/spine/Skeleton.js
@@ -702,7 +702,7 @@ sp.Skeleton = cc.Class({
if (this.isAnimationCached()) {
- this._assembler.handleDynamicAtlasAndSwitchMaterial(this);
+ if (this._assembler) this._assembler.handleDynamicAtlasAndSwitchMaterial(this);
// Cache mode and has animation queue.
if (this._isAniComplete) {
@@ -1088,7 +1088,7 @@ sp.Skeleton = cc.Class({
if (this.attachUtil._hasAttachedNode()) {
this._frameCache.enableCacheAttachedInfo();
}
- this._assembler.handleDynamicAtlasAndSwitchMaterial(this);
+ if (this._assembler) this._assembler.handleDynamicAtlasAndSwitchMaterial(this);
this._frameCache.updateToFrame(0);
this._curFrame = this._frameCache.frames[0];
}
--
2.32.0 (Apple Git-132)