232 lines
4.8 KiB
C++
232 lines
4.8 KiB
C++
#include "render/IMaterial.h"
|
|
#include "render/IMaterialProxy.h"
|
|
|
|
namespace LifeGraphics
|
|
{
|
|
|
|
IMaterialPass::IMaterialPass(MaterialPass _type)
|
|
:passType(_type), ps(nullptr), vs(nullptr), gs(nullptr), cb(nullptr)
|
|
{
|
|
}
|
|
IMaterialPass::~IMaterialPass()
|
|
{
|
|
}
|
|
void IMaterialPass::SetShader(SHADER_TYPE _type, IShader* shader)
|
|
{
|
|
switch(_type)
|
|
{
|
|
case ST_VS:
|
|
vs = shader;
|
|
break;
|
|
case ST_PS:
|
|
ps = shader;
|
|
break;
|
|
case ST_GS:
|
|
gs = shader;
|
|
break;
|
|
default:
|
|
{
|
|
//TODO replace it by new log error
|
|
printf("Unknown shader type in IMaterialPass::SetShader\n");
|
|
}
|
|
}
|
|
}
|
|
IShader* IMaterialPass::GetShader(SHADER_TYPE _type)
|
|
{
|
|
switch(_type)
|
|
{
|
|
case ST_VS:
|
|
return vs;
|
|
case ST_PS:
|
|
return ps;
|
|
case ST_GS:
|
|
return gs;
|
|
default:
|
|
{
|
|
//TODO replace it by new log error
|
|
printf("Unknown shader type in IMaterialPass::GetShader\n");
|
|
}
|
|
}
|
|
}
|
|
MaterialPass IMaterialPass::GetPassType()
|
|
{
|
|
return passType;
|
|
}
|
|
IConstantBuffer* IMaterialPass::GetConstantBuffer()
|
|
{
|
|
return cb;
|
|
}
|
|
void IMaterialPass::SetTexture(texture_ptr tex, uint32 slot)
|
|
{
|
|
textureSlots[slot] = tex;
|
|
}
|
|
void IMaterialPass::Apply()
|
|
{
|
|
for(int i = 0; i < MAX_TEX_SLOT; i++)
|
|
{
|
|
texture_ptr tex = textureSlots[i];
|
|
if(tex.ptr() != nullptr)
|
|
{
|
|
CG::me()->GetRenderer()->SetPSTexture(tex.ptr(), i);
|
|
}
|
|
}
|
|
|
|
CG::me()->GetRenderer()->SetPixelShader(ps);
|
|
CG::me()->GetRenderer()->SetVertexShader(vs);
|
|
}
|
|
|
|
IMaterial::IMaterial(IShaderGraph* _graph, IShaderGraphCompiler* _compiler)
|
|
:CastShadows(false), ReceiveShadows(false), Opaque(false), flags(MF_NONE)
|
|
{
|
|
graph = _graph;
|
|
compiler = _compiler;
|
|
}
|
|
IMaterial::~IMaterial()
|
|
{
|
|
}
|
|
IMaterialPass* IMaterial::AddPass(MaterialPass _type)
|
|
{
|
|
IMaterialPass* result = GetPass(_type);
|
|
if(result == nullptr)
|
|
{
|
|
result = new IMaterialPass(_type);
|
|
passes[_type] = result;
|
|
}
|
|
return result;
|
|
}
|
|
void IMaterial::SetTexture(int id, texture_ptr tex)
|
|
{
|
|
textures[id] = tex;
|
|
}
|
|
texture_ptr IMaterial::GetTexture(int id)
|
|
{
|
|
return textures[id];
|
|
}
|
|
IMaterialPass* IMaterial::GetPass(MaterialPass _type)
|
|
{
|
|
PassCollectionItr it = passes.find(_type);
|
|
return it == passes.end() ? nullptr : it->second;
|
|
}
|
|
uint32 IMaterial::GetPassCount()
|
|
{
|
|
return passes.size();
|
|
}
|
|
IMaterialProxy* IMaterial::CreateProxy(IObjectMesh* parent)
|
|
{
|
|
IMaterialProxy* proxy = new IMaterialProxy(this, parent);
|
|
//TODO
|
|
//Add proxy to watch collection!
|
|
return proxy;
|
|
}
|
|
IMaterialTechnique* IMaterial::CreateTechnique(MaterialTechnique tech, IMaterialProxy* target)
|
|
{
|
|
switch (tech)
|
|
{
|
|
case LifeGraphics::MT_RENDER_FORWARD:
|
|
return nullptr;
|
|
break;
|
|
case LifeGraphics::MT_RENDER_DEFERRED:
|
|
{
|
|
IMaterialTechnique* technique = new IMaterialTechnique(tech, target);
|
|
|
|
|
|
return technique;
|
|
|
|
}
|
|
break;
|
|
default:
|
|
return nullptr;
|
|
break;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
IMaterialPass* IMaterial::CreatePass(IMaterialTechnique* tech, MaterialPass pass)
|
|
{
|
|
switch (tech->GetTechniqueType())
|
|
{
|
|
case MT_RENDER_FORWARD:
|
|
return nullptr;
|
|
break;
|
|
case MT_RENDER_DEFERRED:
|
|
{
|
|
switch(pass)
|
|
{
|
|
case MP_G_FILL:
|
|
{
|
|
IMaterialPass* p = new IMaterialPass(pass);
|
|
String ps, vs;
|
|
compiler->CompileNode(graph->GetNodeByID(0), pass, ps, vs, &p->inputInfo);
|
|
IShader* psh = ResourceManager::me()->CompileUserShaderPS(ps.c_str(), ps.size());
|
|
IShader* vsh = ResourceManager::me()->CompileUserShaderVS(vs.c_str(), vs.size());
|
|
|
|
|
|
|
|
p->SetShader(ST_PS, psh);
|
|
p->SetShader(ST_VS, vsh);
|
|
|
|
//set textures
|
|
for(int i = 0; i < p->inputInfo.Textures.size(); i++)
|
|
{
|
|
ShaderTextureMapping mapping = p->inputInfo.Textures[i];
|
|
p->SetTexture(GetTexture(mapping.nodeId), mapping.reg);
|
|
}
|
|
|
|
return p;
|
|
}
|
|
case MP_DEPTH_SM:
|
|
{
|
|
IMaterialPass* p = new IMaterialPass(pass);
|
|
String ps, vs;
|
|
compiler->CompileNode(graph->GetNodeByID(0), pass, ps, vs, &p->inputInfo);
|
|
IShader* psh = ResourceManager::me()->CompileUserShaderPS(ps.c_str(), ps.size());
|
|
IShader* vsh = ResourceManager::me()->CompileUserShaderVS(vs.c_str(), vs.size());
|
|
|
|
p->SetShader(ST_PS, psh);
|
|
p->SetShader(ST_VS, vsh);
|
|
|
|
return p;
|
|
}
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
return nullptr;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/*IMaterial::IMaterial(uint32 constantBufferSize)
|
|
:castShadows(false),receiveShadows(false),
|
|
ownerFlags(EF_NONE), AlphaBlendEnable(false)
|
|
{
|
|
Name = AS_STRING("unnamed");
|
|
materialCb = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(PER_MATERIAL_CONSTANTS));
|
|
}
|
|
IMaterial::~IMaterial()
|
|
{
|
|
}
|
|
IConstantBuffer* IMaterial::GetConstantBuffer()
|
|
{
|
|
return materialCb;
|
|
}
|
|
void IMaterial::SetTexture(texture_ptr tex, uint32 slot)
|
|
{
|
|
textureSlots[slot] = tex;
|
|
}
|
|
void IMaterial::Apply()
|
|
{
|
|
for(int i = 0; i < MAX_TEX_SLOT; i++)
|
|
{
|
|
texture_ptr tex = textureSlots[i];
|
|
if(tex.ptr() != 0)
|
|
{
|
|
CG::me()->GetRenderer()->SetPSTexture(tex.ptr(), i);
|
|
}
|
|
}
|
|
|
|
//CG::me()->GetRenderer()->SetPixelShader(g_buffer_pass_ps);
|
|
//CG::me()->GetRenderer()->SetVertexShader(g_buffer_pass_vs);
|
|
}*/ |