UNPKG

laya-coreui-es

Version:

laya核心库、ui库es版本,剔除了媒体、TTF等功能。基于 LayaAir-release_2.12.0 修改

405 lines (404 loc) 15.7 kB
import { Const } from "../Const"; import { SpriteConst } from "../display/SpriteConst"; import { Filter } from "../filters/Filter"; import { Matrix } from "../maths/Matrix"; import { Rectangle } from "../maths/Rectangle"; import { Texture } from "../resource/Texture"; import { WebGLRTMgr } from "../resource/WebGLRTMgr"; import { Stat } from "../utils/Stat"; import { BlendMode } from "../webgl/canvas/BlendMode"; import { WebGLCacheAsNormalCanvas } from "../webgl/canvas/WebGLCacheAsNormalCanvas"; import { ShaderDefines2D } from "../webgl/shader/d2/ShaderDefines2D"; import { Value2D } from "../webgl/shader/d2/value/Value2D"; import { SubmitCMD } from "../webgl/submit/SubmitCMD"; import { WebGLContext } from "../webgl/WebGLContext"; import { LayaGLQuickRunner } from "./LayaGLQuickRunner"; import { ILaya } from "../../ILaya"; export class RenderSprite { static __init__() { LayaGLQuickRunner.__init__(); var i, len; var initRender; initRender = new RenderSprite(RenderSprite.INIT, null); len = RenderSprite.renders.length = SpriteConst.CHILDS * 2; for (i = 0; i < len; i++) RenderSprite.renders[i] = initRender; RenderSprite.renders[0] = new RenderSprite(0, null); function _initSame(value, o) { var n = 0; for (var i = 0; i < value.length; i++) { n |= value[i]; RenderSprite.renders[n] = o; } } } static _initRenderFun(sprite, context, x, y) { var type = sprite._renderType; var r = RenderSprite.renders[type] = RenderSprite._getTypeRender(type); r._fun(sprite, context, x, y); } static _getTypeRender(type) { if (LayaGLQuickRunner.map[type]) return new RenderSprite(type, null); var rst = null; var tType = SpriteConst.CHILDS; while (tType > 0) { if (tType & type) rst = new RenderSprite(tType, rst); tType = tType >> 1; } return rst; } constructor(type, next) { if (LayaGLQuickRunner.map[type]) { this._fun = LayaGLQuickRunner.map[type]; this._next = RenderSprite.NORENDER; return; } this._next = next || RenderSprite.NORENDER; switch (type) { case 0: this._fun = this._no; return; case SpriteConst.ALPHA: this._fun = this._alpha; return; case SpriteConst.TRANSFORM: this._fun = this._transform; return; case SpriteConst.BLEND: this._fun = this._blend; return; case SpriteConst.CANVAS: this._fun = this._canvas; return; case SpriteConst.MASK: this._fun = this._mask; return; case SpriteConst.CLIP: this._fun = this._clip; return; case SpriteConst.STYLE: this._fun = this._style; return; case SpriteConst.GRAPHICS: this._fun = this._graphics; return; case SpriteConst.CHILDS: this._fun = this._children; return; case SpriteConst.CUSTOM: this._fun = this._custom; return; case SpriteConst.TEXTURE: this._fun = this._texture; return; case SpriteConst.FILTERS: this._fun = Filter._filter; return; case RenderSprite.INIT: this._fun = RenderSprite._initRenderFun; return; } this.onCreate(type); } onCreate(type) { } _style(sprite, context, x, y) { var style = sprite._style; if (style.render != null) style.render(sprite, context, x, y); var next = this._next; next._fun.call(next, sprite, context, x, y); } _no(sprite, context, x, y) { } _custom(sprite, context, x, y) { sprite.customRender(context, x, y); this._next._fun.call(this._next, sprite, context, 0, 0); } _clip(sprite, context, x, y) { var next = this._next; if (next == RenderSprite.NORENDER) return; var r = sprite._style.scrollRect; var width = r.width; var height = r.height; if (width === 0 || height === 0) { return; } context.save(); context.clipRect(x, y, width, height); next._fun.call(next, sprite, context, x - r.x, y - r.y); context.restore(); } _texture(sprite, context, x, y) { var tex = sprite.texture; if (tex._getSource()) { var width = sprite._width || tex.sourceWidth; var height = sprite._height || tex.sourceHeight; var wRate = width / tex.sourceWidth; var hRate = height / tex.sourceHeight; width = tex.width * wRate; height = tex.height * hRate; if (width <= 0 || height <= 0) return; var px = x - sprite.pivotX + tex.offsetX * wRate; var py = y - sprite.pivotY + tex.offsetY * hRate; context.drawTexture(tex, px, py, width, height); } var next = this._next; if (next != RenderSprite.NORENDER) next._fun.call(next, sprite, context, x, y); } _graphics(sprite, context, x, y) { var style = sprite._style; var g = sprite._graphics; g && g._render(sprite, context, x - style.pivotX, y - style.pivotY); var next = this._next; if (next != RenderSprite.NORENDER) next._fun.call(next, sprite, context, x, y); } _image(sprite, context, x, y) { var style = sprite._style; context.drawTexture2(x, y, style.pivotX, style.pivotY, sprite.transform, sprite._graphics._one); } _image2(sprite, context, x, y) { var style = sprite._style; context.drawTexture2(x, y, style.pivotX, style.pivotY, sprite.transform, sprite._graphics._one); } _alpha(sprite, context, x, y) { var style = sprite._style; var alpha; if ((alpha = style.alpha) > 0.01 || sprite._needRepaint()) { var temp = context.globalAlpha; context.globalAlpha *= alpha; var next = this._next; next._fun.call(next, sprite, context, x, y); context.globalAlpha = temp; } } _transform(sprite, context, x, y) { var transform = sprite.transform, _next = this._next; var style = sprite._style; if (transform && _next != RenderSprite.NORENDER) { context.save(); context.transform(transform.a, transform.b, transform.c, transform.d, transform.tx + x, transform.ty + y); _next._fun.call(_next, sprite, context, 0, 0); context.restore(); } else { if (_next != RenderSprite.NORENDER) _next._fun.call(_next, sprite, context, x, y); } } _children(sprite, context, x, y) { var style = sprite._style; var childs = sprite._children, n = childs.length, ele; x = x - sprite.pivotX; y = y - sprite.pivotY; var textLastRender = sprite._getBit(Const.DRAWCALL_OPTIMIZE) && context.drawCallOptimize(true); if (style.viewport) { var rect = style.viewport; var left = rect.x; var top = rect.y; var right = rect.right; var bottom = rect.bottom; var _x, _y; for (i = 0; i < n; ++i) { if ((ele = childs[i])._visible && ((_x = ele._x) < right && (_x + ele.width) > left && (_y = ele._y) < bottom && (_y + ele.height) > top)) { ele.render(context, x, y); } } } else { for (var i = 0; i < n; ++i) (ele = childs[i])._visible && ele.render(context, x, y); } textLastRender && context.drawCallOptimize(false); } _canvas(sprite, context, x, y) { var _cacheStyle = sprite._cacheStyle; var _next = this._next; if (!_cacheStyle.enableCanvasRender) { _next._fun.call(_next, sprite, context, x, y); return; } _cacheStyle.cacheAs === 'bitmap' ? (Stat.canvasBitmap++) : (Stat.canvasNormal++); var cacheNeedRebuild = false; var textNeedRestore = false; if (_cacheStyle.canvas) { var canv = _cacheStyle.canvas; var ctx = canv.context; var charRIs = canv.touches; if (charRIs) { for (var ci = 0; ci < charRIs.length; ci++) { if (charRIs[ci].deleted) { textNeedRestore = true; break; } } } cacheNeedRebuild = canv.isCacheValid && !canv.isCacheValid(); } if (sprite._needRepaint() || (!_cacheStyle.canvas) || textNeedRestore || cacheNeedRebuild || ILaya.stage.isGlobalRepaint()) { if (_cacheStyle.cacheAs === 'normal') { if (context._targets) { _next._fun.call(_next, sprite, context, x, y); return; } else { this._canvas_webgl_normal_repaint(sprite, context); } } else { this._canvas_repaint(sprite, context, x, y); } } var tRec = _cacheStyle.cacheRect; context.drawCanvas(_cacheStyle.canvas, x + tRec.x, y + tRec.y, tRec.width, tRec.height); } _canvas_repaint(sprite, context, x, y) { var _cacheStyle = sprite._cacheStyle; var _next = this._next; var tx; var canvas = _cacheStyle.canvas; var left; var top; var tRec; var tCacheType = _cacheStyle.cacheAs; var w, h; var scaleX, scaleY; var scaleInfo; scaleInfo = _cacheStyle._calculateCacheRect(sprite, tCacheType, x, y); scaleX = scaleInfo.x; scaleY = scaleInfo.y; tRec = _cacheStyle.cacheRect; w = tRec.width * scaleX; h = tRec.height * scaleY; left = tRec.x; top = tRec.y; if (tCacheType === 'bitmap' && (w > 2048 || h > 2048)) { console.warn("cache bitmap size larger than 2048,cache ignored"); _cacheStyle.releaseContext(); _next._fun.call(_next, sprite, context, x, y); return; } if (!canvas) { _cacheStyle.createContext(); canvas = _cacheStyle.canvas; } tx = canvas.context; tx.sprite = sprite; (canvas.width != w || canvas.height != h) && canvas.size(w, h); if (tCacheType === 'bitmap') tx.asBitmap = true; else if (tCacheType === 'normal') tx.asBitmap = false; tx.clear(); if (scaleX != 1 || scaleY != 1) { var ctx = tx; ctx.save(); ctx.scale(scaleX, scaleY); _next._fun.call(_next, sprite, tx, -left, -top); ctx.restore(); sprite._applyFilters(); } else { ctx = tx; _next._fun.call(_next, sprite, tx, -left, -top); sprite._applyFilters(); } if (_cacheStyle.staticCache) _cacheStyle.reCache = false; Stat.canvasReCache++; } _canvas_webgl_normal_repaint(sprite, context) { var _cacheStyle = sprite._cacheStyle; var _next = this._next; var canvas = _cacheStyle.canvas; var tCacheType = _cacheStyle.cacheAs; _cacheStyle._calculateCacheRect(sprite, tCacheType, 0, 0); if (!canvas) { canvas = new WebGLCacheAsNormalCanvas(context, sprite); _cacheStyle.canvas = canvas; } var tx = canvas.context; canvas.startRec(); _next._fun.call(_next, sprite, tx, sprite.pivotX, sprite.pivotY); sprite._applyFilters(); Stat.canvasReCache++; canvas.endRec(); } _blend(sprite, context, x, y) { var style = sprite._style; var next = this._next; if (style.blendMode) { context.save(); context.globalCompositeOperation = style.blendMode; next._fun.call(next, sprite, context, x, y); context.restore(); } else { next._fun.call(next, sprite, context, x, y); } } _mask(sprite, context, x, y) { var next = this._next; var mask = sprite.mask; var submitCMD; var ctx = context; if (mask) { ctx.save(); var preBlendMode = ctx.globalCompositeOperation; var tRect = new Rectangle(); tRect.copyFrom(mask.getBounds()); tRect.width = Math.round(tRect.width); tRect.height = Math.round(tRect.height); tRect.x = Math.round(tRect.x); tRect.y = Math.round(tRect.y); if (tRect.width > 0 && tRect.height > 0) { var w = tRect.width; var h = tRect.height; var tmpRT = WebGLRTMgr.getRT(w, h); ctx.breakNextMerge(); ctx.pushRT(); ctx.addRenderObject(SubmitCMD.create([ctx, tmpRT, w, h], RenderSprite.tmpTarget, this)); mask.render(ctx, -tRect.x, -tRect.y); ctx.breakNextMerge(); ctx.popRT(); ctx.save(); let shrink = 0.1; ctx.clipRect(x + tRect.x - sprite.getStyle().pivotX + shrink, y + tRect.y - sprite.getStyle().pivotY + shrink, w - shrink * 2, h - shrink * 2); next._fun.call(next, sprite, ctx, x, y); ctx.restore(); preBlendMode = ctx.globalCompositeOperation; ctx.addRenderObject(SubmitCMD.create(["mask"], RenderSprite.setBlendMode, this)); var shaderValue = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); var uv = Texture.INV_UV; ctx.drawTarget(tmpRT, x + tRect.x - sprite.getStyle().pivotX, y + tRect.y - sprite.getStyle().pivotY, w, h, Matrix.TEMP.identity(), shaderValue, uv, 6); ctx.addRenderObject(SubmitCMD.create([tmpRT], RenderSprite.recycleTarget, this)); ctx.addRenderObject(SubmitCMD.create([preBlendMode], RenderSprite.setBlendMode, this)); } ctx.restore(); } else { next._fun.call(next, sprite, context, x, y); } } static tmpTarget(ctx, rt, w, h) { rt.start(); rt.clear(0, 0, 0, 0); } static recycleTarget(rt) { WebGLRTMgr.releaseRT(rt); } static setBlendMode(blendMode) { var gl = WebGLContext.mainContext; BlendMode.targetFns[BlendMode.TOINT[blendMode]](gl); } } RenderSprite.INIT = 0x11111; RenderSprite.renders = []; RenderSprite.NORENDER = new RenderSprite(0, null); RenderSprite.tempUV = new Array(8);