For me
[DirectX12] 18) Render Target 본문
위의 사진과 같이 UI에 RenderTarget을 적용한 결과이다.
마치 CCTV처럼 원하는 곳을 다른 곳에 원하는 곳에 한 화면을 그릴 수 있게 함
RenderBegin - Render - RenderEnd 순으로 진행되고,
가지고 있는 모든 RenderTargetGroup 초기화 - 그림자 - Deferred - Light - Final - Forward 순으로 Render 가 진행된다.
RenderTargetGroup.h
더보기
#pragma once
#include "Texture.h"
enum class RENDER_TARGET_GROUP_TYPE : uint8
{
SWAP_CHAIN, // BACK_BUFFER, FRONT_BUFFER
SHADOW, // SHADOW
G_BUFFER, // POSITION, NORMAL, COLOR
LIGHTING, // DIFFUSE LIGHT, SPECULAR LIGHT
END,
};
enum
{
RENDER_TARGET_SHADOW_GROUP_MEMBER_COUNT = 1,
RENDER_TARGET_G_BUFFER_GROUP_MEMBER_COUNT = 3,
RENDER_TARGET_LIGHTING_GROUP_MEMBER_COUNT = 2,
RENDER_TARGET_GROUP_COUNT = static_cast<uint8>(RENDER_TARGET_GROUP_TYPE::END)
};
struct RenderTarget
{
shared_ptr<Texture> target;
float clearColor[4];
};
class RenderTargetGroup
{
public:
void Create(RENDER_TARGET_GROUP_TYPE groupType, vector<RenderTarget>& rtVec, shared_ptr<Texture> dsTexture);
void OMSetRenderTargets(uint32 count, uint32 offset);
void OMSetRenderTargets();
void ClearRenderTargetView(uint32 index);
void ClearRenderTargetView();
shared_ptr<Texture> GetRTTexture(uint32 index) { return _rtVec[index].target; }
shared_ptr<Texture> GetDSTexture() { return _dsTexture; }
void WaitTargetToResource();
void WaitResourceToTarget();
private:
RENDER_TARGET_GROUP_TYPE _groupType;
vector<RenderTarget> _rtVec;
uint32 _rtCount;
shared_ptr<Texture> _dsTexture;
ComPtr<ID3D12DescriptorHeap> _rtvHeap;
private:
uint32 _rtvHeapSize;
D3D12_CPU_DESCRIPTOR_HANDLE _rtvHeapBegin;
D3D12_CPU_DESCRIPTOR_HANDLE _dsvHeapBegin;
private:
D3D12_RESOURCE_BARRIER _targetToResource[8];
D3D12_RESOURCE_BARRIER _resourceToTarget[8];
};
RenderTargetGroup.cpp
더보기
#include "pch.h"
#include "RenderTargetGroup.h"
#include "Engine.h"
#include "Device.h"
void RenderTargetGroup::Create(RENDER_TARGET_GROUP_TYPE groupType, vector<RenderTarget>& rtVec, shared_ptr<Texture> dsTexture)
{
_groupType = groupType;
_rtVec = rtVec;
_rtCount = static_cast<uint32>(rtVec.size());
_dsTexture = dsTexture;
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
heapDesc.NumDescriptors = _rtCount;
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
heapDesc.NodeMask = 0;
DEVICE->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_rtvHeap));
_rtvHeapSize = DEVICE->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
_rtvHeapBegin = _rtvHeap->GetCPUDescriptorHandleForHeapStart();
_dsvHeapBegin = _dsTexture->GetDSV()->GetCPUDescriptorHandleForHeapStart();
for (uint32 i = 0; i < _rtCount; i++)
{
uint32 destSize = 1;
D3D12_CPU_DESCRIPTOR_HANDLE destHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(_rtvHeapBegin, i * _rtvHeapSize);
uint32 srcSize = 1;
ComPtr<ID3D12DescriptorHeap> srcRtvHeapBegin = _rtVec[i].target->GetRTV();
D3D12_CPU_DESCRIPTOR_HANDLE srcHandle = srcRtvHeapBegin->GetCPUDescriptorHandleForHeapStart();
DEVICE->CopyDescriptors(1, &destHandle, &destSize, 1, &srcHandle, &srcSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
}
for (int i = 0; i < _rtCount; ++i)
{
_targetToResource[i] = CD3DX12_RESOURCE_BARRIER::Transition(_rtVec[i].target->GetTex2D().Get(),
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COMMON);
_resourceToTarget[i] = CD3DX12_RESOURCE_BARRIER::Transition(_rtVec[i].target->GetTex2D().Get(),
D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
}
void RenderTargetGroup::OMSetRenderTargets(uint32 count, uint32 offset)
{
D3D12_VIEWPORT vp = D3D12_VIEWPORT{ 0.f, 0.f, _rtVec[0].target->GetWidth() , _rtVec[0].target->GetHeight(), 0.f, 1.f };
D3D12_RECT rect = D3D12_RECT{ 0, 0, static_cast<LONG>(_rtVec[0].target->GetWidth()), static_cast<LONG>(_rtVec[0].target->GetHeight()) };
GRAPHICS_CMD_LIST->RSSetViewports(1, &vp);
GRAPHICS_CMD_LIST->RSSetScissorRects(1, &rect);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(_rtvHeapBegin, offset * _rtvHeapSize);
GRAPHICS_CMD_LIST->OMSetRenderTargets(count, &rtvHandle, FALSE/*1개*/, &_dsvHeapBegin);
}
void RenderTargetGroup::OMSetRenderTargets()
{
D3D12_VIEWPORT vp = D3D12_VIEWPORT{ 0.f, 0.f, _rtVec[0].target->GetWidth() , _rtVec[0].target->GetHeight(), 0.f, 1.f };
D3D12_RECT rect = D3D12_RECT{ 0, 0, static_cast<LONG>(_rtVec[0].target->GetWidth()), static_cast<LONG>(_rtVec[0].target->GetHeight()) };
GRAPHICS_CMD_LIST->RSSetViewports(1, &vp);
GRAPHICS_CMD_LIST->RSSetScissorRects(1, &rect);
GRAPHICS_CMD_LIST->OMSetRenderTargets(_rtCount, &_rtvHeapBegin, TRUE/*다중*/, &_dsvHeapBegin);
}
void RenderTargetGroup::ClearRenderTargetView(uint32 index)
{
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(_rtvHeapBegin, index * _rtvHeapSize);
GRAPHICS_CMD_LIST->ClearRenderTargetView(rtvHandle, _rtVec[index].clearColor, 0, nullptr);
GRAPHICS_CMD_LIST->ClearDepthStencilView(_dsvHeapBegin, D3D12_CLEAR_FLAG_DEPTH, 1.f, 0, 0, nullptr);
}
void RenderTargetGroup::ClearRenderTargetView()
{
WaitResourceToTarget();
for (uint32 i = 0; i < _rtCount; i++)
{
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(_rtvHeapBegin, i * _rtvHeapSize);
GRAPHICS_CMD_LIST->ClearRenderTargetView(rtvHandle, _rtVec[i].clearColor, 0, nullptr);
}
GRAPHICS_CMD_LIST->ClearDepthStencilView(_dsvHeapBegin, D3D12_CLEAR_FLAG_DEPTH, 1.f, 0, 0, nullptr);
}
void RenderTargetGroup::WaitTargetToResource()
{
GRAPHICS_CMD_LIST->ResourceBarrier(_rtCount, _targetToResource);
}
void RenderTargetGroup::WaitResourceToTarget()
{
GRAPHICS_CMD_LIST->ResourceBarrier(_rtCount, _resourceToTarget);
}
'DirectX12' 카테고리의 다른 글
[DirectX12] 20) Compute Shader (0) | 2023.01.19 |
---|---|
[DirectX12] 19) Deferred , Forward Rendering (0) | 2023.01.19 |
[DirectX12] 17) 직교투영 (0) | 2023.01.19 |
[DirectX12] 16) Quaternion (0) | 2023.01.19 |
[DirectX12] 15) SkyBox (0) | 2023.01.18 |