UNPKG

@awayjs/renderer

Version:
260 lines (259 loc) 12.8 kB
import { __extends } from "tslib"; import { AssetEvent, Matrix3D, PerspectiveProjection, } from '@awayjs/core'; import { AttributesBuffer, ContextGLTriangleFace } from '@awayjs/stage'; import { ContainerNodeEvent, PickGroup } from '@awayjs/view'; import { _Render_RenderableBase } from './base/_Render_RenderableBase'; import { _Render_RendererMaterial } from './base/_Render_RendererMaterial'; import { TriangleElements } from './elements/TriangleElements'; import { MaterialEvent } from './events/MaterialEvent'; import { RenderableEvent } from './events/RenderableEvent'; import { RendererBase } from './RendererBase'; import { RenderGroup } from './RenderGroup'; import { ImageTexture2D } from './textures/ImageTexture2D'; import { Settings as StageSettings } from '@awayjs/stage'; import { RenderEntity } from './base/RenderEntity'; import { DefaultRenderer } from './DefaultRenderer'; var CacheRenderer = /** @class */ (function (_super) { __extends(CacheRenderer, _super); function CacheRenderer() { var _this = _super.call(this) || this; _this._textures = []; _this.animateUVs = false; _this.bothSides = false; _this.curves = false; _this.imageRect = false; _this.useColorTransform = true; _this.alphaBlending = true; _this.alphaThreshold = 0; _this._onTextureInvalidate = function (event) { return _this.invalidate(); }; _this._onInvalidateParentNode = function (event) { return _this.onInvalidate(null); }; _this._onInvalidateColorTransform = function (event) { return _this.onInvalidate(null); }; _this._traverserGroup = RenderGroup.getInstance(CacheRenderer); _this._maskGroup = RenderGroup.getInstance(DefaultRenderer); return _this; } Object.defineProperty(CacheRenderer.prototype, "assetType", { get: function () { return CacheRenderer.assetType; }, enumerable: false, configurable: true }); Object.defineProperty(CacheRenderer.prototype, "texture", { /** * The 2d texture to use as a bitmap cache. */ get: function () { //TODO check invalidation of _texture return this._texture; }, set: function (value) { if (this._texture == value) return; if (this._texture) this.removeTexture(this._texture); this._texture = value; if (this._texture) this.addTexture(this._texture); this.invalidatePasses(); }, enumerable: false, configurable: true }); CacheRenderer.prototype.init = function (node, pool) { _super.prototype.init.call(this, node, pool); if (this._parentNode) { this._parentNode.addEventListener(ContainerNodeEvent.INVALIDATE_MATRIX3D, this._onInvalidateParentNode); this._parentNode.addEventListener(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM, this._onInvalidateColorTransform); } // for check filters/blends changes this.node.container.addEventListener(RenderableEvent.INVALIDATE_STYLE, this._onInvalidateParentNode); this.node.container.addEventListener(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM, this._onInvalidateColorTransform); this.texture = new ImageTexture2D(); }; CacheRenderer.prototype.render = function (enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig) { var _this = this; if (enableDepthAndStencil === void 0) { enableDepthAndStencil = true; } if (surfaceSelector === void 0) { surfaceSelector = 0; } if (mipmapSelector === void 0) { mipmapSelector = 0; } if (maskConfig === void 0) { maskConfig = 0; } var container = this.node.container; var stage = this.stage; var useNonNativeBlend = this.useNonNativeBlend; var targetImage = (useNonNativeBlend ? this.parentRenderer.style.image : this._style.image); if (!targetImage) { return _super.prototype.render.call(this, enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig); } // WE MUST store older render target config, // because node can have cached child, that can be filtered this.stage.pushRenderTargetConfig(); var sourceImage; // we not require use TMP texture when not have MSAA if (stage.context.glVersion === 2 && StageSettings.ENABLE_MULTISAMPLE_TEXTURE) { sourceImage = stage.filterManager.popTemp(targetImage.width, targetImage.height, true); } //for DefaultRenderer when child has a blendmode applied if (useNonNativeBlend) { var proj = this.parentRenderer.view.projection; this.parentRenderer.view.projection = new PerspectiveProjection(); this.parentRenderer.view.target = targetImage; //this.parentRenderer.disableClear = true; this.parentRenderer._initRender(targetImage); this.parentRenderer.executeRender(); this.parentRenderer.resetHead(); //this.parentRenderer.disableClear = false; this.parentRenderer.view.target = null; this.parentRenderer.view.projection = proj; this._disableClear = true; } // we should render with colorTransform to self, enable it this.node.colorTransformDisabled = false; this._initRender(sourceImage || targetImage); _super.prototype.render.call(this, enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig); // restore colorTransform state as in transform state this.node.colorTransformDisabled = this.node.transformDisabled; if (targetImage.width * targetImage.height === 0) { throw new Error('Cannot have image with size 0 * 0'); } //@ts-ignore var filters = container.filters; if (filters && filters.length > 0) { filters.forEach(function (e) { return e && (e.imageScale = _this._boundsScale); }); stage.filterManager.applyFilters(sourceImage || targetImage, targetImage, // because we use source as filter target - we not require copy targetImage.rect, targetImage.rect, filters); } else if (sourceImage) { // this is fast, it should only call blitFramebuffer, // same as in regular MSAA stage.filterManager.copyPixels(sourceImage, targetImage, targetImage.rect, targetImage.rect.topLeft, useNonNativeBlend, useNonNativeBlend ? container.blendMode : ''); } if (sourceImage) { stage.filterManager.pushTemp(sourceImage); } // pop render target after any filters, // required for deep filters (when node with filter has filtered child) this.stage.popRenderTarget(); }; // apply blend modes and swap texture if needed CacheRenderer.prototype.preActivateRenderPass = function () { }; CacheRenderer.prototype.getNumTextures = function () { return this._textures.length; }; CacheRenderer.prototype.getTextureAt = function (index) { return this._textures[index]; }; CacheRenderer.prototype.addTexture = function (texture) { this._textures.push(texture); texture.addEventListener(AssetEvent.INVALIDATE, this._onTextureInvalidate); this.invalidate(); }; CacheRenderer.prototype.removeTexture = function (texture) { this._textures.splice(this._textures.indexOf(texture), 1); texture.removeEventListener(AssetEvent.INVALIDATE, this._onTextureInvalidate); this.invalidate(); }; /** * Marks the shader programs for all passes as invalid, so they will be recompiled before the next use. * * @private */ CacheRenderer.prototype.invalidatePasses = function () { this.dispatchEvent(new MaterialEvent(MaterialEvent.INVALIDATE_PASSES, this)); }; /** * */ CacheRenderer.prototype.enterNode = function (node) { var enter = _super.prototype.enterNode.call(this, node); if (enter && node.boundsVisible) this.applyEntity(node.getBoundsPrimitive(PickGroup.getInstance())); return enter; }; CacheRenderer.prototype.onInvalidate = function (event) { _super.prototype.onInvalidate.call(this, event); this.dispatchEvent(new RenderableEvent(RenderableEvent.INVALIDATE_ELEMENTS, this)); this.dispatchEvent(new RenderableEvent(RenderableEvent.INVALIDATE_STYLE, this)); this.invalidate(); this.invalidatePasses(); }; CacheRenderer.prototype.onClear = function (event) { this.removeTexture(this._texture); this._texture.clear(); this._texture = null; this._style.image.clear(); this._style.image = null; if (this._parentNode) { this._parentNode.removeEventListener(ContainerNodeEvent.INVALIDATE_MATRIX3D, this._onInvalidateParentNode); this._parentNode.removeEventListener(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM, this._onInvalidateColorTransform); } this.node.container.removeEventListener(RenderableEvent.INVALIDATE_STYLE, this._onInvalidateParentNode); this.node.container.removeEventListener(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM, this._onInvalidateColorTransform); _super.prototype.onClear.call(this, event); }; CacheRenderer.registerMaterial = function (renderMaterialClass, materialClass) { RenderGroup.getInstance(CacheRenderer).registerMaterial(renderMaterialClass, materialClass); }; CacheRenderer.assetType = '[renderer CacheRenderer]'; return CacheRenderer; }(RendererBase)); export { CacheRenderer }; var _Render_Renderer = /** @class */ (function (_super) { __extends(_Render_Renderer, _super); function _Render_Renderer() { return _super !== null && _super.apply(this, arguments) || this; } _Render_Renderer.prototype._getStageElements = function () { var asset = this._asset; var paddedBounds = asset.getPaddedBounds(); //const bounds = asset.getBounds(); var offsetX = 0; //paddedBounds.x - bounds.x; var offsetY = 0; //paddedBounds.y - bounds.y; var matrix3D = Matrix3D.CALCULATION_MATRIX; matrix3D.copyFrom(this.renderSceneTransform); matrix3D.appendScale(asset._boundsScale, asset._boundsScale, asset._boundsScale); matrix3D.appendTranslation(offsetX * 0.5, offsetY * 0.5, 0); matrix3D.invert(); var vectors = [ paddedBounds.left, paddedBounds.top, 0, paddedBounds.right, paddedBounds.bottom, 0, paddedBounds.right, paddedBounds.top, 0, paddedBounds.left, paddedBounds.top, 0, paddedBounds.left, paddedBounds.bottom, 0, paddedBounds.right, paddedBounds.bottom, 0, ]; matrix3D.transformVectors(vectors, vectors); var elements = this._elements; if (!elements) { elements = this._elements = new TriangleElements(new AttributesBuffer(5, 6)); elements.setPositions(vectors); elements.setUVs([0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1]); } else { elements.setPositions(vectors); } return elements.getAbstraction(this._stage); }; _Render_Renderer.prototype.executeRender = function (enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig) { if (enableDepthAndStencil === void 0) { enableDepthAndStencil = true; } if (surfaceSelector === void 0) { surfaceSelector = 0; } if (mipmapSelector === void 0) { mipmapSelector = 0; } if (maskConfig === void 0) { maskConfig = 0; } // disable cull, because for render to texture it is bugged this._stage.context.setCulling(ContextGLTriangleFace.NONE); _super.prototype.executeRender.call(this, enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig); }; _Render_Renderer.prototype._getRenderMaterial = function () { return this._asset.getAbstraction(this.entity.renderer.getRenderElements(this.stageElements.elements)); }; _Render_Renderer.prototype._getStyle = function () { return this._asset.style; }; _Render_Renderer.assetType = '[render Renderer]'; return _Render_Renderer; }(_Render_RenderableBase)); export { _Render_Renderer }; DefaultRenderer.registerMaterial(_Render_RendererMaterial, CacheRenderer); CacheRenderer.registerMaterial(_Render_RendererMaterial, CacheRenderer); RenderEntity.registerRenderable(_Render_Renderer, CacheRenderer);