| .forEach(map=> | .forEach(map=> | ||||
| !map.isRenderTargetTexture && map.userData.disposeOnIdle !== false && | !map.isRenderTargetTexture && map.userData.disposeOnIdle !== false && | ||||
| map.dispose && !isInScene(map) && map.dispose()) | map.dispose && !isInScene(map) && map.dispose()) | ||||
| this.unregisterMaterial(mat) // todo, re-add when material is added again to the scene. | |||||
| // this.unregisterMaterial(mat) // not unregistering on dispose, that has to be done explicitly. todo: make an easy way to do that. | |||||
| } | } | ||||
| private _materialMaps = new Map<string, Set<ITexture>>() | private _materialMaps = new Map<string, Set<ITexture>>() |
| protected _createTargetClass(clazz: Class<WebGLRenderTarget>, size: number[], options: WebGLRenderTargetOptions): IRenderTarget { | protected _createTargetClass(clazz: Class<WebGLRenderTarget>, size: number[], options: WebGLRenderTargetOptions): IRenderTarget { | ||||
| const processNewTarget = this._processNewTarget | const processNewTarget = this._processNewTarget | ||||
| const disposeTarget = this.disposeTarget.bind(this) | |||||
| return new class RenderTarget extends clazz implements IRenderTarget { | return new class RenderTarget extends clazz implements IRenderTarget { | ||||
| isTemporary?: boolean | isTemporary?: boolean | ||||
| sizeMultiplier?: number | sizeMultiplier?: number | ||||
| super.copy(source as any) | super.copy(source as any) | ||||
| return this | return this | ||||
| } | } | ||||
| // Note - by default unregister need to be false. | |||||
| dispose(unregister = false) { | |||||
| if (unregister === true) disposeTarget(this, true) | |||||
| else super.dispose() | |||||
| } | |||||
| }(this, ...size, options) | }(this, ...size, options) | ||||
| } | } | ||||
| return target | return target | ||||
| } | } | ||||
| disposeTarget(target: IRenderTarget): void { | |||||
| /** | |||||
| * Dispose and remove tracked target. Release target in-case of temporary target. | |||||
| * To just dispose from the GPU memory and keep reference, call `target.dispose()` or `target.dispose(false)` | |||||
| * @param target | |||||
| * @param remove | |||||
| */ | |||||
| disposeTarget(target: IRenderTarget, remove = true): void { | |||||
| if (!target) return | if (!target) return | ||||
| if (target.isTemporary) return this.releaseTempTarget(target) | if (target.isTemporary) return this.releaseTempTarget(target) | ||||
| this.removeTrackedTarget(target) | |||||
| target.dispose() | |||||
| if (remove) this.removeTrackedTarget(target) | |||||
| // @ts-expect-error internal, not in types | |||||
| target.dispose(false) // false is not required but still passing so that it doesnt cause infinite loop in future. | |||||
| } | } | ||||
| getTempTarget<T extends IRenderTarget = IRenderTarget>(op: CreateRenderTargetOptions = {}): T { | getTempTarget<T extends IRenderTarget = IRenderTarget>(op: CreateRenderTargetOptions = {}): T { |
| ;(window as any).threeViewers?.splice((window as any).threeViewers.indexOf(this), 1) | ;(window as any).threeViewers?.splice((window as any).threeViewers.indexOf(this), 1) | ||||
| if (this.resizeObserver) this.resizeObserver.unobserve(this._canvas) | if (this.resizeObserver) this.resizeObserver.unobserve(this._canvas) | ||||
| else window.removeEventListener('resize', this.resize) | |||||
| window.removeEventListener('resize', this.resize) | |||||
| this.dispatchEvent({type: 'dispose'}) | this.dispatchEvent({type: 'dispose'}) | ||||
| } | } |