port from perforce
This commit is contained in:
61
aiwaz/Aiwaz/Resources/Shader/InternalShader.cpp
Normal file
61
aiwaz/Aiwaz/Resources/Shader/InternalShader.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "stdafx.h"
|
||||
#include "InternalShader.h"
|
||||
#include "IResourceFactory.h"
|
||||
|
||||
|
||||
InternalShader::InternalShader(const IEngine& argEngine)
|
||||
: m_Engine(argEngine)
|
||||
, m_Effect(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InternalShader::~InternalShader()
|
||||
{
|
||||
m_Engine.get_ResourceFactory().DeleteInternalShader(*const_cast<InternalShader*>(this), true);
|
||||
}
|
||||
|
||||
|
||||
void InternalShader::LoadFromFile(const string16& argFileName)
|
||||
{
|
||||
if (m_Effect != NULL)
|
||||
this->Uninitialize();
|
||||
|
||||
HRESULT result = E_FAIL;
|
||||
|
||||
IFile* shaderFile = m_Engine.get_FileSystem().Open(argFileName);
|
||||
if (shaderFile == NULL)
|
||||
throw L"Unable to open shader file.";
|
||||
|
||||
ID3D10Blob* error = NULL;
|
||||
result = ::D3DX10CreateEffectFromMemory(shaderFile->get_Buffer(), shaderFile->get_BufferLength(), std::to_string8(argFileName).c_str(), NULL, NULL, "fx_4_0",
|
||||
#ifdef _DEBUG
|
||||
D3D10_SHADER_ENABLE_STRICTNESS | D3D10_SHADER_DEBUG,
|
||||
#else
|
||||
D3D10_SHADER_ENABLE_STRICTNESS,
|
||||
#endif
|
||||
0, &m_Engine.get_DX10Device(), NULL, NULL, &m_Effect, &error, NULL);
|
||||
|
||||
if (result != S_OK)
|
||||
std::cout << std::red << "Unable to load shader file from memory. " << std::white << std::endl;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
string8 errorText = static_cast<char*>(error->GetBufferPointer());
|
||||
std::cout << std::red << errorText << std::white << std::endl;
|
||||
::OutputDebugString(errorText.c_str());
|
||||
throw errorText;
|
||||
}
|
||||
if (error != NULL)
|
||||
error->Release();
|
||||
|
||||
delete shaderFile;
|
||||
}
|
||||
|
||||
|
||||
void InternalShader::Uninitialize()
|
||||
{
|
||||
if (m_Effect != NULL)
|
||||
m_Effect->Release();
|
||||
m_Effect = NULL;
|
||||
}
|
||||
24
aiwaz/Aiwaz/Resources/Shader/InternalShader.h
Normal file
24
aiwaz/Aiwaz/Resources/Shader/InternalShader.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "IEngine.h"
|
||||
#include "IShader.h"
|
||||
#include "IFileSystem.h"
|
||||
|
||||
|
||||
class InternalShader
|
||||
: public IInternalShader
|
||||
{
|
||||
public:
|
||||
InternalShader(const IEngine& argEngine);
|
||||
virtual ~InternalShader();
|
||||
|
||||
virtual void Uninitialize();
|
||||
|
||||
virtual void LoadFromFile(const string16& argValue);
|
||||
|
||||
virtual ID3D10Effect* get_DX10Effect() const { return m_Effect; }
|
||||
|
||||
protected:
|
||||
const IEngine& m_Engine;
|
||||
ID3D10Effect* m_Effect;
|
||||
};
|
||||
140
aiwaz/Aiwaz/Resources/Shader/Shader.cpp
Normal file
140
aiwaz/Aiwaz/Resources/Shader/Shader.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#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;
|
||||
}
|
||||
53
aiwaz/Aiwaz/Resources/Shader/Shader.h
Normal file
53
aiwaz/Aiwaz/Resources/Shader/Shader.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "IFileSystem.h"
|
||||
#include "IEngine.h"
|
||||
#include "IShader.h"
|
||||
#include "../Commands/CommandUserBase.h"
|
||||
|
||||
|
||||
class Shader
|
||||
: public IShader
|
||||
, public CommandUserBase
|
||||
{
|
||||
protected:
|
||||
static const unsigned char ApplyFirstPassCommandType = 0;
|
||||
static const unsigned char NextPassCommandType = 1;
|
||||
|
||||
public:
|
||||
Shader(IEngine& argEngine);
|
||||
virtual ~Shader();
|
||||
|
||||
virtual void LoadFromFile(const string16& argValue);
|
||||
|
||||
virtual string8 get_TechniqueName() const { return m_TechniqueName; }
|
||||
virtual void set_TechniqueName(const string8& argValue);
|
||||
|
||||
virtual ID3D10EffectTechnique* get_DX10Technique() const { return m_Technique; }
|
||||
virtual IInternalShader* get_InternalShader() const { return m_InternalShader; }
|
||||
|
||||
virtual bool TryApplyNextPass();
|
||||
virtual void ApplyFirstPass();
|
||||
virtual uint32 get_CurrentRenderPass() const { return m_CurrentPass; }
|
||||
|
||||
virtual void set_Priority(unsigned char argValue);
|
||||
virtual unsigned char get_Priority() const;
|
||||
|
||||
protected:
|
||||
virtual void Uninitialize();
|
||||
IInternalShader* CreateOrFindShader(const string16& argFileName);
|
||||
|
||||
// ICommandUser
|
||||
virtual CommandExecuteResult::Enumeration ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon);
|
||||
virtual string8 get_UserName() const { return "Shader"; }
|
||||
|
||||
private:
|
||||
IEngine& m_Engine;
|
||||
|
||||
string8 m_TechniqueName;
|
||||
uint32 m_CurrentPass;
|
||||
ID3D10EffectTechnique* m_Technique;
|
||||
IInternalShader* m_InternalShader;
|
||||
D3D10_TECHNIQUE_DESC m_TechDesc;
|
||||
unsigned char m_Priority;
|
||||
};
|
||||
Reference in New Issue
Block a user