일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 자료구조
- 구현
- DFS
- 트리
- 유니온 파인드
- Team Fortress 2
- ue5
- XR Interaction Toolkit
- 백트래킹
- 재귀
- 백준
- c++
- Unreal Engine 5
- 수학
- 투 포인터
- 그래프
- 그리디 알고리즘
- 알고리즘
- BFS
- 유니티
- 문자열
- 정렬
- 누적 합
- 다익스트라
- 브루트포스
- VR
- 우선순위 큐
- 시뮬레이션
- 다이나믹 프로그래밍
- 스택
- Today
- Total
1일1알
DirectX11 학습 - 프로젝트 기본 프레임워크 본문
[게임 프로그래머 도약반] DirectX11 입문 강의 - 인프런
게임 프로그래머 공부에 있어서 필수적인 DirectX 11 지식을 초보자들의 눈높이에 맞춰 설명하는 강의입니다., [사진][사진] [사진] 게임 개발자는 Unreal, Unity만 사용할 줄 알면 되는 거 아닌가요? 엔
www.inflearn.com
위 강의를 보며 약 2달간 DirectX11을 학습하며 이론으로만 알고있던 렌더링 파이프라인 과정들을 직접 실습해보고 다양한 렌더링 기술들에 대해 학습하였다.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
GameDesc desc;
desc.appName = L"GameCoding";
desc.hInstance = hInstance;
desc.vsync = false;
desc.hWnd = NULL;
desc.width = 1080;
desc.height = 720;
desc.clearColor = Color(0.5f, 0.5f, 0.5f, 1.f);
// IExecute 인터페이스를 상속받은 여러가지 주제들에 대한 클래스
//desc.app = make_shared<Triangle>();
//desc.app = make_shared<P_Texture>();
//desc.app = make_shared<P_3Normal>();
//desc.app = make_shared<P_4_Mesh>();
//desc.app = make_shared<P_5_Light>();
//desc.app = make_shared<P_7_NomalMapping>();
//desc.app = make_shared<P_8_StaticMesh>();
//desc.app = make_shared<P_9_Animation>();
//desc.app = make_shared<P_10_SkyBox>();
desc.app = make_shared<P_RenderAll>();
// GAME : Game 클래스의 싱글톤 객체
GAME->Run(desc);
return 0;
}
우선 기본적인 프레임워크는 다음과 같다.
Game 클래스에서 Run 함수를 통해 프로그램을 시작하는데, Run의 매개변수로 GameDesc를 받아준다.
GameDesc에서는 초기 색상, 해상도 등의 값을 정해주고 IExecute라는 인터페이스를 인자로 가지고 있다.
이 IExecute를 상속받아서 여러가지 주제들에 대한 데모들을 하나씩 만들고 이것을 갈아끼워가면서 프로그램을 구동시키며 학습을 진행하였다.
WPARAM Game::Run(GameDesc& desc)
{
_desc = desc;
assert(_desc.app != nullptr);
// 1) 윈도우 창 정보 등록
MyRegisterClass();
// 2) 윈도우 창 생성
if (!InitInstance(SW_SHOWNORMAL))
return FALSE;
// 싱글돈 매니저들 초기화
GRAPHICS->Init(_desc.hWnd);
TIME->Init();
INPUT->Init(_desc.hWnd);
GUI->Init();
RESOURCES->Init();
_desc.app->Init();
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
Update();
}
}
return msg.wParam;
}
Run 함수 내부에서는 렌더링을 위한 여러가지 초기화 작업을 해준다.
GRAPHICS : Device, DeviceContext Swapchain, RenderTargetView, DepthStencilView 생성, 뷰포트 설정
- Device : GPU와 통신할 수 있는 객체, GPU 관련 리소스 생성
- DeviceContext : Device를 통해 생성된 리소스를 렌더링 파이프라인에 연결
- Swapchain : 더블 버퍼링을 사용하여 화면에 보여주는 버퍼와 그리는 버퍼를 분리
- RenderTargetView : 픽셀쉐이더에서 그려진 결과물을 저장하는 리소스를 묘사하는 View
- DepthStencilView : 깊이, Stencil 정보를 저장한 버퍼를 묘사하는 View
- View : 렌더링 파이프라인에 생성한 리소스를 연결할때는 해당 정보를 그대로 제출하는것이 아니라 해당 정보를 묘사하는 View를 제출한다. (RenderTargetView , DepthStencilView)
나머지 초기화 부분들은 렌더링 부분과는 크게 관련이 없기때문에 넘어가겠다.
그리고 Windows Api를 사용해 Update 함수를 호출되도록 한다.
void Game::Update()
{
TIME->Update();
INPUT->Update();
ShowFps();
GRAPHICS->RenderBegin();
GUI->Update();
SCENE->Update();
_desc.app->Update();
_desc.app->Render();
GUI->Render();
GRAPHICS->RenderEnd();
}
Update에서 중요하게 볼 부분은 GRAPHICS->RenderBegin()과 GRAPHICS->RenderEnd()이다.
void Graphics::RenderBegin()
{
_deviceContext->OMSetRenderTargets(1, _renderTargetView.GetAddressOf(), _depthStencilView.Get());
_deviceContext->ClearRenderTargetView(_renderTargetView.Get(), (float*)(&GAME->GetGameDesc().clearColor));
_deviceContext->ClearDepthStencilView(_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
_vp.RSSetViewport();
}
GRAPHICS->RenderBegin()에서는 RenderTargetView, DepthStencilView를 초기값으로 밀어준 뒤DeviceContext를 통해 렌더링 파이프라인에 연결해준다. 이전 프레임의 값을 그대로 사용하면 안되기 때문에 매 프레임마다 값들을 밀어준다.
그리고 초기에 설정한 뷰포트 또한 DeviceContext를 통해 연결해준다.
void Graphics::RenderEnd()
{
HRESULT hr = _swapChain->Present(1, 0);
CHECK(hr);
}
RenderEnd에서는 Swapchain을 이용해 백버퍼에 그려진 정보를 제출한다.
여기까지 완료한 뒤 IExecute를 상속받은 클래스를 연결한 뒤 아무 코드도 작성하지 않고 실행하면 초기에 설정한 Color(0.5f, 0.5f, 0.5f, 1.f) 즉 회색값이 창에 띄워진다. 물론 중간에 생략한 부분이 꽤 있긴 하지만 크게 중요하지는 않다고 판단되어 넘어갔다.
이제 렌더링 과정에 대한 기본적인 초기화 작업은 끝났고, Update 함수에서 IExecute를 상속받은 클래스 의 Update와 Render함수도 호출해주기 때문에 화면에 그려줄 물체를 생성한 클래스에서 작업해주면 된다.
'DirectX11' 카테고리의 다른 글
DirectX11 학습 - Normal Mapping (0) | 2024.03.30 |
---|---|
DirectX11 학습 - Light (0) | 2024.03.30 |
DirectX11 학습 - Normal Vector (0) | 2024.03.28 |
DirectX11 학습 - 텍스쳐 입히기, 카메라 (0) | 2024.03.28 |
DirectX11 학습 - 삼각형 띄우기 (0) | 2024.03.26 |