mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-09-24 08:14:36 +00:00
[engine] 多纹理渲染 - 支持 cc.Label(not char cache mode)、cc.RichText、cc.Sprite、cc.MotionStreak 组件
This commit is contained in:
@@ -192,7 +192,7 @@ let Label = cc.Class({
|
||||
editor: CC_EDITOR && {
|
||||
menu: 'i18n:MAIN_MENU.component.renderers/Label',
|
||||
help: 'i18n:COMPONENT.help_url.label',
|
||||
inspector: 'packages://inspector/inspectors/comps/label.js',
|
||||
inspector: 'packages://service-pack/inspectors/comps/label.js',
|
||||
},
|
||||
|
||||
properties: {
|
||||
@@ -578,6 +578,11 @@ let Label = cc.Class({
|
||||
},
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.label.underline_height',
|
||||
},
|
||||
|
||||
autoSwitchMaterial: {
|
||||
type: RenderComponent.EnableType,
|
||||
default: RenderComponent.EnableType.GLOBAL,
|
||||
},
|
||||
},
|
||||
|
||||
statics: {
|
||||
@@ -782,7 +787,25 @@ let Label = cc.Class({
|
||||
}
|
||||
|
||||
if (!this._frame) return;
|
||||
material && material.setProperty('texture', this._frame._texture);
|
||||
|
||||
if (material) {
|
||||
// 根据材质更新 uniform
|
||||
const isMultiMaterial = material.material.isMultiSupport();
|
||||
if (isMultiMaterial) {
|
||||
// 贴图在 updateRenderData 才确定下来
|
||||
// if (texture) this._updateMultiTexId(material, texture);
|
||||
this._texIdDirty = true;
|
||||
} else {
|
||||
material.setProperty('texture', this._frame._texture);
|
||||
}
|
||||
|
||||
// 根据材质更新 assembler
|
||||
if (this._assembler) {
|
||||
if ((isMultiMaterial && !this._assembler.isMulti) || !isMultiMaterial && this._assembler.isMulti) {
|
||||
RenderComponent.prototype._resetAssembler.call(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BlendFunc.prototype._updateMaterial.call(this);
|
||||
},
|
||||
|
@@ -161,6 +161,10 @@ var MotionStreak = cc.Class({
|
||||
if (this._texture === value) return;
|
||||
|
||||
this._texture = value;
|
||||
|
||||
// 自动切换材质
|
||||
this._checkSwitchMaterial();
|
||||
|
||||
this._updateMaterial();
|
||||
},
|
||||
type: cc.Texture2D,
|
||||
@@ -210,6 +214,25 @@ var MotionStreak = cc.Class({
|
||||
},
|
||||
animatable: false,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.motionStreak.fastMode'
|
||||
},
|
||||
|
||||
autoSwitchMaterial: {
|
||||
type: RenderComponent.EnableType,
|
||||
default: RenderComponent.EnableType.GLOBAL,
|
||||
},
|
||||
},
|
||||
|
||||
__preload() {
|
||||
this._super();
|
||||
this._checkSwitchMaterial();
|
||||
},
|
||||
|
||||
_checkSwitchMaterial() {
|
||||
if (this._assembler) {
|
||||
const material = this._materials[0];
|
||||
if (!material) return;
|
||||
if (!this._texture) return;
|
||||
this._assembler.checkAndSwitchMaterial(this, this._texture, material);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -220,7 +243,32 @@ var MotionStreak = cc.Class({
|
||||
|
||||
_updateMaterial () {
|
||||
let material = this.getMaterial(0);
|
||||
material && material.setProperty('texture', this._texture);
|
||||
|
||||
// 根据材质更新 uniform
|
||||
const isMultiMaterial = material.material.isMultiSupport();
|
||||
if (isMultiMaterial) {
|
||||
if (!this._texture) return;
|
||||
this._updateMultiTexId(material, this._texture);
|
||||
} else {
|
||||
const textureImpl = this._texture && this._texture.getImpl();
|
||||
if (material.getProperty('texture') !== textureImpl) {
|
||||
material.setProperty('texture', this._texture);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据材质更新 assembler
|
||||
if (this._assembler) {
|
||||
if ((isMultiMaterial && !this._assembler.isMulti) || !isMultiMaterial && this._assembler.isMulti) {
|
||||
this._resetAssembler();
|
||||
}
|
||||
}
|
||||
|
||||
// texId
|
||||
if (isMultiMaterial && this._texIdDirty && this._assembler) {
|
||||
if (!this._texture) return;
|
||||
this._assembler.updateTexId(this);
|
||||
this._texIdDirty = false;
|
||||
}
|
||||
|
||||
BlendFunc.prototype._updateMaterial.call(this);
|
||||
},
|
||||
|
@@ -33,6 +33,32 @@ const Material = require('../assets/material/CCMaterial');
|
||||
|
||||
let _temp_color = new Color();
|
||||
|
||||
/**
|
||||
* !#en enable type
|
||||
* !#zh 启用类型
|
||||
* @enum RenderComponent.EnableType
|
||||
*/
|
||||
var EnableType = cc.Enum({
|
||||
/**
|
||||
* !#en Global.
|
||||
* !#zh 使用全局值
|
||||
* @property {Number} GLOBAL
|
||||
*/
|
||||
GLOBAL: 0,
|
||||
/**
|
||||
* !#en Enable.
|
||||
* !#zh 开启
|
||||
* @property {Number} ENABLE
|
||||
*/
|
||||
ENABLE: 1,
|
||||
/**
|
||||
* !#en Disable.
|
||||
* !#zh 关闭
|
||||
* @property {Number} DISABLE
|
||||
*/
|
||||
DISABLE: 2,
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Base class for components which supports rendering features.
|
||||
@@ -51,6 +77,10 @@ let RenderComponent = cc.Class({
|
||||
disallowMultiple: true
|
||||
},
|
||||
|
||||
statics: {
|
||||
EnableType: EnableType,
|
||||
},
|
||||
|
||||
properties: {
|
||||
_materials: {
|
||||
default: [],
|
||||
@@ -78,12 +108,16 @@ let RenderComponent = cc.Class({
|
||||
|
||||
ctor () {
|
||||
this._vertsDirty = true;
|
||||
this._texIdDirty = true;
|
||||
this._texId = 0;
|
||||
this._assembler = null;
|
||||
},
|
||||
|
||||
_resetAssembler () {
|
||||
Assembler.init(this);
|
||||
this._updateColor();
|
||||
// 切换 Assembler 时,texId 与 vDatas 数据不同步
|
||||
this._texId = 0;
|
||||
this.setVertsDirty();
|
||||
},
|
||||
|
||||
@@ -252,7 +286,43 @@ let RenderComponent = cc.Class({
|
||||
renderer.material = material;
|
||||
renderer.cullingMask = cullingMask;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_updateMultiTexId(material, texture) {
|
||||
const multi = material.material.getMultiHandler();
|
||||
|
||||
const spTexture = texture;
|
||||
const nSpTexture = spTexture.getImpl();
|
||||
|
||||
// 快速检查插槽上的贴图是否相同
|
||||
// 如果是当作普通材质使用,multi.getTexture(this._texId) !== nSpTexture 会一直为 true
|
||||
const same = this._texId === 0
|
||||
? material.getProperty('texture') !== nSpTexture
|
||||
: multi.getTexture(this._texId) !== nSpTexture;
|
||||
|
||||
if (same) {
|
||||
// 如果材质变体被修改了,则直接跳过位置检查
|
||||
const isChanged = Object.prototype.hasOwnProperty.call(material._effect._passes['0']._properties, 'texture');
|
||||
const texId = isChanged ? -1 : multi.getIndex(nSpTexture);
|
||||
|
||||
if (texId !== -1) {
|
||||
// 插槽位置不对,则更新位置
|
||||
this._texId = texId;
|
||||
this._texIdDirty = true;
|
||||
} else {
|
||||
// 插槽根本没有该纹理,则修改变体的 texture
|
||||
material.setProperty('texture', spTexture);
|
||||
if (this._texId !== 0) {
|
||||
this._texId = 0;
|
||||
this._texIdDirty = true;
|
||||
}
|
||||
// cc.warn('renderComponent use multi-material but not has valid property.');
|
||||
}
|
||||
} else {
|
||||
this._texIdDirty = false;
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
cc.RenderComponent = module.exports = RenderComponent;
|
||||
|
@@ -28,6 +28,7 @@ const js = require('../platform/js');
|
||||
const macro = require('../platform/CCMacro');
|
||||
const textUtils = require('../utils/text-utils');
|
||||
const HtmlTextParser = require('../utils/html-text-parser');
|
||||
import MaterialVariant from '../assets/material/material-variant';
|
||||
const _htmlTextParser = new HtmlTextParser();
|
||||
|
||||
const HorizontalAlign = macro.TextAlignment;
|
||||
@@ -36,6 +37,8 @@ const RichTextChildName = "RICHTEXT_CHILD";
|
||||
const RichTextChildImageName = "RICHTEXT_Image_CHILD";
|
||||
const CacheMode = cc.Label.CacheMode;
|
||||
|
||||
const RenderComponent = require('./CCRenderComponent');
|
||||
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||||
@@ -130,7 +133,7 @@ let RichText = cc.Class({
|
||||
editor: CC_EDITOR && {
|
||||
menu: 'i18n:MAIN_MENU.component.renderers/RichText',
|
||||
help: 'i18n:COMPONENT.help_url.richtext',
|
||||
inspector: 'packages://inspector/inspectors/comps/richtext.js',
|
||||
inspector: 'packages://service-pack/inspectors/comps/richtext.js',
|
||||
executeInEditMode: true
|
||||
},
|
||||
|
||||
@@ -347,6 +350,30 @@ let RichText = cc.Class({
|
||||
this.handleTouchEvent ? this._addEventListeners() : this._removeEventListeners();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
autoSwitchMaterial: {
|
||||
type: RenderComponent.EnableType,
|
||||
default: RenderComponent.EnableType.GLOBAL,
|
||||
notify: function (oldValue) {
|
||||
if (this.autoSwitchMaterial === oldValue) return;
|
||||
for (let i = 0; i < this._labelSegments.length; i++) {
|
||||
const labelComponent = this._labelSegments[i].getComponent(cc.Label);
|
||||
if (labelComponent) {
|
||||
labelComponent.autoSwitchMaterial = this.autoSwitchMaterial;
|
||||
}
|
||||
const spriteComponent = this._labelSegments[i].getComponent(cc.Sprite);
|
||||
if (spriteComponent) {
|
||||
spriteComponent.autoSwitchMaterial = this.autoSwitchMaterial;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this._labelSegmentsCache.length; i++) {
|
||||
const labelComponent = this._labelSegmentsCache[i].getComponent(cc.Label);
|
||||
if (labelComponent) {
|
||||
labelComponent.autoSwitchMaterial = this.autoSwitchMaterial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -653,6 +680,8 @@ let RichText = cc.Class({
|
||||
let spriteNode = new cc.PrivateNode(RichTextChildImageName);
|
||||
spriteNode._objFlags |= cc.Object.Flags.DontSave;
|
||||
let spriteComponent = spriteNode.addComponent(cc.Sprite);
|
||||
|
||||
spriteComponent.autoSwitchMaterial = this.autoSwitchMaterial;
|
||||
switch (richTextElement.style.imageAlign)
|
||||
{
|
||||
case 'top':
|
||||
@@ -945,6 +974,7 @@ let RichText = cc.Class({
|
||||
|
||||
labelComponent.cacheMode = this.cacheMode;
|
||||
|
||||
labelComponent.autoSwitchMaterial = this.autoSwitchMaterial;
|
||||
let isAsset = this.font instanceof cc.Font;
|
||||
if (isAsset && !this._isSystemFontUsed) {
|
||||
labelComponent.font = this.font;
|
||||
|
@@ -160,7 +160,7 @@ var Sprite = cc.Class({
|
||||
editor: CC_EDITOR && {
|
||||
menu: 'i18n:MAIN_MENU.component.renderers/Sprite',
|
||||
help: 'i18n:COMPONENT.help_url.sprite',
|
||||
inspector: 'packages://inspector/inspectors/comps/sprite.js',
|
||||
inspector: 'packages://service-pack/inspectors/comps/sprite.js',
|
||||
},
|
||||
|
||||
properties: {
|
||||
@@ -386,7 +386,12 @@ var Sprite = cc.Class({
|
||||
animatable: false,
|
||||
type: SizeMode,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.sprite.size_mode'
|
||||
}
|
||||
},
|
||||
|
||||
autoSwitchMaterial: {
|
||||
type: RenderComponent.EnableType,
|
||||
default: RenderComponent.EnableType.GLOBAL,
|
||||
},
|
||||
},
|
||||
|
||||
statics: {
|
||||
@@ -465,9 +470,25 @@ var Sprite = cc.Class({
|
||||
if (oldDefine !== undefined && !oldDefine) {
|
||||
material.define('USE_TEXTURE', true);
|
||||
}
|
||||
let textureImpl = texture && texture.getImpl();
|
||||
if (material.getProperty('texture') !== textureImpl) {
|
||||
material.setProperty('texture', texture);
|
||||
|
||||
// 根据材质更新 uniform
|
||||
const isMultiMaterial = material.material.isMultiSupport();
|
||||
if (isMultiMaterial) {
|
||||
// 在 assembler 中进行更新性能会更好,不需要每次 setSpriteFrame 都更新,并且动态图集会导致两次触发
|
||||
// if (texture) this._updateMultiTexId(material, texture);
|
||||
this._texIdDirty = true;
|
||||
} else {
|
||||
const textureImpl = texture && texture.getImpl();
|
||||
if (material.getProperty('texture') !== textureImpl) {
|
||||
material.setProperty('texture', texture);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据材质更新 assembler
|
||||
if (this._assembler) {
|
||||
if ((isMultiMaterial && !this._assembler.isMulti) || !isMultiMaterial && this._assembler.isMulti) {
|
||||
this._resetAssembler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user