SpriteComponent이던, StaticMeshComponent이던 Material을 갖고 있다. Material은 멤버로 아래와 같은 녀석들을 갖고 있다.
CSharedPtr<CGraphicShader> m_Shader;
std::vector<MaterialTextureInfo> m_TextureInfo;
Vector4 m_BaseColor;
float m_Opacity;
class CMaterialConstantBuffer* m_CBuffer;
CSharedPtr<class CRenderState> m_RenderStateArray[(int)RenderState_Type::Max];
enum class RenderState_Type
{
Blend,
Rasterizer,
DepthStencil,
Max
};
여기서 m_RenderStateArray에 RenderState_Type::Blend에 미리 생성해둔 "AlphaBlend"라는 BlendState 클래스를 할당해줘야 한다. 그러면 Material의 Render에서 m_RenderStateArray에 BlendState가 들어있으면 그 BlendState를 아래와 같이 Set해준다.
void CMaterial::Render()
{
// 말 그대로 완성된 m_VS, m_Ps등을 SetShader해주는 함수
if (m_Shader)
m_Shader->SetShader();
// 출력 직전에 m_BaseColor 갱신 후
// 상수버퍼에 갱신한 m_BaseColor로 업데이트
if (m_CBuffer)
{
m_CBuffer->SetBaseColor(m_BaseColor);
m_CBuffer->SetOpacity(m_Opacity);
m_CBuffer->UpdateCBuffer();
}
for (int i = 0; i < (int)RenderState_Type::Max; ++i)
{
if (m_RenderStateArray[i])
m_RenderStateArray[i]->SetState();
}
size_t Size = m_TextureInfo.size();
for (size_t i = 0; i < Size; ++i)
{
// Texture에 대한 Resource view를 Set해주는 함수
m_TextureInfo[i].Texture->SetShader(m_TextureInfo[i].Register, m_TextureInfo[i].ShaderType, 0);
}
}
void CBlendState::SetState()
{
CDevice::GetInst()->GetContext()->OMGetBlendState((ID3D11BlendState**)&m_PrevState, m_PrevBlendFactor, &m_PrevSampleMask);
CDevice::GetInst()->GetContext()->OMSetBlendState((ID3D11BlendState*)m_State, m_BlendFactor, m_SampleMask);
}
SpriteComponent나 StaticMeshComponent가 SetTransParency(true)를 호출하면 Material이 미리 만들어둔 "AlphaBlend"라는 이름의 BlendState를 출력병합기에 Set해줄것이다.
void CSpriteComponent::SetTransparency(bool Enable)
{
m_Material->SetTransparency(Enable);
}
void CMaterial::SetTransparency(bool Enable)
{
if (Enable)
m_RenderStateArray[(int)RenderState_Type::Blend] = CRenderManager::GetInst()->FindRenderState("AlphaBlend");
}
위에서 언급했듯이 "AlphaBlend"라는 이름의 BlendState 클래스는 RenderStateManager에서 이미 만들어서 m_mapRenderState에 넣어뒀다.
bool CRenderStateManager::Init()
{
AddBlendInfo("AlphaBlend");
CreateBlendState("AlphaBlend", true, false);
return true;
}
void CRenderStateManager::AddBlendInfo(const std::string& Name,
bool BlendEnable, D3D11_BLEND SrcBlend,
D3D11_BLEND DestBlend, D3D11_BLEND_OP BlendOp, D3D11_BLEND SrcBlendAlpha,
D3D11_BLEND DestBlendAlpha, D3D11_BLEND_OP BlendOpAlpha,
UINT8 RenderTargetWriteMask)
{
CBlendState* State = (CBlendState*)FindRenderState(Name);
if (!State)
{
State = new CBlendState;
State->SetName(Name);
m_mapRenderState.insert(std::make_pair(Name, State));
}
State->AddBlendInfo(BlendEnable, SrcBlend, DestBlend, BlendOp,
SrcBlendAlpha, DestBlendAlpha, BlendOpAlpha, RenderTargetWriteMask);
}
bool CRenderStateManager::CreateBlendState(const std::string& Name, bool AlphaToCoverageEnable,
bool IndependentBlendEnable)
{
CBlendState* State = (CBlendState*)FindRenderState(Name);
if (!State)
return false;
if (!State->CreateState(AlphaToCoverageEnable, IndependentBlendEnable))
{
SAFE_RELEASE(State);
return false;
}
return true;
}
void CBlendState::AddBlendInfo(bool BlendEnable, D3D11_BLEND SrcBlend, D3D11_BLEND DestBlend,
D3D11_BLEND_OP BlendOp, D3D11_BLEND SrcBlendAlpha, D3D11_BLEND DestBlendAlpha, D3D11_BLEND_OP BlendOpAlpha,
UINT8 RenderTargetWriteMask)
{
D3D11_RENDER_TARGET_BLEND_DESC Desc = {};
Desc.BlendEnable = BlendEnable;
Desc.SrcBlend = SrcBlend;
Desc.DestBlend = DestBlend;
Desc.BlendOp = BlendOp;
Desc.SrcBlendAlpha = SrcBlendAlpha;
Desc.DestBlendAlpha = DestBlendAlpha;
Desc.BlendOpAlpha = BlendOpAlpha;
Desc.RenderTargetWriteMask = RenderTargetWriteMask;
m_vecDesc.push_back(Desc);
}
bool CBlendState::CreateState(bool AlphaToCoverageEnable, bool IndependentBlendEnable)
{
if (m_vecDesc.empty())
return false;
D3D11_BLEND_DESC Desc = {};
Desc.AlphaToCoverageEnable = AlphaToCoverageEnable;
Desc.IndependentBlendEnable = IndependentBlendEnable;
memcpy(Desc.RenderTarget, &m_vecDesc[0], sizeof(D3D11_RENDER_TARGET_BLEND_DESC) * m_vecDesc.size());
if (FAILED(CDevice::GetInst()->GetDevice()->CreateBlendState(&Desc, (ID3D11BlendState**)&m_State)))
return false;
return true;
}
'공부 > Graphics, DirectX, 포트폴리오 구조' 카테고리의 다른 글
Component, Mesh, Matarial간의 관계와 렌더링 과정 요약 필기 (0) | 2022.03.30 |
---|---|
Texture, Render Target 그리고 Surface란? (2) | 2022.01.11 |
[포트폴리오 구조] ResourceManager, SceneResource 그리고 각종 Manager들의 관계 (0) | 2021.12.17 |
DirectX의 더블 버퍼링 (0) | 2021.12.07 |
안티 앨리어싱(Anti-Aliasing), 멀티 샘플링(Multi-Sampling), 알파 포괄도 변환(Alpha-To-Coverage) (0) | 2021.12.03 |