136 lines
5.4 KiB
C#
136 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Aiwaz.Contracts;
|
|
using Aiwaz.Resources.Attributes;
|
|
using System.Collections.ObjectModel;
|
|
|
|
namespace Aiwaz.Resources.Prefab
|
|
{
|
|
public struct PingPongBufferDescription
|
|
{
|
|
public int LoopCount;
|
|
public string ShaderFileName;
|
|
public string ShaderTechniqueA;
|
|
public string ShaderTechniqueB;
|
|
public string PreProcessShaderTechnique;
|
|
|
|
public int TextureWidth;
|
|
public int TextureHeight;
|
|
public SlimDX.DXGI.Format TextureFormat;
|
|
};
|
|
|
|
[CreationParameters("Standard ping-pong buffer")]
|
|
public class PingPongBufferParams : ICreationParams
|
|
{
|
|
public PingPongBufferDescription Desc;
|
|
public Texture InputTexture;
|
|
|
|
public PingPongBufferParams()
|
|
{
|
|
}
|
|
}
|
|
|
|
[AiwazResource("PingPong buffer", "Two buffers that alternate each other")]
|
|
public class PingPongBuffer : Resource
|
|
{
|
|
public Texture InputTexture { get; protected set;}
|
|
public Texture OutputTexture { get { return textureB.Texture; } }
|
|
public RenderCommandNode RootNode { get; protected set; }
|
|
public RenderCommandNode PreProcessNode { get; protected set; }
|
|
|
|
RenderCommandNode renderTargetNodeA;
|
|
RenderCommandNode renderTargetNodeB;
|
|
Shader shaderA;
|
|
Shader shaderB;
|
|
Shader shaderPreProcess;
|
|
RenderTargetTexture textureA;
|
|
RenderTargetTexture textureB;
|
|
GeometryBuffer screenQuad;
|
|
ShaderParameterSet shaderParameterA;
|
|
ShaderParameterSet shaderParameterB;
|
|
ShaderParameterSet shaderParameterPreProcess;
|
|
|
|
public PingPongBuffer(PingPongBufferParams parameters)
|
|
{
|
|
creationParams = parameters;
|
|
if (string.IsNullOrEmpty(parameters.Desc.ShaderFileName))
|
|
throw new ArgumentNullException("ShaderFileName");
|
|
|
|
shaderA = new Shader(new ShaderParams() { FileName = parameters.Desc.ShaderFileName, TechniqueName = parameters.Desc.ShaderTechniqueA } );
|
|
shaderB = new Shader(new ShaderParams() { FileName = parameters.Desc.ShaderFileName, TechniqueName = parameters.Desc.ShaderTechniqueB } );
|
|
shaderPreProcess = new Shader(new ShaderParams() { FileName = parameters.Desc.ShaderFileName, TechniqueName = parameters.Desc.PreProcessShaderTechnique });
|
|
|
|
textureA = new RenderTargetTexture(new RenderTargetTextureParams() { width = parameters.Desc.TextureWidth, height = parameters.Desc.TextureHeight, format = parameters.Desc.TextureFormat } );
|
|
textureB = new RenderTargetTexture(new RenderTargetTextureParams() { width = parameters.Desc.TextureWidth, height = parameters.Desc.TextureHeight, format = parameters.Desc.TextureFormat } );
|
|
|
|
shaderParameterA = new ShaderParameterSet();
|
|
shaderParameterA.SetParameter("InputTexture", textureB.Texture, ParameterBindType.BindBySemantic);
|
|
|
|
shaderParameterB = new ShaderParameterSet();
|
|
shaderParameterB.SetParameter("InputTexture", textureA.Texture, ParameterBindType.BindBySemantic);
|
|
|
|
this.InputTexture = parameters.InputTexture;
|
|
shaderParameterPreProcess = new ShaderParameterSet();
|
|
shaderParameterPreProcess.SetParameter("InputTexture", this.InputTexture, ParameterBindType.BindBySemantic);
|
|
|
|
var quad = new Quad(new QuadParams() { Width = 2.0f, Height = 2.0f } );
|
|
screenQuad = quad.GeometryBuffer;
|
|
|
|
renderTargetNodeA = new RenderCommandNode();
|
|
renderTargetNodeA.Children.Add(textureA);
|
|
renderTargetNodeA.Children.Add(shaderA);
|
|
renderTargetNodeA.Children.Add(shaderParameterA);
|
|
renderTargetNodeA.Children.Add(screenQuad);
|
|
|
|
renderTargetNodeB = new RenderCommandNode();
|
|
renderTargetNodeB.Children.Add(textureB);
|
|
renderTargetNodeB.Children.Add(shaderB);
|
|
renderTargetNodeB.Children.Add(shaderParameterB);
|
|
renderTargetNodeB.Children.Add(screenQuad);
|
|
|
|
this.RootNode = new RenderCommandNode();
|
|
this.PreProcessNode = new RenderCommandNode();
|
|
|
|
// preprocessing
|
|
this.RootNode.Children.Add(textureB);
|
|
this.RootNode.Children.Add(shaderPreProcess);
|
|
this.RootNode.Children.Add(shaderParameterPreProcess);
|
|
this.RootNode.Children.Add(screenQuad);
|
|
this.RootNode.Children.Add(this.PreProcessNode);
|
|
|
|
// real pingpongs
|
|
for (int i = 0; i < parameters.Desc.LoopCount; ++i)
|
|
{
|
|
this.RootNode.Children.Add(renderTargetNodeA);
|
|
this.RootNode.Children.Add(renderTargetNodeB);
|
|
}
|
|
}
|
|
|
|
private ICreationParams creationParams;
|
|
public override ICreationParams CreationParams
|
|
{
|
|
get { return creationParams; }
|
|
}
|
|
|
|
private ObservableCollection<IResource> children;
|
|
[ReadOnly]
|
|
public override ObservableCollection<IResource> Children
|
|
{
|
|
get
|
|
{
|
|
if (children == null)
|
|
{
|
|
children = new ObservableCollection<IResource>();
|
|
children.Add(InputTexture);
|
|
children.Add(OutputTexture);
|
|
children.Add(RootNode);
|
|
children.Add(PreProcessNode);
|
|
}
|
|
return children;
|
|
}
|
|
}
|
|
}
|
|
}
|