포스트

DirecX12 | Lecture 6. 삼각형 띄우기 (인프런)

DirectX12 강의 6. 삼각형 띄우기를 정리한 글입니다.

DirecX12 | Lecture 6. 삼각형 띄우기 (인프런)

강의 정보 🎓


1. DescriptorHeap → SwapChain으로 이전

  • 이유: RTV는 프레임 버퍼와 밀접한 관계 → SwapChain 내부에서 관리하는 것이 적절하다
  • 변경사항:
    • DescriptorHeapInit()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 권장

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가 리소스를 접근하기 위한 뷰 생성 필요
RTVRender Target View – 출력 타겟 버퍼 뷰

요약 및 느낀점 📝

  • 삼각형을 그리기 위해 RootSignature, Mesh, Shader들을 만들었다.
  • HLSLi를 통해서 셰이더 코드를 건들였다.

    느낀점 💡 나만의 컨벤션에 맞춰서 구조를 조금씩 바꾸다 보니 고민이 상당히 많아진다. 예를 들어 수업에서는 매크로를 사용하여 긴 체이닝을 줄여서 사용하였는데 매크로 이외의 방식으로 해결하려다 보니 조금씩 문제가 있을 수 밖에 없었다. 이런 리펙토링에 시간을 좀 쓰고있는데 의미가 있는 일이었으면 좋겠다.

프로젝트 상태 💾

< 실행 시 다음과 같은 삼각형이 그려진다 >

< 실행 시 다음과 같은 삼각형이 그려진다 >

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.