#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(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; }