141 lines
3.2 KiB
C++
141 lines
3.2 KiB
C++
#include "stdafx.h"
|
|
#include "IResourceFactory.h"
|
|
#include "Shader.h"
|
|
|
|
|
|
Shader::Shader(IEngine& argEngine)
|
|
: m_Engine(argEngine)
|
|
, m_Technique(NULL)
|
|
, m_InternalShader(NULL)
|
|
, m_CurrentPass(-1)
|
|
, m_Priority(0)
|
|
{
|
|
m_Commands.push_back(new Command(this, CommandFlags::StartChain | CommandFlags::SubChainStart, ApplyFirstPassCommandType, 2, m_Priority));
|
|
m_Commands.push_back(new Command(this, CommandFlags::SubChainEnd, NextPassCommandType, -1, m_Priority));
|
|
}
|
|
|
|
|
|
Shader::~Shader()
|
|
{
|
|
this->Uninitialize();
|
|
m_Engine.get_ResourceFactory().DeleteShader(*const_cast<Shader*>(this), true);
|
|
}
|
|
|
|
|
|
void Shader::set_TechniqueName(const string8& argValue)
|
|
{
|
|
m_TechniqueName = argValue;
|
|
|
|
if (this->get_InternalShader() == NULL)
|
|
return;
|
|
|
|
if (m_TechniqueName.empty())
|
|
{
|
|
m_Technique = this->get_InternalShader()->get_DX10Effect()->GetTechniqueByIndex(0);
|
|
|
|
if (m_Technique != NULL)
|
|
{
|
|
D3D10_TECHNIQUE_DESC desc;
|
|
m_Technique->GetDesc(&desc);
|
|
m_TechniqueName = desc.Name;
|
|
}
|
|
}
|
|
|
|
m_Technique = this->get_InternalShader()->get_DX10Effect()->GetTechniqueByName(m_TechniqueName.c_str());
|
|
if (m_Technique == NULL)
|
|
{
|
|
throw L"Shader: Technique not found.";
|
|
}
|
|
|
|
m_Technique->GetDesc(&m_TechDesc);
|
|
}
|
|
|
|
|
|
void Shader::LoadFromFile(const string16& argValue)
|
|
{
|
|
this->CreateOrFindShader(argValue);
|
|
this->set_TechniqueName(m_TechniqueName);
|
|
}
|
|
|
|
|
|
void Shader::Uninitialize()
|
|
{
|
|
if (m_Engine.get_EngineStates().LastShader == this)
|
|
m_Engine.get_EngineStates().LastShader = NULL;
|
|
|
|
m_Technique = NULL;
|
|
m_CurrentPass = -1;
|
|
m_TechniqueName = "";
|
|
}
|
|
|
|
|
|
bool Shader::TryApplyNextPass()
|
|
{
|
|
if (m_InternalShader == NULL || m_Technique == NULL)
|
|
throw L"Shader: Access forbidden until resource has been initialized.";
|
|
|
|
if (m_CurrentPass >= m_TechDesc.Passes)
|
|
m_CurrentPass = m_TechDesc.Passes;
|
|
else
|
|
m_CurrentPass++;
|
|
|
|
if (m_CurrentPass >= m_TechDesc.Passes)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
void Shader::ApplyFirstPass()
|
|
{
|
|
if (m_InternalShader == NULL || m_Technique == NULL)
|
|
throw L"Shader: Access forbidden until resource has been initialized.";
|
|
m_CurrentPass = 0;
|
|
|
|
m_Engine.get_EngineStates().LastShader = this;
|
|
}
|
|
|
|
|
|
void Shader::set_Priority(unsigned char argValue)
|
|
{
|
|
m_Priority = argValue;
|
|
for (uint32 i = 0; i < m_Commands.size(); ++i)
|
|
if (m_Commands[i]->Type == ApplyFirstPassCommandType)
|
|
m_Commands[i]->SubPriority = m_Priority;
|
|
}
|
|
|
|
|
|
unsigned char Shader::get_Priority() const
|
|
{
|
|
return m_Priority;
|
|
}
|
|
|
|
|
|
IInternalShader* Shader::CreateOrFindShader(const string16& argFileName)
|
|
{
|
|
IResourceFactory& resFac = m_Engine.get_ResourceFactory();
|
|
m_InternalShader = &resFac.CreateOrFindInternalShader(std::to_string8(argFileName));
|
|
if (m_InternalShader != NULL)
|
|
{
|
|
if (resFac.HasCreatedResource())
|
|
m_InternalShader->LoadFromFile(argFileName);
|
|
return m_InternalShader;
|
|
}
|
|
|
|
throw L"Shader: Unable to create ShaderInternal for specified Shader.";
|
|
}
|
|
|
|
|
|
CommandExecuteResult::Enumeration Shader::ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon)
|
|
{
|
|
if (argCommandType == Shader::ApplyFirstPassCommandType)
|
|
{
|
|
this->ApplyFirstPass();
|
|
}
|
|
else if (argCommandType == Shader::NextPassCommandType)
|
|
{
|
|
if (this->TryApplyNextPass())
|
|
return CommandExecuteResult::RetrySubChainSkipHead;
|
|
}
|
|
return CommandExecuteResult::None;
|
|
}
|