UNPKG

@awayjs/renderer

Version:
286 lines (285 loc) 13.5 kB
import { __extends } from "tslib"; import { AssetEvent, Matrix3D, PerspectiveProjection, } from '@awayjs/core'; import { AttributesBuffer, Image2D, ContextGLTriangleFace, StageEvent, ImageSampler } from '@awayjs/stage'; import { ContainerNodeEvent, HierarchicalProperty, 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 { 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._onInvalidateSceneTransform = function (event) { return _this.onInvalidateSceneTransform(); }; _this._onInvalidateColorTransform = function (event) { return _this.onInvalidateColorTransform(); }; _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._onInvalidateElements = function () { // for (const key in this._abstractionPool) // (this._abstractionPool[key] as _Render_RenderableBase)._onInvalidateElements(); }; CacheRenderer.prototype._onInvalidateMaterial = function () { // for (const key in this._abstractionPool) // (this._abstractionPool[key] as _Render_RenderableBase)._onInvalidateMaterial(); }; CacheRenderer.prototype.init = function (node, group) { _super.prototype.init.call(this, node, group); node.view.stage.addEventListener(StageEvent.INVALIDATE_SIZE, this._onSizeInvalidateDelegate); if (this._parentNode) { this._parentNode.addEventListener(ContainerNodeEvent.INVALIDATE_MATRIX3D, this._onInvalidateSceneTransform); this._parentNode.addEventListener(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM, this._onInvalidateColorTransform); } // for check filters/blends changes node.container._renderObjects[group.id] = this; this.texture = new ImageTexture2D(); }; CacheRenderer.prototype.render = 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; } 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 msaa = stage.context.glVersion === 2 && StageSettings.ENABLE_MULTISAMPLE_TEXTURE; // we not require use TMP texture when not have MSAA var sourceImage = (msaa) ? stage.filterManager.popTemp(targetImage.width, targetImage.height, true) : targetImage; //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; } this._initRender(sourceImage); _super.prototype.render.call(this, enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig); if (targetImage.width * targetImage.height === 0) { throw new Error('Cannot have image with size 0 * 0'); } //@ts-ignore var filters = container.filters; var scale = this.getBoundsScale(); if (filters && filters.length > 0) { filters.forEach(function (e) { return e && (e.imageScale = scale); }); stage.filterManager.applyFilters(sourceImage, targetImage, // because we use source as filter target - we not require copy targetImage.rect, targetImage.rect, filters); } else if (msaa) { // 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 (msaa) { stage.filterManager.pushTemp(sourceImage); } // pop render target after any filters, // required for deep filters (when node with filter has filtered child) this.stage.popRenderTarget(); }; CacheRenderer.prototype._updateBounds = function () { _super.prototype._updateBounds.call(this); var image = this._style.image; var pad = this._paddedBounds; if (image) { this._style.image._setSize(pad.width, pad.height); } else { this._style.image = new Image2D(pad.width, pad.height, false); this._style.sampler = new ImageSampler(false, false, false); //this._view.target = this._style.image; } }; // 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 () { _super.prototype.onInvalidate.call(this); for (var key in this._renderObjects) this._renderObjects[key]._onInvalidateElements(); for (var key in this._renderObjects) this._renderObjects[key]._onInvalidateStyle(); this.invalidate(); this.invalidatePasses(); }; CacheRenderer.prototype.onInvalidateSceneTransform = function () { this._asset.invalidateHierarchicalProperty(HierarchicalProperty.SCENE_TRANSFORM); this.onInvalidate(); }; CacheRenderer.prototype.onInvalidateColorTransform = function () { this._asset.invalidateHierarchicalProperty(HierarchicalProperty.COLOR_TRANSFORM); this.invalidate(); }; CacheRenderer.prototype.onClear = function () { this.removeTexture(this._texture); this._texture.clear(); this._texture = null; this._style.image.clear(); this._style.image = null; this._asset.view.stage.removeEventListener(StageEvent.INVALIDATE_SIZE, this._onSizeInvalidateDelegate); if (this._parentNode) { this._parentNode.removeEventListener(ContainerNodeEvent.INVALIDATE_MATRIX3D, this._onInvalidateSceneTransform); this._parentNode.removeEventListener(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM, this._onInvalidateColorTransform); } var container = this._asset.container; if (container) delete container._renderObjects[this.group.id]; _super.prototype.onClear.call(this); }; 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.renderable; var paddedBounds = asset.getPaddedBounds(); var matrix3D = Matrix3D.CALCULATION_MATRIX; var scale = asset.getBoundsScale(); matrix3D.copyFrom(this.entity.renderSceneTransform); matrix3D.appendScale(scale, scale, scale); 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 this._stage.abstractions.getAbstraction(elements); }; _Render_Renderer.prototype.draw = 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.draw.call(this); }; _Render_Renderer.prototype._getRenderMaterial = function () { return this.entity.renderer .getRenderElements(this.stageElements.elements).abstractions .getAbstraction(this.renderable); }; _Render_Renderer.prototype._getStyle = function () { return this.renderable.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);