module BABYLON { export class PostProcessRenderEffect { private _engine: Engine; private _postProcesses: any; private _getPostProcess: () => PostProcess; private _singleInstance: boolean; private _cameras: Camera[]; private _indicesForCamera: number[][]; private _renderPasses: any; private _renderEffectAsPasses: any; // private public _name: string; public applyParameters: (postProcess: PostProcess) => void; constructor(engine: Engine, name: string, getPostProcess: () => PostProcess, singleInstance?: boolean) { this._engine = engine; this._name = name; this._singleInstance = singleInstance || true; this._getPostProcess = getPostProcess; this._cameras = []; this._indicesForCamera = []; this._postProcesses = {}; this._renderPasses = {}; this._renderEffectAsPasses = {}; } public _update(): void { for (var renderPassName in this._renderPasses) { this._renderPasses[renderPassName]._update(); } } public addPass(renderPass: PostProcessRenderPass): void { this._renderPasses[renderPass._name] = renderPass; this._linkParameters(); } public removePass(renderPass: PostProcessRenderPass): void { delete this._renderPasses[renderPass._name]; this._linkParameters(); } public addRenderEffectAsPass(renderEffect: PostProcessRenderEffect): void { this._renderEffectAsPasses[renderEffect._name] = renderEffect; this._linkParameters(); } public getPass(passName: string): void { for (var renderPassName in this._renderPasses) { if (renderPassName === passName) { return this._renderPasses[passName]; } } } public emptyPasses(): void { this._renderPasses = {}; this._linkParameters(); } // private public _attachCameras(cameras: Camera); public _attachCameras(cameras: Camera[]); public _attachCameras(cameras: any): void { var cameraKey; var _cam = Tools.MakeArray(cameras || this._cameras); for (var i = 0; i < _cam.length; i++) { var camera = _cam[i]; var cameraName = camera.name; if (this._singleInstance) { cameraKey = 0; } else { cameraKey = cameraName; } this._postProcesses[cameraKey] = this._postProcesses[cameraKey] || this._getPostProcess(); var index = camera.attachPostProcess(this._postProcesses[cameraKey]); if (!this._indicesForCamera[cameraName]) { this._indicesForCamera[cameraName] = []; } this._indicesForCamera[cameraName].push(index); if (this._cameras.indexOf(camera) === -1) { this._cameras[cameraName] = camera; } for (var passName in this._renderPasses) { this._renderPasses[passName]._incRefCount(); } } this._linkParameters(); } // private public _detachCameras(cameras: Camera); public _detachCameras(cameras: Camera[]); public _detachCameras(cameras: any): void { var _cam = Tools.MakeArray(cameras || this._cameras); for (var i = 0; i < _cam.length; i++) { var camera = _cam[i]; var cameraName = camera.name; camera.detachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName], this._indicesForCamera[cameraName]); var index = this._cameras.indexOf(cameraName); this._indicesForCamera.splice(index, 1); this._cameras.splice(index, 1); for (var passName in this._renderPasses) { this._renderPasses[passName]._decRefCount(); } } } // private public _enable(cameras: Camera); public _enable(cameras: Camera[]); public _enable(cameras: any): void { var _cam = Tools.MakeArray(cameras || this._cameras); for (var i = 0; i < _cam.length; i++) { var camera = _cam[i]; var cameraName = camera.name; for (var j = 0; j < this._indicesForCamera[cameraName].length; j++) { if (camera._postProcesses[this._indicesForCamera[cameraName][j]] === undefined) { cameras[i].attachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName], this._indicesForCamera[cameraName][j]); } } for (var passName in this._renderPasses) { this._renderPasses[passName]._incRefCount(); } } } // private public _disable(cameras: Camera); public _disable(cameras: Camera[]); public _disable(cameras: any): void { var _cam = Tools.MakeArray(cameras || this._cameras); for (var i = 0; i < _cam.length; i++) { var camera = _cam[i]; var cameraName = camera.Name; camera.detachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName], this._indicesForCamera[cameraName]); for (var passName in this._renderPasses) { this._renderPasses[passName]._decRefCount(); } } } public getPostProcess(camera?: Camera): PostProcess { if (this._singleInstance) { return this._postProcesses[0]; } else { return this._postProcesses[camera.name]; } } private _linkParameters(): void { for (var index in this._postProcesses) { if (this.applyParameters) { this.applyParameters(this._postProcesses[index]); } this._postProcesses[index].onBeforeRender = (effect: Effect) => { this._linkTextures(effect); }; } } private _linkTextures(effect): void { for (var renderPassName in this._renderPasses) { effect.setTexture(renderPassName, this._renderPasses[renderPassName].getRenderTexture()); } for (var renderEffectName in this._renderEffectAsPasses) { effect.setTextureFromPostProcess(renderEffectName + "Sampler", this._renderEffectAsPasses[renderEffectName].getPostProcess()); } } } }