UNPKG

@awayjs/renderer

Version:
754 lines (748 loc) 32.1 kB
import { __extends } from "tslib"; import { Matrix3D, Vector3D, AbstractionBase, Box, Rectangle, WeakAssetSet, } from '@awayjs/core'; import { ContextGLBlendFactor, ContextGLCompareMode, ContextGLStencilAction, ContextGLTriangleFace, StageEvent, ContextGLClearMask, Image2D, ImageSampler, BlendMode, isNativeBlend, Settings as StageSettings } from '@awayjs/stage'; import { ViewEvent, PickGroup, } from '@awayjs/view'; import { Settings } from './Settings'; import { RenderEntity } from './base/RenderEntity'; import { RenderGroup } from './RenderGroup'; import { RenderableMergeSort } from './sort/RenderableMergeSort'; import { Style } from './base/Style'; import { StyleEvent } from './events/StyleEvent'; import { RenderableEvent } from './events/RenderableEvent'; /** * RendererBase forms an abstract base class for classes that are used in the rendering pipeline to render the * contents of a partition * * @class away.render.RendererBase */ var RendererBase = /** @class */ (function (_super) { __extends(RendererBase, _super); function RendererBase() { var _this = _super.call(this) || this; _this._renderMatrix = new Matrix3D(); /*internal*/ _this._boundsScale = 1; _this._paddedBounds = new Rectangle(); _this._bounds = new Box(); _this._boundsDirty = true; _this._mappers = new Array(); _this._elementsPools = {}; _this._cameraForward = new Vector3D(); _this._depthTextureDirty = true; _this._depthPrepass = false; _this._pNumElements = 0; _this._renderEntities = new WeakAssetSet('RenderEntity'); _this._opaqueRenderables = []; _this._blendedRenderables = []; _this._disableColor = false; _this._disableClear = false; _this._renderBlended = true; _this._numCullPlanes = 0; /** * */ _this.renderableSorter = new RenderableMergeSort(); _this._onInvalidateProperties = function (_event) { return _this._invalidateStyle(); }; _this._onSizeInvalidateDelegate = function (event) { return _this.onSizeInvalidate(event); }; _this._onContextUpdateDelegate = function (event) { return _this.onContextUpdate(event); }; return _this; } Object.defineProperty(RendererBase.prototype, "cullPlanes", { /** * */ get: function () { return this._customCullPlanes; }, set: function (value) { this._customCullPlanes = value; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "renderBlended", { get: function () { return this._renderBlended; }, set: function (value) { this._renderBlended = value; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "disableColor", { get: function () { return this._disableColor; }, set: function (value) { if (this._disableColor == value) return; this._disableColor = value; this._invalid = true; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "disableClear", { get: function () { return this._disableClear; }, set: function (value) { if (this._disableClear == value) return; this._disableClear = value; this._invalid = true; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "numElements", { /** * */ get: function () { return this._pNumElements; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "context", { get: function () { return this._context; }, enumerable: false, configurable: true }); RendererBase.prototype.getPaddedBounds = function () { if (this._boundsDirty) this._updateBounds(); return this._paddedBounds; }; RendererBase.prototype.getBounds = function () { if (this._boundsDirty) this._updateBounds(); return this._bounds; }; Object.defineProperty(RendererBase.prototype, "style", { /** * */ get: function () { if (this._boundsDirty) this._updateBounds(); return this._style; }, set: function (value) { if (this._style == value) return; if (this._style) this._style.removeEventListener(StyleEvent.INVALIDATE_PROPERTIES, this._onInvalidateProperties); this._style = value; if (this._style) this._style.addEventListener(StyleEvent.INVALIDATE_PROPERTIES, this._onInvalidateProperties); this._invalidateStyle(); }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "node", { get: function () { return this._asset; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "group", { get: function () { return this._pool; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "blendMode", { get: function () { var containerBlend = this.node.container.blendMode; // native blends if (isNativeBlend(containerBlend)) return containerBlend; return BlendMode.LAYER; }, enumerable: false, configurable: true }); Object.defineProperty(RendererBase.prototype, "useNonNativeBlend", { get: function () { return StageSettings.USE_NON_NATIVE_BLEND && this._asset.container.blendMode && this._asset.container.blendMode !== BlendMode.LAYER && this.blendMode == BlendMode.LAYER; }, enumerable: false, configurable: true }); /** * Creates a new RendererBase object. */ RendererBase.prototype.init = function (node, group) { _super.prototype.init.call(this, node, group); this._parentNode = node.parent; this.style = new Style(); this.view = node.view; this.stage = this.view.stage; this.stage.addEventListener(StageEvent.CONTEXT_CREATED, this._onContextUpdateDelegate); this.stage.addEventListener(StageEvent.CONTEXT_RECREATED, this._onContextUpdateDelegate); this.view.addEventListener(ViewEvent.INVALIDATE_SIZE, this._onSizeInvalidateDelegate); this._boundsPicker = PickGroup.getInstance().getBoundsPicker(this.node); if (this.stage.context) this._context = this.stage.context; }; RendererBase.prototype.onClear = function (event) { this.clear(); _super.prototype.onClear.call(this, event); this.stage.removeEventListener(StageEvent.CONTEXT_CREATED, this._onContextUpdateDelegate); this.stage.removeEventListener(StageEvent.CONTEXT_RECREATED, this._onContextUpdateDelegate); this.view.removeEventListener(ViewEvent.INVALIDATE_SIZE, this._onSizeInvalidateDelegate); this.parentRenderer = null; this._parentNode = null; this._boundsPicker = null; this._activeMasksDirty = false; this._activeMaskOwners = null; this._renderEntity = null; if (this._style) { this._style.removeEventListener(StyleEvent.INVALIDATE_PROPERTIES, this._onInvalidateProperties); this._style = null; } this._renderEntities.forEach(function (entity) { return entity.onClear(event); }); this.resetHead(); for (var key in this._elementsPools) { this._elementsPools[key].clear(); delete this._elementsPools[key]; } this._boundsDirty = true; this._entityMaskOwners = null; this._disableColor = false; this._disableClear = false; this._renderBlended = true; }; RendererBase.prototype.onInvalidate = function (event) { _super.prototype.onInvalidate.call(this, event); this._boundsDirty = true; }; RendererBase.prototype.addRenderEntity = function (renderEntity) { this._renderEntities.add(renderEntity); }; RendererBase.prototype.removeRenderEntity = function (renderEntity) { this._renderEntities.remove(renderEntity); }; RendererBase.prototype.update = function (node) { //update mappers var len = this._mappers.length; for (var i = 0; i < len; i++) this._mappers[i].update(node); }; RendererBase.prototype._addMapper = function (mapper) { if (this._mappers.indexOf(mapper) != -1) return; this._mappers.push(mapper); }; RendererBase.prototype._removeMapper = function (mapper) { var index = this._mappers.indexOf(mapper); if (index != -1) this._mappers.splice(index, 1); }; RendererBase.prototype.getRenderElements = function (elements) { return this._elementsPools[elements.assetType] || (this._elementsPools[elements.assetType] = new (RenderGroup.getRenderElementsClass(elements))(this)); }; RendererBase.prototype.requestAbstraction = function (asset) { return RendererBase._store.length ? RendererBase._store.pop() : new RenderEntity(); }; RendererBase.prototype.storeAbstraction = function (abstraction) { RendererBase._store.push(abstraction); }; /** * Renders the potentially visible geometry to the back buffer or texture. * @param target An option target texture to render to. * @param surfaceSelector The index of a CubeTexture's face to render to. * @param additionalClearMask Additional clear mask information, in case extra clear channels are to be omitted. */ RendererBase.prototype.render = function (enableDepthAndStencil, surfaceSelector, mipmapSelector, maskConfig) { //TODO refactor setTarget so that rendertextures are created before this check // if (!this._stage || !this._context) // return; if (enableDepthAndStencil === void 0) { enableDepthAndStencil = true; } if (surfaceSelector === void 0) { surfaceSelector = 0; } if (mipmapSelector === void 0) { mipmapSelector = 0; } if (maskConfig === void 0) { maskConfig = 0; } this._enableDepthAndStencil = enableDepthAndStencil; this._surfaceSelector = surfaceSelector; this._mipmapSelector = mipmapSelector; this._maskConfig = maskConfig; //check for mask rendering if (this._maskConfig) { this._disableClear = true; this._disableColor = true; } this.update(this._asset); // invalidate mipmaps (if target exists) to regenerate if required if (this.view.target) this.view.target.invalidateMipmaps(); // this._pRttViewProjectionMatrix.copyFrom(projection.viewMatrix3D); // this._pRttViewProjectionMatrix.appendScale(this.textureRatioX, this.textureRatioY, 1); /* if (_backgroundImageRenderer) _backgroundImageRenderer.render(); */ if (!StageSettings.USE_NON_NATIVE_BLEND || this._invalid) this.traverse(); this.executeRender(enableDepthAndStencil, surfaceSelector, mipmapSelector); //line required for correct rendering when using away3d with starling. //DO NOT REMOVE UNLESS STARLING INTEGRATION IS RETESTED! //this._context.setDepthTest(false, ContextGLCompareMode.LESS_EQUAL); //oopsie if (!this.view.shareContext || this.view.target) { if (this._snapshotRequired && this._snapshotBitmapImage2D) { this._context.drawToBitmapImage2D(this._snapshotBitmapImage2D); this._snapshotRequired = false; } } }; RendererBase.prototype.resetHead = function () { //reset head values this._blendedRenderables = []; this._opaqueRenderables = []; }; RendererBase.prototype.traverse = function () { this.resetHead(); this._invalid = false; this._pNumElements = 0; this._activeMaskOwners = null; this._cameraTransform = this.view.projection.transform.matrix3D; this._cameraForward = this.view.projection.transform.forwardVector; this._cullPlanes = this._customCullPlanes ? this._customCullPlanes : this.view.projection.viewFrustumPlanes; this._numCullPlanes = this._cullPlanes ? this._cullPlanes.length : 0; this._maskId = this._asset.getMaskId(); RendererBase._collectionMark++; this._asset.acceptTraverser(this); //sort the resulting renderables if (this.renderableSorter) { // this._pOpaqueRenderableHead = this.renderableSorter.sortOpaqueRenderables(this._pOpaqueRenderableHead); // this._pBlendedRenderableHead = this.renderableSorter.sortBlendedRenderables(this._pBlendedRenderableHead); } }; RendererBase.prototype._iRenderCascades = function (enableDepthAndStencil, surfaceSelector) { // this._stage.setRenderTarget(target, true, 0); // this._context.clear(1, 1, 1, 1, 1, 0); if (enableDepthAndStencil === void 0) { enableDepthAndStencil = true; } if (surfaceSelector === void 0) { surfaceSelector = 0; } // this._context.setBlendFactors(ContextGLBlendFactor.ONE, ContextGLBlendFactor.ZERO); // this._context.setDepthTest(true, ContextGLCompareMode.LESS); // var head:_Render_RenderableBase = this._pOpaqueRenderableHead; // var first:boolean = true; // //TODO cascades must have separate collectors, rather than separate draw commands // for (var i:number = numCascades - 1; i >= 0; --i) { // //this._stage.scissorRect = scissorRects[i]; // //this.drawCascadeRenderables(head, cameras[i], first? null : cameras[i].frustumPlanes); // first = false; // } // line required for correct rendering when using away3d with starling. // DO NOT REMOVE UNLESS STARLING INTEGRATION IS RETESTED! // this._context.setDepthTest(false, ContextGLCompareMode.LESS_EQUAL); }; /** * Renders the potentially visible geometry to the back buffer or texture. Only executed if everything is set up. * * @param target An option target texture to render to. * @param surfaceSelector The index of a CubeTexture's face to render to. * @param additionalClearMask Additional clear mask information, in case extra clear channels are to be omitted. */ RendererBase.prototype.executeRender = function (enableDepthAndStencil, surfaceSelector, mipmapSelector) { if (enableDepthAndStencil === void 0) { enableDepthAndStencil = true; } if (surfaceSelector === void 0) { surfaceSelector = 0; } if (mipmapSelector === void 0) { mipmapSelector = 0; } //TODO: allow sharedContexts for image targets this.view.clear(!this._depthPrepass && !this._disableClear, enableDepthAndStencil, surfaceSelector, mipmapSelector, (!this.view.shareContext || this.view.target) ? ContextGLClearMask.ALL : ContextGLClearMask.DEPTH); //initialise blend mode this._context.setBlendFactors(ContextGLBlendFactor.ONE, ContextGLBlendFactor.ZERO); //initialise depth test this._context.setDepthTest(true, ContextGLCompareMode.LESS_EQUAL); //initialise color mask if (this._disableColor) this._context.setColorMask(false, false, false, false); else this._context.setColorMask(true, true, true, true); //initialise stencil if (this._maskConfig) this._context.enableStencil(); else this._context.disableStencil(); this.drawRenderables(this._opaqueRenderables); if (this._renderBlended) this.drawRenderables(this._blendedRenderables); }; /* * Will draw the renderer's output on next render to the provided bitmap data. * */ RendererBase.prototype.queueSnapshot = function (bmd) { this._snapshotRequired = true; this._snapshotBitmapImage2D = bmd; }; //private drawCascadeRenderables(renderRenderable:_Render_RenderableBase, camera:Camera, cullPlanes:Array<Plane3D>) //{ // var renderRenderable2:_Render_RenderableBase; // var render:_Render_MaterialBase; // var pass:IPass; // // while (renderRenderable) { // renderRenderable2 = renderRenderable; // render = renderRenderable.render; // pass = render.passes[0] //assuming only one pass per material // // this.activatePass(renderRenderable, pass, camera); // // do { // // if completely in front, it will fall in a different cascade // // do not use near and far planes // if (!cullPlanes || renderRenderable2.node.worldBounds.isInFrustum(cullPlanes, 4)) { // renderRenderable2._iRender(pass, camera, this._pRttViewProjectionMatrix); // } else { // renderRenderable2.cascaded = true; // } // // renderRenderable2 = renderRenderable2.next; // // } while (renderRenderable2 && renderRenderable2.render == render && !renderRenderable2.cascaded); // // this.deactivatePass(renderRenderable, pass); // // renderRenderable = renderRenderable2; // } //} /** * Draw a list of renderables. * * @param renderables The renderables to draw. */ RendererBase.prototype.drawRenderables = function (renderRenderables) { var index = 0; var len = renderRenderables.length; var renderRenderable = renderRenderables[index]; var renderMaterial; var numPasses; var i; var r; while (index < len) { renderMaterial = renderRenderable.renderMaterial; numPasses = renderMaterial ? renderMaterial.numPasses : 1; if (this._activeMasksDirty || this._checkMaskOwners(renderRenderable.maskOwners)) { if (!(this._activeMaskOwners = renderRenderable.maskOwners)) { //re-establish stencil settings (if not inside another mask) if (!this._maskConfig) this._context.disableStencil(); } else { this._renderMasks(this._activeMaskOwners); } this._activeMasksDirty = false; } //iterate through each shader object for (var p = 0; p < numPasses; p++) { renderMaterial && renderMaterial.activatePass(p); i = index; r = renderRenderable; do { ///console.log("maskOwners", renderRenderable2.maskOwners); r.executeRender(this._enableDepthAndStencil, this._surfaceSelector, this._mipmapSelector, this._maskConfig); if (++i == len) break; r = renderRenderables[i]; } while (r.renderMaterial == renderMaterial && !(this._activeMasksDirty = this._checkMaskOwners(r.maskOwners))); renderMaterial && renderMaterial.deactivatePass(); } index = i; renderRenderable = r; } }; /** * Assign the context once retrieved */ RendererBase.prototype.onContextUpdate = function (event) { this._context = this.stage.context; }; /* public get iBackground():Texture2DBase { return this._background; } */ /* public set iBackground(value:Texture2DBase) { if (this._backgroundImageRenderer && !value) { this._backgroundImageRenderer.dispose(); this._backgroundImageRenderer = null; } if (!this._backgroundImageRenderer && value) { this._backgroundImageRenderer = new BackgroundImageRenderer(this._stage); } this._background = value; if (this._backgroundImageRenderer) this._backgroundImageRenderer.texture = value; } */ /* public get backgroundImageRenderer():BackgroundImageRenderer { return _backgroundImageRenderer; } */ /** * */ RendererBase.prototype.onSizeInvalidate = function (event) { if (this._pRttBufferManager) { this._pRttBufferManager.viewWidth = this.view.width; this._pRttBufferManager.viewHeight = this.view.height; } this._depthTextureDirty = true; }; /** * * @param node * @returns {boolean} */ RendererBase.prototype.enterNode = function (node) { var maskOrFrustrum = (this._maskConfig || node.isInFrustum(this._asset, this._cullPlanes, this._numCullPlanes, PickGroup.getInstance())); var enter = node._collectionMark != RendererBase._collectionMark && node.isRenderable() && maskOrFrustrum && node.getMaskId() == this._maskId; node._collectionMark = RendererBase._collectionMark; return enter; }; RendererBase.prototype.getTraverser = function (rootNode) { if (rootNode.renderToImage) { //new node for the container var node = rootNode.getLocalNode(); var boundsPicker = PickGroup.getInstance().getBoundsPicker(node); if (!boundsPicker.getBoxBounds(node, true, true)) return this; var traverser = this._traverserGroup.getRenderer(node); traverser.renderableSorter = null; traverser.parentRenderer = this; //if (this._invalid) { this._renderEntity = node.getAbstraction(this); // project onto camera's z-axis this._zIndex = this._cameraTransform.position.subtract(rootNode.getPosition()) .dotProduct(this._cameraForward) + rootNode.container.zOffset; //save sceneTransform this._renderSceneTransform = rootNode.getRenderMatrix3D(this._cameraTransform); //save mask id this._entityMaskId = rootNode.getMaskId(); this._entityMaskOwners = rootNode.getMaskOwners(); this.applyTraversable(traverser); //} return traverser; } return this; }; RendererBase.prototype.applyEntity = function (node) { var _a; var entity = node.container.getEntity(); if (entity) { this._renderEntity = node.getAbstraction(this); // project onto camera's z-axis this._zIndex = this._cameraTransform.position.subtract(node.getPosition()) .dotProduct(this._cameraForward) + node.container.zOffset; //save sceneTransform this._renderSceneTransform = node.getRenderMatrix3D(this._cameraTransform); //save mask id this._entityMaskId = node.getMaskId(); this._entityMaskOwners = node.getMaskOwners(); //collect renderables entity._acceptTraverser(this); } else { //check if we have a RenderEntity abstraction and if so, clear it! (_a = node.checkAbstraction(this)) === null || _a === void 0 ? void 0 : _a.onClear(null); } }; RendererBase.prototype.applyTraversable = function (traversable) { var renderRenderable = traversable.getAbstraction(this._renderEntity); //store renderable properties renderRenderable.cascaded = false; renderRenderable.zIndex = this._zIndex; renderRenderable.maskId = this._entityMaskId; renderRenderable.maskOwners = this._entityMaskOwners; renderRenderable.renderSceneTransform = this._renderSceneTransform; var renderMaterial = renderRenderable.renderMaterial; renderRenderable.materialID = renderMaterial.materialID; renderRenderable.renderOrderId = renderMaterial.renderOrderId; if (renderMaterial.requiresBlending) { this._blendedRenderables.push(renderRenderable); } else { this._opaqueRenderables.push(renderRenderable); } //need to re-trigger stageElements getter in case animator has changed this._pNumElements += renderRenderable.stageElements.elements.numElements; }; RendererBase.prototype._renderMasks = function (maskOwners) { //calculate the bit index of maskConfig devided by two var halfBitIndex = Math.log2(this._maskConfig) >> 1; //create a new base and config value for the mask to be rendered //maskBase set to next odd significant bit var newMaskBase = this._maskConfig ? Math.pow(2, (halfBitIndex + 1) << 1) : 1; var newMaskConfig = newMaskBase; if (newMaskConfig > 0xff) { console.warn('[RenderBase] Mask bit overflow, maskConfig %d', newMaskConfig); return; } this._context.enableStencil(); var numLayers = maskOwners.length; var children; var numChildren; var first = true; for (var i = 0; i < numLayers; ++i) { children = maskOwners[i].getMasks(); numChildren = children.length; if (numChildren) { this._context.setStencilActions(ContextGLTriangleFace.FRONT_AND_BACK, (first) ? ContextGLCompareMode.ALWAYS : ContextGLCompareMode.EQUAL, ContextGLStencilAction.SET, ContextGLStencilAction.SET, ContextGLStencilAction.KEEP); first = false; //flips between read odd write even to read even write odd this._context.setStencilReferenceValue(0xFF, newMaskConfig, newMaskConfig = (newMaskConfig & newMaskBase) + newMaskBase); //clears write mask to zero this._context.clear(0, 0, 0, 0, 0, 0, ContextGLClearMask.STENCIL); for (var j = 0; j < numChildren; ++j) this._maskGroup.getRenderer(children[j]).render(true, 0, 0, newMaskConfig); } } if (!first) { this._context.setStencilActions(ContextGLTriangleFace.FRONT_AND_BACK, ContextGLCompareMode.EQUAL, ContextGLStencilAction.SET, ContextGLStencilAction.SET, ContextGLStencilAction.KEEP); } //reads from mask output, writes to previous mask state this._context.setStencilReferenceValue(0xFF, newMaskConfig, this._maskConfig); //re-establish color mask settings (if not inside another mask) if (!this._disableColor) { this._context.setColorMask(true, true, true, true); } }; RendererBase.prototype._checkMaskOwners = function (maskOwners) { if (this._activeMaskOwners == null || maskOwners == null) return Boolean(this._activeMaskOwners != maskOwners); if (this._activeMaskOwners.length != maskOwners.length) return true; var numLayers = maskOwners.length; var numMasks; var masks; var activeNumMasks; var activeMasks; for (var i = 0; i < numLayers; i++) { masks = maskOwners[i].getMasks(); numMasks = masks.length; activeMasks = this._activeMaskOwners[i].getMasks(); activeNumMasks = activeMasks.length; if (activeNumMasks != numMasks) return true; for (var j = 0; j < numMasks; j++) { if (activeMasks[j] != masks[j]) return true; } } return false; }; RendererBase.prototype._invalidateStyle = function () { this.dispatchEvent(new RenderableEvent(RenderableEvent.INVALIDATE_STYLE, this)); }; RendererBase.prototype._updateBounds = function () { this._boundsDirty = false; var matrix3D = this._renderMatrix; var container = this._asset.container; var pad = this._paddedBounds; var scale; if (this._parentNode) { scale = Math.min(3, this._parentNode.view.projection.scale); matrix3D.copyFrom(this._parentNode.getMatrix3D()); } else { // no parent - no transform scale = Math.min(3, this.view.projection.scale); matrix3D.identity(); } //scale = 1; this._boundsScale = scale; if (scale !== 1) matrix3D.appendScale(scale, scale, scale); var bounds = this._boundsPicker.getBoxBounds(this._asset, true, true); if (!bounds) { console.error('[CachedRenderer] Bounds invalid, supress calculation', this._asset); return; } if (isNaN(bounds.width) || isNaN(bounds.height)) { console.error('[CachedRenderer] Bounds invalid (NaN), supress calculation', this._asset); return; } this._bounds.copyFrom(bounds); matrix3D.transformBox(this._bounds, this._bounds); matrix3D.invert(); if (this.useNonNativeBlend) { //set to bounds of parent var parentBounds = this.parentRenderer.getPaddedBounds(); pad.setTo(parentBounds.x, parentBounds.y, parentBounds.width, parentBounds.height); this._style.image = this.parentRenderer.style.image; this._style.sampler = new ImageSampler(false, Settings.SMOOTH_CACHED_IMAGE, false); } else { pad.setTo(this._bounds.x, this._bounds.y, this._bounds.width, this._bounds.height); if (container.filters && container.filters.length > 0) { container.filters.forEach(function (e) { return e && (e.imageScale = scale); }); this.stage.filterManager.computeFiltersPadding(pad, container.filters, pad); } pad.x = (pad.x - 2) | 0; pad.y = (pad.y - 2) | 0; pad.width = (pad.width + 4) | 0; pad.height = (pad.height + 4) | 0; var image = this._style.image; if (pad.width * pad.height == 0) { throw new Error('Cannot have image with size 0 * 0'); } 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, Settings.SMOOTH_CACHED_IMAGE, false); //this._view.target = this._style.image; } } }; RendererBase.prototype._initRender = function (target) { var pad = this._paddedBounds; var scale = this._boundsScale; var matrix3D = this._renderMatrix; var ox = 0; //pad.x - this._bounds.x; var oy = 0; //pad.y - this._bounds.y; var view = this.view; var proj = view.projection; matrix3D._rawData[14] = -1000; // without this we will handle empty image when target is big (scale > +3) proj.far = 4000; proj.near = 1; proj.transform.matrix3D = matrix3D; proj.ratio = (target.width / target.height); proj.originX = -1 - 2 * (pad.x - ox * 0.5) / target.width; proj.originY = -1 - 2 * (pad.y - oy * 0.5) / target.height; proj.scale = scale * 1000 / target.height; view.target = target; }; RendererBase._store = []; RendererBase._collectionMark = 0; return RendererBase; }(AbstractionBase)); export { RendererBase };