250627

lililllilillll·2025년 6월 26일

개발 일지

목록 보기
215/350

✅ What I did today


  • LeetCode
  • DirectX 12를 이용한 3D 게임 프로그래밍 입문


⚔️ LeetCode


20. Valid Parentheses

bool Twenty::isValid(std::string s)
{
	std::stack<char> cs;
	for (char c : s)
	{
		if (cs.empty())
		{
			cs.push(c);
		}
		// 아래 3개 묶었으면 좋았을듯
		else if (c == ')')
		{
			if (cs.top() == '(') cs.pop();
			else return false;
		}
		else if (c == '}')
		{
			if (cs.top() == '{') cs.pop();
			else return false;
		}
		else if (c == ']')
		{
			if (cs.top() == '[') cs.pop();
			else return false;
		}
		else
		{
			cs.push(c);
		}
	}
	if (!cs.empty()) return false;
	else return true;
}

stack

#include <stack>

std::stack<int> s;
함수설명
s.push(x)원소 삽입 (맨 위에 추가)
s.pop()맨 위 원소 제거
s.top()맨 위 원소 접근
s.empty()비었는지 여부 확인
s.size()현재 원소 수 반환

변수 초기화

저장 영역예시초기화 여부비고
로컬 변수 (자동 저장소)함수 내부 int x;❌ 안 됨 (쓰레기 값)반드시 수동 초기화 필요
글로벌 변수파일 최상단 int x;✅ 자동 0 초기화명시 안 해도 안전
정적 변수static int x;✅ 자동 0 초기화함수 안에 있어도 정적으로 취급
클래스 멤버 변수class A { int x; };❌ 기본적으로 안 됨생성자에서 직접 초기화해야 함

std::stack 같은 건 객체라서 생성자에 의해 자동으로 초기화된다. 그래서 로컬 변수여도 초기화됨. 기본 타입은 생성자 없으므로 로컬 변수일 때 수동 초기화해야됨.



📖 DirectX 12를 이용한 3D 게임 프로그래밍 입문


Part 2 Direct3D의 기초

Chapter 4 Direct3D의 초기화

4.1 기본 지식

Direct3D 12 특징

  • CPU 부담을 크게 줄이고 다중 스레드 지원 개선
  • 이전보다 추상화 줄음
  • 현세대 GPU 좀 더 밀접하게 반영

COM(Component Object Model)

  • 프로그래밍 언어 독립성과 하위 호환성 가능하게 하는 기술
  • COM 인터페이스를 가리키는 포인터를 함수 또는 COM 인터페이스 메서드로 얻는다. (new는 안 씀)
  • COM 인터페이스를 다 사용한 후에는 delete로 삭제하지 않고 Release 메서드를 호출한다
  • COM 인터페이스는 참조 횟수가 0이 되면 메모리에서 해제된다.
  • Microsoft::WRL::ComPtr은 COM 객체를 위한 스마트 포인터다.
  • Get : root COM 인터페이스를 가리키는 포인터 반환
  • GetAddressOf : root COM 인터페이스를 가리키는 포인터의 포인터 반환
  • Reset : ComPtr 인스턴스를 nullptr로 설정하고 root COM 인터페이스의 참조 횟수를 1 감소한다. (직접 nullptr 배정해도 참조 횟수 감소)

텍스처

  • 텍스처에는 DXGI_FORMAT_으로 시작하는 자료형만 담을 수 있다.
  • 무형식 텍스처 : 메모리만 확보해두고 해석 방식은 나중에 텍스처를 파이프라인에 묶을 때 지정

교환 사슬과 페이지 전환

  • 애니메이션 blink 현상 피하기 위해 전면 버퍼에는 이전 프레임 놓아서 가려놓고 후면 버퍼에서 그림
  • 제시(presenting) : 후면 버퍼와 전면 버퍼 교환
  • IDXGISwapChain::ResizeBuffers : 버퍼 크기 변경 메서드
  • IDXGISwapChain::Present : 버퍼 제시 메서드

깊이 버퍼

  • 각 픽셀의 깊이 정보를 담는다. 0.0은 시야 절두체 안에서 관찰자에 최대한 가까운 물체, 1.0은 최대한 먼 물체
  • 어떤 픽셀이 앞에 있는지 확인 위해 깊이 버퍼링 또는 z-버퍼링 기법 사용
  • 깊이 버퍼는 하나의 텍스처이므로 역시 DXGI_FORMAT_으로 시작하는 자료 형식 사용
  • 스텐실 버퍼를 반드시 쓰는 건 아니지만, 사용한다면 항상 깊이 버퍼와 같은 텍스처에 포함됨.

자원과 서술자

  • 렌더링 과정에서 GPU는 자원들(후면 버퍼, 깊이,스텐실 버퍼)에 자료 기록하거나 자원(표면 서술 텍스처나 씬 내 기하구조의 3차원 위치 담은 버퍼)들에서 자료 읽는다. 그러기 전에 자원을 렌더링 파이프라인에 bind해야 함.
  • GPU 자원들이 파이프라인에 직접 bind되는 건 아니고 해당 자원을 참조하는 서술자 객체가 bind된다.
  • 서술자라는 추가 간접 레이어를 두는 이유 : GPU 자원이 범용적 메모리 조각이기 때문. 예를 들어 텍스처를 랜더 대상으로도 사용한 후 셰이더 자원으로도 사용할 수 있음. 자원 자체에는 어떻게 쓰여야할지 정보가 없음.
  • 서술자는 자원 자료를 지정하는 수단이자, 자원을 GPU에 서술하는 수단이다.
  • 뷰는 서술자와 동의어. 뷰는 이전 버전에서 쓰였던 용어.

서술자

  • CBV/SRV/UAV 서술자 : 각각 상수 버퍼, 셰이더 자원, 순서 없는 접근(unordered access view)를 서술
  • 샘플러 서술자 : 텍스처 적용에 쓰이는 샘플러 자원 서술
  • RTV 서술자 : 렌더 타겟 자원 서술
  • DSV 서술자 : 깊이·스텐실 자원 서술
  • 서술자 힙 : 서술자들의 배열. 같은 종류 서술자는 같은 서술자 힙에 저장됨. 한 종류 서술자에 여러 개 힙 둘 수도 있다.
  • 서술자들은 응용 프로그램의 초기화 시점에서 생성해야 함

안티앨리어싱

  • 초과표본화(supersampling) : 후면 버퍼, 깊이 버퍼 크기 4배로 잡고 이미지를 제시할 때 원래 크기 버퍼로 환원(resolving, downsampling)한다. 4픽셀 블록의 네 색상의 평균 사용.
  • 다중표본화(multisampling) : 버퍼 크기 4배는 맞지만 픽셀당 한 번만 계산. 서브픽셀들의 가시성(깊이,스텐실 버퍼 이용)과 포괄도(부분픽셀을 다각형이 얼마나 덮은지)를 이용해서 최종 색상 결정.

멀티샘플링

  • 멀티샘플링을 위해선 DXGI_SAMPLE_DESC라는 구조체를 채워야 한다.
  • DXGI_SAMPLE_DESC는 COUNT, Quality라는 두 개의 멤버로 이루어져 있다.
  • Count는 픽셀당 추출할 표본의 개수를 지정, Quality는 원하는 품질 수준을 지정.
  • ID3D12Device::CheckFeatureSupport : 주어진 텍스처 형식과 표본 개수 조합에 대한 품질 수준들의 개수 알 수 있다. (이거 말고도 여러 정보 알아낼 수 있음)

기능 수준 : GPU가 지원하는 기능들의 집합을 정의함. 다렉 버전마다 대응됨.

DXGI(DirectX Graphics Infrastructure)

  • Direct3D와 함께 쓰이는 API. 2D같은 다른 그래픽 API에도 필요한 작업들 포함.
  • 전체 화면 모드 전환, 디스플렝 어댑터나 모니터, 지원되는 디스플레이 모드 등 제공
  • IDXGIFactory : IDXGISwapChain 인터페이스 생성과 디스플레이 어댑터 열거에 사용됨.
  • IDXGIAdapter : 디스플레이 어댑터 관련 인터페이스

상주성 (residency)

  • 자원이 GPU 메모리에 들어 있는지의 여부
  • 응용 프로그램이 사용하는 GPU 메모리의 양을 최소화하면 좋다
  • 같은 자원을 짧은 시간에 GPU에 넣었다 뺐다 하는 상황은 피하면 좋다
  • ID3D12Device::MakeResident(), ID3D12Device::Evict()를 이용해서 상주성을 직접 제어할 수도 있다.


profile
너 정말 **핵심**을 찔렀어

0개의 댓글