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 children; [ReadOnly] public override ObservableCollection Children { get { if (children == null) { children = new ObservableCollection(); children.Add(InputTexture); children.Add(OutputTexture); children.Add(RootNode); children.Add(PreProcessNode); } return children; } } } }