DirecX12 | Lecture 6. 삼각형 띄우기 (인프런)
DirectX12 강의 6. 삼각형 띄우기를 정리한 글입니다.
DirecX12 | Lecture 6. 삼각형 띄우기 (인프런)
강의 정보 🎓
- 강의명: C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈 - Part2: 게임 수학과 DirectX12
- 플랫폼: 인프런
- 현재 섹션: Lecture 6 – 삼각형 띄우기
- 주요 내용: DirectX 12를 활용해서 화면에 삼각형을 그렸다.
1. DescriptorHeap → SwapChain으로 이전
- 이유: RTV는 프레임 버퍼와 밀접한 관계 → SwapChain 내부에서 관리하는 것이 적절하다
- 변경사항:
DescriptorHeap
의Init()
을SwapChain::CreateRtv()
로 통합rtvHeapSize
제거 (필요시 함수 호출로 대체)CreateSwapChain()
→ 세분화 및CreateRtv()
호출 포함DescriptorHeap
파일 완전 삭제 → 디버깅 과정 필요
캡슐화(encapsulation)
“필요한 것만 보여주고, 나머지는 숨겨라”
- private: 내부 멤버함수 → 캡슐화
- 외부에서 호출하지 않는 함수들에 대한 캡슐화가 이루어 졌다.
목적 | 설명 |
---|---|
외부 인터페이스 단순화 | 클래스가 제공하는 public API가 적고 명확해짐 |
오용 방지 | 외부에서 잘못된 순서/상태로 내부 함수 호출하는 걸 막음 |
유지보수 용이 | 내부 구현을 바꿔도 public API만 유지하면 외부 영향 없음 |
테스트 안정성 | public 함수만 테스트 대상이면 테스트 범위도 좁고 명확 |
2. 전역 접근 구조 설계 개선
Engine
에서Device
,CommandQueue
,SwapChain
접근 가능하게 Getter 작성매크로 접근 제거
1 2 3 4 5
// 제거 대상 #define DEVICE gEngine::GetInstance().GetDevice()->GetDevice() // 다음으로 바꾸었다. gEngine::GetInstance().GetDeviceLayer()->GetDevice();
inline 함수 + namespace
구조로 대체하려 했지만 헤더 의존성이 생길 수 있다.- 체이닝을 유지하되 이름을 명확하게 하기로 결정(예:
DeviceLayer
등)
- 헤더 의존성 최소화
- 수업에서는 Egine.h에 Device, CommandQueue, SwapChain 등을 미리 인클루드하였다.
Engine.h
에서 하위 모듈을 직접 include ❌- → 전방선언 + 필요 시 직접 include 권장
3. Root Signature 생성
- 기본적인 루트 시그니처 생성 로직 구현
- 세부 Slot 구성 등 세부 내용은 이후 강의에서 다룬다.
4. Mesh 클래스 구성
- 파일 생성:
Mesh.h
,Mesh.cpp
- 멤버 구성:
- Vertex Buffer, Vertex Buffer View, Vertex Count
- 버텍스 구조체 정의:
EnginePch.h
에 정의 →float3 pos
,float4 color
- 메모리 힙 관련
UPLOAD_HEAP
으로 생성- GPU 전송 후
DEFAULT_HEAP
에 복사하여 관리 할 수 있다. - 정적인 데이터는
DEFAULT_HEAP
권장
- GPU 전송 후
5. Shader 클래스 구성
- 파일 생성:
Shader.h
,Shader.cpp
- 책임
- Shader Blob 관리
- RootSignature 및 PSO 관리
- 셰이더 모델: 수업에서는
vs_5_0
,ps_5_0
을 사용했지만 수정하여vs_5_1
,ps_5_1
으로 사용하겠다.
6. HLSL 및 HLSLi
- Default HLSL 파일 생성
- HLSLi: include 전용 HLSL 파일 (상수, 구조체, 공용 함수 등)
7. Client 프로젝트 - Game 구성
Game::Init()
에서 Mesh와 Shader 초기화- 전방 선언으로 의존성을 최소화하였다.
- 정점 정보를 만든다.
Game::Update()
에서 호출 흐름:1 2 3 4 5 6 7
void Game::Update() { Engine::GetInstance().RenderBegin(); shader->Update(); mesh->Render(); Engine::GetInstance().RenderEnd(); }
참고
개념 | 설명 |
---|---|
리소스 생성 | HeapType 에 따라 Upload/Default 지정 |
뷰(View) | GPU가 리소스를 접근하기 위한 뷰 생성 필요 |
RTV | Render Target View – 출력 타겟 버퍼 뷰 |
요약 및 느낀점 📝
- 삼각형을 그리기 위해 RootSignature, Mesh, Shader들을 만들었다.
- HLSLi를 통해서 셰이더 코드를 건들였다.
느낀점 💡 나만의 컨벤션에 맞춰서 구조를 조금씩 바꾸다 보니 고민이 상당히 많아진다. 예를 들어 수업에서는 매크로를 사용하여 긴 체이닝을 줄여서 사용하였는데 매크로 이외의 방식으로 해결하려다 보니 조금씩 문제가 있을 수 밖에 없었다. 이런 리펙토링에 시간을 좀 쓰고있는데 의미가 있는 일이었으면 좋겠다.
프로젝트 상태 💾
< 실행 시 다음과 같은 삼각형이 그려진다 >
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.