187 lines
4.4 KiB
C++
187 lines
4.4 KiB
C++
#include "stdafx.h"
|
|
#include <algorithm>
|
|
#include "../Commands/CommandBuffer.h"
|
|
#include "IResourceFactory.h"
|
|
#include "RenderCommandNode.h"
|
|
|
|
|
|
RenderCommandNode::RenderCommandNode(IEngine& argEngine)
|
|
: m_Engine(argEngine)
|
|
, m_Dirty(true)
|
|
, m_ParentNode(NULL)
|
|
, m_CommandBuffer(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
RenderCommandNode::~RenderCommandNode()
|
|
{
|
|
if (m_ParentNode != NULL)
|
|
m_ParentNode->RemoveCommandUser(*this);
|
|
|
|
while (!m_CommandUsers.empty())
|
|
RemoveCommandUser(**m_CommandUsers.begin());
|
|
|
|
delete m_CommandBuffer;
|
|
|
|
m_Engine.get_ResourceFactory().DeleteRenderCommandNode(*const_cast<RenderCommandNode*>(this), true);
|
|
}
|
|
|
|
|
|
const std::vector<ICommandUser*> RenderCommandNode::get_CommandUsers() const
|
|
{
|
|
return m_CommandUsers;
|
|
}
|
|
|
|
|
|
void RenderCommandNode::set_Parent(IRenderCommandNode* ar_Node_)
|
|
{
|
|
m_ParentNode = ar_Node_;
|
|
}
|
|
|
|
|
|
IRenderCommandNode* RenderCommandNode::get_Parent() const
|
|
{
|
|
return m_ParentNode;
|
|
}
|
|
|
|
|
|
bool RenderCommandNode::IsDirty() const
|
|
{
|
|
return m_Dirty;
|
|
}
|
|
|
|
|
|
void RenderCommandNode::MarkDirty()
|
|
{
|
|
m_Dirty = true;
|
|
if (m_ParentNode != NULL)
|
|
m_ParentNode->MarkDirty();
|
|
}
|
|
|
|
|
|
void RenderCommandNode::AddCommandUser(ICommandUser& argCommandUser)
|
|
{
|
|
argCommandUser.AssignToRenderCommandNode(*const_cast<RenderCommandNode*>(this));
|
|
m_CommandUsers.push_back(&argCommandUser);
|
|
IRenderCommandNode* node = dynamic_cast<IRenderCommandNode*>(&argCommandUser);
|
|
if (node != NULL)
|
|
node->set_Parent(this);
|
|
this->MarkDirty();
|
|
}
|
|
|
|
|
|
void RenderCommandNode::RemoveCommandUser(ICommandUser& argCommandUser)
|
|
{
|
|
std::vector<ICommandUser*>::iterator found = std::find(m_CommandUsers.begin(), m_CommandUsers.end(), &argCommandUser);
|
|
if (found != m_CommandUsers.end())
|
|
{
|
|
IRenderCommandNode* node = dynamic_cast<IRenderCommandNode*>(&argCommandUser);
|
|
if (node != NULL)
|
|
node->set_Parent(NULL);
|
|
|
|
m_CommandUsers.erase(found);
|
|
argCommandUser.UnassignFromRenderCommandNode(*const_cast<RenderCommandNode*>(this));
|
|
|
|
this->MarkDirty();
|
|
}
|
|
}
|
|
|
|
|
|
void RenderCommandNode::ReplaceCommandUser(ICommandUser& argWhatCommandUser, ICommandUser& argWhithCommandUser)
|
|
{
|
|
std::vector<ICommandUser*>::iterator found = std::find(m_CommandUsers.begin(), m_CommandUsers.end(), &argWhatCommandUser);
|
|
if (found != m_CommandUsers.end())
|
|
{
|
|
IRenderCommandNode* node = dynamic_cast<IRenderCommandNode*>(&argWhatCommandUser);
|
|
if (node != NULL)
|
|
node->set_Parent(NULL);
|
|
|
|
m_CommandUsers.insert(found, &argWhithCommandUser);
|
|
m_CommandUsers.erase(found);
|
|
|
|
argWhatCommandUser.UnassignFromRenderCommandNode(*const_cast<RenderCommandNode*>(this));
|
|
argWhithCommandUser.AssignToRenderCommandNode(*const_cast<RenderCommandNode*>(this));
|
|
|
|
node = dynamic_cast<IRenderCommandNode*>(&argWhithCommandUser);
|
|
if (node != NULL)
|
|
node->set_Parent(this);
|
|
|
|
this->MarkDirty();
|
|
}
|
|
}
|
|
|
|
|
|
void RenderCommandNode::ProcessCommands()
|
|
{
|
|
if (m_Dirty)
|
|
{
|
|
this->GenerateDeviceCommands();
|
|
m_CommandBuffer->Optimize();
|
|
}
|
|
m_CommandBuffer->Perform(true);
|
|
}
|
|
|
|
|
|
void RenderCommandNode::Update(bool argForceUpdate)
|
|
{
|
|
// Walk through all updatables and update them.
|
|
for (uint32 i = 0; i < m_CommandUsers.size(); ++i)
|
|
{
|
|
IUpdatable* updatable = dynamic_cast<IUpdatable*>(m_CommandUsers[i]);
|
|
if (updatable != NULL && (updatable->get_WantsUpdate() || argForceUpdate))
|
|
updatable->Update(argForceUpdate);
|
|
}
|
|
}
|
|
|
|
|
|
bool RenderCommandNode::get_WantsUpdate() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
CommandExecuteResult::Enumeration RenderCommandNode::ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon)
|
|
{
|
|
return CommandExecuteResult::None;
|
|
}
|
|
|
|
|
|
void RenderCommandNode::GenerateDeviceCommands()
|
|
{
|
|
if (!m_Dirty)
|
|
return;
|
|
|
|
m_Dirty = false;
|
|
if (m_CommandBuffer == NULL)
|
|
m_CommandBuffer = new CommandBuffer(false, false);
|
|
else
|
|
m_CommandBuffer->Clear();
|
|
|
|
for (uint32 i = 0; i < m_CommandUsers.size(); ++i)
|
|
{
|
|
// Add the commands all commands
|
|
const std::vector<Command*>& commands = m_CommandUsers[i]->GetCommands();
|
|
for (uint32 k = 0; k < commands.size(); ++k)
|
|
m_CommandBuffer->AddCommand(*commands[k]);
|
|
|
|
// Walk further if we found another RenderCommandNode
|
|
IRenderCommandNodeInternal* nodeInternal = dynamic_cast<IRenderCommandNodeInternal*>(m_CommandUsers[i]);
|
|
if (nodeInternal != NULL)
|
|
{
|
|
nodeInternal->GenerateDeviceCommands();
|
|
|
|
// Merge the buffers
|
|
ICommandBuffer* otherBuffer = nodeInternal->get_CommandBuffer();
|
|
if (otherBuffer != NULL)
|
|
m_CommandBuffer->AddChildCommandBuffer(*otherBuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ICommandBuffer* RenderCommandNode::get_CommandBuffer() const
|
|
{
|
|
return m_CommandBuffer;
|
|
}
|