|
@@ -18,13 +18,42 @@ export class EffectRenderer {
|
|
private _vertexBuffers: {[key: string]: VertexBuffer};
|
|
private _vertexBuffers: {[key: string]: VertexBuffer};
|
|
private _indexBuffer: DataBuffer;
|
|
private _indexBuffer: DataBuffer;
|
|
|
|
|
|
- private _tmpScreenBuffer: Nullable<Texture> = null;
|
|
|
|
|
|
+ private _ringBufferIndex = 0;
|
|
|
|
+ private _ringScreenBuffer: Nullable<Array<Texture>> = null;
|
|
|
|
+
|
|
|
|
+ private _getNextFrameBuffer(incrementIndex = true){
|
|
|
|
+ if (!this._ringScreenBuffer) {
|
|
|
|
+ this._ringScreenBuffer = []
|
|
|
|
+ for(var i = 0;i<2;i++){
|
|
|
|
+ var internalTexture = this.engine.createRenderTargetTexture(
|
|
|
|
+ {
|
|
|
|
+ width: Math.floor(this.engine.getRenderWidth(true)),
|
|
|
|
+ height: Math.floor(this.engine.getRenderHeight(true)),
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ generateDepthBuffer: false,
|
|
|
|
+ generateStencilBuffer: false,
|
|
|
|
+ generateMipMaps: false,
|
|
|
|
+ samplingMode: Constants.TEXTURE_NEAREST_NEAREST,
|
|
|
|
+ },
|
|
|
|
+ );
|
|
|
|
+ var texture = new Texture("", null);
|
|
|
|
+ texture._texture = internalTexture;
|
|
|
|
+ this._ringScreenBuffer.push(texture)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ var ret = this._ringScreenBuffer[this._ringBufferIndex];
|
|
|
|
+ if(incrementIndex){
|
|
|
|
+ this._ringBufferIndex = (this._ringBufferIndex+1) % 2;
|
|
|
|
+ }
|
|
|
|
+ return ret
|
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
/**
|
|
* Creates an effect renderer
|
|
* Creates an effect renderer
|
|
* @param engine the engine to use for rendering
|
|
* @param engine the engine to use for rendering
|
|
*/
|
|
*/
|
|
- constructor(public engine: Engine) {
|
|
|
|
|
|
+ constructor(private engine: Engine) {
|
|
this._vertexBuffers = {
|
|
this._vertexBuffers = {
|
|
[VertexBuffer.PositionKind]: new VertexBuffer(engine, EffectRenderer._Vertices, VertexBuffer.PositionKind, false, false, 2),
|
|
[VertexBuffer.PositionKind]: new VertexBuffer(engine, EffectRenderer._Vertices, VertexBuffer.PositionKind, false, false, 2),
|
|
};
|
|
};
|
|
@@ -42,35 +71,21 @@ export class EffectRenderer {
|
|
}
|
|
}
|
|
effectWrappers.forEach((effectWrapper, i) => {
|
|
effectWrappers.forEach((effectWrapper, i) => {
|
|
var renderTo = outputTexture;
|
|
var renderTo = outputTexture;
|
|
- if ((effectWrappers as Array<EffectWrapper>).length > 1 && i != (effectWrappers as Array<EffectWrapper>).length - 1) {
|
|
|
|
- if (!this._tmpScreenBuffer) {
|
|
|
|
- var internalTexture = this.engine.createRenderTargetTexture(
|
|
|
|
- {
|
|
|
|
- width: Math.floor(this.engine.getRenderWidth(true)),
|
|
|
|
- height: Math.floor(this.engine.getRenderHeight(true)),
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- generateDepthBuffer: false,
|
|
|
|
- generateStencilBuffer: false,
|
|
|
|
- generateMipMaps: false,
|
|
|
|
- samplingMode: Constants.TEXTURE_NEAREST_NEAREST,
|
|
|
|
- },
|
|
|
|
- );
|
|
|
|
- this._tmpScreenBuffer = new Texture("", null);
|
|
|
|
- this._tmpScreenBuffer._texture = internalTexture;
|
|
|
|
- }
|
|
|
|
- renderTo = this._tmpScreenBuffer;
|
|
|
|
- }else {
|
|
|
|
- renderTo = outputTexture;
|
|
|
|
- }
|
|
|
|
|
|
|
|
// for any next effect make it's input the output of the previous effect
|
|
// for any next effect make it's input the output of the previous effect
|
|
if (i !== 0) {
|
|
if (i !== 0) {
|
|
effectWrapper.effect.onBindObservable.addOnce(() => {
|
|
effectWrapper.effect.onBindObservable.addOnce(() => {
|
|
- effectWrapper.effect.setTexture("textureSampler", this._tmpScreenBuffer);
|
|
|
|
|
|
+ effectWrapper.effect.setTexture("textureSampler", this._getNextFrameBuffer(false));
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Set the output to the next screenbuffer
|
|
|
|
+ if ((effectWrappers as Array<EffectWrapper>).length > 1 && i != (effectWrappers as Array<EffectWrapper>).length - 1) {
|
|
|
|
+ renderTo = this._getNextFrameBuffer();
|
|
|
|
+ }else {
|
|
|
|
+ renderTo = outputTexture;
|
|
|
|
+ }
|
|
|
|
+
|
|
// Reset state
|
|
// Reset state
|
|
this.engine.setViewport(new Viewport(0, 0, 1, 1));
|
|
this.engine.setViewport(new Viewport(0, 0, 1, 1));
|
|
this.engine.enableEffect(effectWrapper.effect);
|
|
this.engine.enableEffect(effectWrapper.effect);
|
|
@@ -94,8 +109,21 @@ export class EffectRenderer {
|
|
* Disposes of the effect renderer
|
|
* Disposes of the effect renderer
|
|
*/
|
|
*/
|
|
dispose() {
|
|
dispose() {
|
|
- if (this._tmpScreenBuffer) {
|
|
|
|
- this._tmpScreenBuffer.dispose();
|
|
|
|
|
|
+ if (this._ringScreenBuffer) {
|
|
|
|
+ this._ringScreenBuffer.forEach((b)=>{
|
|
|
|
+ b.dispose()
|
|
|
|
+ })
|
|
|
|
+ this._ringScreenBuffer = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];
|
|
|
|
+ if (vertexBuffer) {
|
|
|
|
+ vertexBuffer.dispose();
|
|
|
|
+ delete this._vertexBuffers[VertexBuffer.PositionKind];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this._indexBuffer) {
|
|
|
|
+ this.engine._releaseBuffer(this._indexBuffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -104,7 +132,6 @@ export class EffectRenderer {
|
|
* Wraps an effect to be used for rendering
|
|
* Wraps an effect to be used for rendering
|
|
*/
|
|
*/
|
|
export class EffectWrapper {
|
|
export class EffectWrapper {
|
|
- private static _counter = 0;
|
|
|
|
/**
|
|
/**
|
|
* Event that is fired right before the effect is drawn (should be used to update uniforms)
|
|
* Event that is fired right before the effect is drawn (should be used to update uniforms)
|
|
*/
|
|
*/
|
|
@@ -119,8 +146,13 @@ export class EffectWrapper {
|
|
* @param creationOptions options to create the effect
|
|
* @param creationOptions options to create the effect
|
|
*/
|
|
*/
|
|
constructor(creationOptions: {engine: Engine, fragmentShader: string, attributeNames: Array<string>, uniformNames: Array<string>, samplerNames: Array<string>}) {
|
|
constructor(creationOptions: {engine: Engine, fragmentShader: string, attributeNames: Array<string>, uniformNames: Array<string>, samplerNames: Array<string>}) {
|
|
- var shaderName = "EffectWrapperEffect" + EffectWrapper._counter++;
|
|
|
|
- Effect.ShadersStore[shaderName + "FragmentShader"] = creationOptions.fragmentShader;
|
|
|
|
- this.effect = creationOptions.engine.createEffect({vertex: "postprocess", fragment: shaderName}, creationOptions.attributeNames, creationOptions.uniformNames, creationOptions.samplerNames, "", undefined);
|
|
|
|
|
|
+ this.effect = new Effect({fragmentSource: creationOptions.fragmentShader, vertex: "postprocess"},creationOptions.attributeNames,creationOptions.uniformNames, creationOptions.samplerNames, creationOptions.engine);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Disposes of the effect wrapper
|
|
|
|
+ */
|
|
|
|
+ public dispose(){
|
|
|
|
+ this.effect.dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|