mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2024-12-26 11:48:29 +00:00
[engine] service pack 命名空间、多纹理渲染基础
This commit is contained in:
parent
f31cb598e3
commit
7d0519ed68
@ -80,8 +80,50 @@ var builtins = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._loadBuiltins('effect', () => {
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -470,6 +470,9 @@ var Texture2D = cc.Class({
|
|||||||
if (CC_EDITOR) {
|
if (CC_EDITOR) {
|
||||||
this._exportedExts = null;
|
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._packable && cc.dynamicAtlasManager && cc.dynamicAtlasManager.deleteAtlasTexture(this);
|
||||||
|
|
||||||
|
this.unlinkMaterial();
|
||||||
|
|
||||||
this._image = null;
|
this._image = null;
|
||||||
this._texture && this._texture.destroy();
|
this._texture && this._texture.destroy();
|
||||||
this._super();
|
this._super();
|
||||||
@ -1054,7 +1059,43 @@ var Texture2D = cc.Class({
|
|||||||
else {
|
else {
|
||||||
cb();
|
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;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,6 +72,7 @@ let Material = cc.Class({
|
|||||||
this._manualHash = false;
|
this._manualHash = false;
|
||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
this._effect = null;
|
this._effect = null;
|
||||||
|
this._multiHandler = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
properties: {
|
properties: {
|
||||||
@ -124,6 +125,8 @@ let Material = cc.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._effect = this._effectAsset.getInstantiatedEffect();
|
this._effect = this._effectAsset.getInstantiatedEffect();
|
||||||
|
|
||||||
|
this.updateMultiSupport();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -140,6 +143,7 @@ let Material = cc.Class({
|
|||||||
set (v) {
|
set (v) {
|
||||||
this._techniqueIndex = v;
|
this._techniqueIndex = v;
|
||||||
this._effect.switchTechnique(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;
|
export default Material;
|
||||||
|
@ -40,6 +40,8 @@ if (!CC_EDITOR || !Editor.isMainProcess) {
|
|||||||
require('./physics');
|
require('./physics');
|
||||||
require('./camera/CCCamera');
|
require('./camera/CCCamera');
|
||||||
require('./geom-utils');
|
require('./geom-utils');
|
||||||
|
|
||||||
|
require('./sp');
|
||||||
}
|
}
|
||||||
|
|
||||||
require('./mesh');
|
require('./mesh');
|
||||||
|
3
engine/cocos2d/core/sp/index.js
Normal file
3
engine/cocos2d/core/sp/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
require('./sp');
|
||||||
|
require('./multi-handler');
|
||||||
|
require('./multi-batcher');
|
74
engine/cocos2d/core/sp/multi-batcher.ts
Normal file
74
engine/cocos2d/core/sp/multi-batcher.ts
Normal file
@ -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;
|
146
engine/cocos2d/core/sp/multi-handler.ts
Normal file
146
engine/cocos2d/core/sp/multi-handler.ts
Normal file
@ -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;
|
86
engine/cocos2d/core/sp/sp.js
Normal file
86
engine/cocos2d/core/sp/sp.js
Normal file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user