egret-labs / egret-core

Egret is a brand new open mobile game and application engine which allows you to quickly build mobile games and apps on Android,iOS and Windows.
http://www.egret.com
Other
3.9k stars 787 forks source link

Egret Engine2D 5.3.5以后换肤,Canvas下无法渲染Dragonbons中使用网格的图片 #396

Open Afarways opened 3 years ago

Afarways commented 3 years ago

问题描述

我换肤方案是使用的官方提供的替换slot图片的方案,发现在Canvas下无法渲染Dragonbons中使用网格的图片;

//封装简单的换肤函数
/**
 * 替换插槽
 * @param slotName 插槽名称 原材料
 * @param textureName 图片名  xxx_png
 * @param 偏移量
 */
public setNewSlot( slotName:string, textureName:string ,offsetX:number=0, offsetY:number=0){
    var slot:dragonBones.Slot = this.armatureDisplay.armature.getSlot(slotName);
    var b:egret.Bitmap = new egret.Bitmap();
    b.texture = RES.getRes(textureName);
    b.x = slot.display.x;
    b.y = slot.display.y;
    b.anchorOffsetX = b.width/2 + offsetX;
    b.anchorOffsetY = b.height/2 + offsetY;
    slot.setDisplay( b );
}

问题追踪

通过追溯源码发现,换肤后会打断龙骨本身的批处理,会执行disableBatch()函数,之后Dragonbons的渲染流程会发生变化, 渲染 上面是批处理和非批处理的渲染流程,只是针对与网格Mesh图片,追溯源码后发现,打断批处理后之所以渲染不出来是因为图片的matrix属性丢失; matrix属性丢失原因 渲染 copy 原因是getRenderNode()的时候调用了cleanBeforeRender(),此处matrix被置为空;

/**
 * 在显示对象的$updateRenderNode()方法被调用前,自动清空自身的drawData数据。
 */
MeshNode.prototype.cleanBeforeRender = function () {
  _super.prototype.cleanBeforeRender.call(this);
  this.image = null;
  this.matrix = null;
};

而在renderMesh()中有这样一段代码,如果m为空,则无法调用context.translate,移动canvas画笔,因此绘制不出来;

  if (m) {
    context.save();
    saved = true;
    if (context.$offsetX != 0 || context.$offsetY != 0) {
        context.translate(context.$offsetX, context.$offsetY);
        offsetX = context.$offsetX;
        offsetY = context.$offsetY;
        context.$offsetX = context.$offsetY = 0;
    }
    context.transform(m.a, m.b, m.c, m.d, m.tx, m.ty);
}

我的解决方案

修改renderMesh()

  context.save();
  saved = true;
  if (context.$offsetX != 0 || context.$offsetY != 0) {
      context.translate(context.$offsetX, context.$offsetY);
      offsetX = context.$offsetX;
      offsetY = context.$offsetY;
      context.$offsetX = context.$offsetY = 0;
  }
  m && context.transform(m.a, m.b, m.c, m.d, m.tx, m.ty);

麻烦看看这样解决是否正确,盼复。

JansonC commented 3 years ago

我在webgl下也遇到这个问题,新版的龙骨更改了渲染流程,新增了frameData这个数据,导致空的slot设置display的时候,根本不起效,因为没有对应的frameData,暂时没有解决方法,只能用旧版的龙骨