port from perforce
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "ICommonObjectFactory.h"
|
||||
#include "PingPongBuffer.h"
|
||||
#include "../Resources/ShaderParameterCollection/Types/Texture.h"
|
||||
|
||||
|
||||
PingPongBuffer::PingPongBuffer(IEngine& argEngine)
|
||||
: m_Engine(argEngine)
|
||||
, m_RenderTargetNodeA(NULL)
|
||||
, m_RenderTargetNodeB(NULL)
|
||||
, m_ShaderA(NULL)
|
||||
, m_ShaderB(NULL)
|
||||
, m_ShaderPreProcess(NULL)
|
||||
, m_TextureA(NULL)
|
||||
, m_TextureB(NULL)
|
||||
, m_ScreenQuad(NULL)
|
||||
, m_ShaderParameterA(NULL)
|
||||
, m_ShaderParameterB(NULL)
|
||||
, m_ShaderParameterPreProcess(NULL)
|
||||
, m_InputTexture(NULL)
|
||||
{
|
||||
m_RootNode = &m_Engine.get_ResourceFactory().CreateRenderCommandNode();
|
||||
m_PreProcessNode = &m_Engine.get_ResourceFactory().CreateRenderCommandNode();
|
||||
}
|
||||
|
||||
|
||||
PingPongBuffer::~PingPongBuffer()
|
||||
{
|
||||
IResourceFactory& resourceFac = m_Engine.get_ResourceFactory();
|
||||
|
||||
resourceFac.DeleteTexture(*m_InputTexture);
|
||||
|
||||
resourceFac.DeleteShader(*m_ShaderA);
|
||||
resourceFac.DeleteShader(*m_ShaderB);
|
||||
resourceFac.DeleteShader(*m_ShaderPreProcess);
|
||||
resourceFac.DeleteRenderTargetTexture(*m_TextureA);
|
||||
resourceFac.DeleteRenderTargetTexture(*m_TextureB);
|
||||
resourceFac.DeleteGeometryBuffer(*m_ScreenQuad);
|
||||
resourceFac.DeleteShaderParameterCollection(*m_ShaderParameterA);
|
||||
resourceFac.DeleteShaderParameterCollection(*m_ShaderParameterB);
|
||||
resourceFac.DeleteShaderParameterCollection(*m_ShaderParameterPreProcess);
|
||||
|
||||
resourceFac.DeleteRenderCommandNode(*m_RootNode);
|
||||
resourceFac.DeleteRenderCommandNode(*m_PreProcessNode);
|
||||
resourceFac.DeleteRenderCommandNode(*m_RenderTargetNodeA);
|
||||
resourceFac.DeleteRenderCommandNode(*m_RenderTargetNodeB);
|
||||
}
|
||||
|
||||
ITexture& PingPongBuffer::get_InputTexture() const
|
||||
{
|
||||
return *m_InputTexture;
|
||||
}
|
||||
|
||||
|
||||
void PingPongBuffer::set_InputTexture(ITexture& argTexture)
|
||||
{
|
||||
m_InputTexture = &argTexture;
|
||||
this->Rebuild(m_Descriptor);
|
||||
}
|
||||
|
||||
|
||||
ITexture& PingPongBuffer::get_OutputTexture() const
|
||||
{
|
||||
return m_TextureB->get_TextureResource();
|
||||
}
|
||||
|
||||
|
||||
const PingPongBufferDescription& PingPongBuffer::get_Descriptor() const
|
||||
{
|
||||
return m_Descriptor;
|
||||
}
|
||||
|
||||
|
||||
void PingPongBuffer::set_Descriptor(const PingPongBufferDescription& argValue)
|
||||
{
|
||||
this->Rebuild(argValue);
|
||||
}
|
||||
|
||||
|
||||
IRenderCommandNode& PingPongBuffer::get_RootNode() const
|
||||
{
|
||||
return *m_RootNode;
|
||||
}
|
||||
|
||||
|
||||
IRenderCommandNode& PingPongBuffer::get_PreProcessNode() const
|
||||
{
|
||||
return *m_PreProcessNode;
|
||||
}
|
||||
|
||||
|
||||
void PingPongBuffer::Rebuild(const PingPongBufferDescription& argValue)
|
||||
{
|
||||
// Shader A
|
||||
if (argValue.ShaderFileName.empty())
|
||||
return;
|
||||
|
||||
if (m_ShaderA == NULL || argValue.ShaderFileName != m_Descriptor.ShaderFileName)
|
||||
{
|
||||
m_ShaderA = &m_Engine.get_ResourceFactory().CreateOrFindShader();
|
||||
m_ShaderA->LoadFromFile(argValue.ShaderFileName);
|
||||
}
|
||||
if (argValue.ShaderTechniqueA != m_Descriptor.ShaderTechniqueA)
|
||||
m_ShaderA->set_TechniqueName(argValue.ShaderTechniqueA);
|
||||
|
||||
// ShaderB
|
||||
if (m_ShaderB == NULL || argValue.ShaderFileName != m_Descriptor.ShaderFileName)
|
||||
{
|
||||
m_ShaderB = &m_Engine.get_ResourceFactory().CreateOrFindShader();
|
||||
m_ShaderB->LoadFromFile(argValue.ShaderFileName);
|
||||
}
|
||||
if (argValue.ShaderTechniqueB != m_Descriptor.ShaderTechniqueB)
|
||||
m_ShaderB->set_TechniqueName(argValue.ShaderTechniqueB);
|
||||
|
||||
// PreProcessShader (downscale, input to buffer)
|
||||
if (m_ShaderPreProcess == NULL || argValue.ShaderFileName != m_Descriptor.ShaderFileName)
|
||||
{
|
||||
m_ShaderPreProcess = &m_Engine.get_ResourceFactory().CreateOrFindShader();
|
||||
m_ShaderPreProcess->LoadFromFile(argValue.ShaderFileName);
|
||||
}
|
||||
if (argValue.PreProcessShaderTechnique != m_Descriptor.PreProcessShaderTechnique)
|
||||
m_ShaderPreProcess->set_TechniqueName(argValue.PreProcessShaderTechnique);
|
||||
|
||||
if (m_TextureA == NULL || m_TextureB == NULL || argValue.TextureWidth != m_Descriptor.TextureWidth || argValue.TextureHeight != m_Descriptor.TextureHeight || argValue.TextureFormat != m_Descriptor.TextureFormat)
|
||||
{
|
||||
if (m_TextureA == NULL)
|
||||
m_TextureA = &m_Engine.get_ResourceFactory().CreateOrFindRenderTargetTexture();
|
||||
if (m_TextureB == NULL)
|
||||
m_TextureB = &m_Engine.get_ResourceFactory().CreateOrFindRenderTargetTexture();
|
||||
m_TextureA->SetTextureParameters(argValue.TextureWidth, argValue.TextureHeight, argValue.TextureFormat);
|
||||
m_TextureB->SetTextureParameters(argValue.TextureWidth, argValue.TextureHeight, argValue.TextureFormat);
|
||||
}
|
||||
|
||||
m_ShaderParameterA = &m_Engine.get_ResourceFactory().CreateOrFindShaderParameterCollection();
|
||||
m_ShaderParameterA->SetParameter("InputTexture", m_TextureB->get_TextureResource());
|
||||
|
||||
m_ShaderParameterB = &m_Engine.get_ResourceFactory().CreateOrFindShaderParameterCollection();
|
||||
m_ShaderParameterB->SetParameter("InputTexture", m_TextureA->get_TextureResource());
|
||||
|
||||
m_ShaderParameterPreProcess = &m_Engine.get_ResourceFactory().CreateOrFindShaderParameterCollection();
|
||||
m_ShaderParameterPreProcess->SetParameter("InputTexture", new TextureShaderParameter(*m_InputTexture, ParameterBindType::BindBySemantic));
|
||||
|
||||
if (m_ScreenQuad == NULL)
|
||||
m_ScreenQuad = m_Engine.get_CommonObjectFactory().CreateQuad(2.0f, 2.0f, false);
|
||||
|
||||
m_RenderTargetNodeA = &m_Engine.get_ResourceFactory().CreateRenderCommandNode();
|
||||
AddToNode(*m_RenderTargetNodeA, m_TextureA);
|
||||
AddToNode(*m_RenderTargetNodeA ,m_ShaderA);
|
||||
AddToNode(*m_RenderTargetNodeA, m_ShaderParameterA);
|
||||
AddToNode(*m_RenderTargetNodeA, m_ScreenQuad);
|
||||
|
||||
m_RenderTargetNodeB = &m_Engine.get_ResourceFactory().CreateRenderCommandNode();
|
||||
AddToNode(*m_RenderTargetNodeB, m_TextureB);
|
||||
AddToNode(*m_RenderTargetNodeB, m_ShaderB);
|
||||
AddToNode(*m_RenderTargetNodeB, m_ShaderParameterB);
|
||||
AddToNode(*m_RenderTargetNodeB, m_ScreenQuad);
|
||||
|
||||
|
||||
const std::vector<ICommandUser*>& lk_CommandUsers = m_RootNode->get_CommandUsers();
|
||||
while (!lk_CommandUsers.empty())
|
||||
m_RootNode->RemoveCommandUser(*lk_CommandUsers[0]);
|
||||
|
||||
// preprocessing
|
||||
AddToNode(*m_RootNode, m_TextureB);
|
||||
AddToNode(*m_RootNode, m_ShaderPreProcess);
|
||||
AddToNode(*m_RootNode, m_ShaderParameterPreProcess);
|
||||
AddToNode(*m_RootNode, m_ScreenQuad);
|
||||
AddToNode(*m_RootNode, m_PreProcessNode);
|
||||
|
||||
// real pingpongs
|
||||
for (uint32 i = 0; i < argValue.LoopCount; ++i)
|
||||
{
|
||||
AddToNode(*m_RootNode, m_RenderTargetNodeA);
|
||||
AddToNode(*m_RootNode, m_RenderTargetNodeB);
|
||||
}
|
||||
|
||||
m_Descriptor = argValue;
|
||||
}
|
||||
Reference in New Issue
Block a user