@awayjs/renderer
Version:
Renderer for AwayJS
260 lines (259 loc) • 12.8 kB
JavaScript
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);