[DirectX11] 2. 기본 설정

유기태·2023년 11월 30일
0

DirectX강의 필기

목록 보기
3/14

Device setting

1. Device,DC 초기화

  • 가상 어댑터 즉, 그래픽 하드웨어를 추상화 해주는 객체라고 보면된다.
  • D3D11CreateDevice()
  • D3D_DRIVER_TYPE_HARDWARE
    하드웨어 디바이스(즉, gpu가 있을 시 D3D_DRIVER_TYPE_HARDWARE 설정) 해당 장치로 초기화하겠다는 뜻
  • D3D11_CREATE_DEVICE_DEBUG : DX는 동적 라이브러리임 그래서 이에 대한 오류를 받기 위해서는 해당 인자값이 필요
  • D3D11_SDK_VERSION d3d11 : 라이브러리 버전
  • Device 객체를 반환함 : Device 객체는 포인터 변수이기 때문에 해당 Device에 주소를 주기 위해 더블 포인터로 반환
  • DC 객체 역시 같은 원리로 더블 포인터로 반환
int Device::Init(HWND _hWnd, POINT _vResolution)
{
	m_vRenderResolution = _vResolution;
	m_hRenderWnd = _hWnd;
	// 장치 초기화
	D3D_FEATURE_LEVEL eLevel = D3D_FEATURE_LEVEL_11_0;
	
	if (FAILED(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 
		D3D11_CREATE_DEVICE_DEBUG, nullptr, 0, D3D11_SDK_VERSION, 
		m_Device.GetAddressOf(), &eLevel, m_Context.GetAddressOf())))
	{
		return E_FAIL;
	}

	// 스왑 체인 생성
	if (FAILED(CreateSwapChain()))
	{
		return E_FAIL;
	}

	// 렌더 타켓 뷰
	if (FAILED(CreateTargetView()))
	{
		return E_FAIL;
	}

	return S_OK;
}

2. SwapChain 생성

업로드중..

※ DXGI(DirectX Graphics Infrastructure)
: 그래픽 카드를 운영체제에서 추상화 해줄 때 드라이버와 이 DXGI 객체를 통해 추상화해준다.

  • 전면 buffer와 back buffer를 활용해 서로 스와핑을하며, 화면을 업데이트 하는것을 말한다.
  • winapi같은 경우 메모리에 표시되는 bitmap에 그림을 그려놓고 화면에 출력되는 maindc에 있는 bitmap에 복사하는 방법을 사용했다면
  • DX는 그 두 그림판을 그래픽 어뎁터가 번갈아가면서 가리키며, 사용자에게 마치 여러 그림이 이어지는거 같은 착각을 준다.
int Device::CreateSwapChain()
{
	// SwapChain 생성 구조체
	DXGI_SWAP_CHAIN_DESC tDesc = {};

	// SwapChain 이 관리하는 Buffer(RenderTarget) 의 구성 정보
	tDesc.BufferCount = 1;
	tDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	tDesc.BufferDesc.Width = (UINT)m_vRenderResolution.x;
	tDesc.BufferDesc.Height = (UINT)m_vRenderResolution.y;
	tDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // buffer에 pixle format
	tDesc.BufferDesc.RefreshRate.Denominator = 1; // 분모 1
	tDesc.BufferDesc.RefreshRate.Numerator = 60; // 분자 60 
	tDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	tDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	tDesc.Flags = 0;

	tDesc.SampleDesc.Count = 1;
	tDesc.SampleDesc.Quality = 0;

	tDesc.Windowed = true; // 창모드
	tDesc.OutputWindow = m_hRenderWnd; // swapchain 출력 윈도우 지정
	
	// swapchain을 생성시키는 객체 생성
	IDXGIDevice* pIdxgiDevice = nullptr;
	IDXGIAdapter* pAdapter = nullptr;
	IDXGIFactory* pFactory = nullptr;

	m_Device->QueryInterface(__uuidof(IDXGIDevice), (void**)&pIdxgiDevice);
	pIdxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pAdapter);
	pAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&pFactory);

	pIdxgiDevice->Release();
	pAdapter->Release();
	pFactory->Release();


	// 스왑 체인 생성
	if(FAILED(pFactory->CreateSwapChain(m_Device.Get(), &tDesc, m_SwapChain.GetAddressOf())))
	{
		return E_FAIL;
	}

	return S_OK;
}

3. RenderTargetView 생성

※ View 객체는 DX resource(texture,buffer)를 가리키고 있는 객체라 생각하면 된다.
DX에서는 resource들이 각자의 역할을 가지고 있는데 resource를 사용하는 곳에서 그 사용처에 맞지 않은 객체를 사용하는것(resource는 다 같은 타입이기때문에)를 방지하기 위해 resource가 아닌 resource를 가리키고 있는 View 객체를 호출한다.

View 객체에 대한 texture가 오류를 내지 않았다면, View 객체는 왠만하면 오류를 내지 않는다!

RenderTargetView
  • 렌더타켓 텍스쳐를 스왑체인으로 부터 얻어온다.
  • 스왑 체인을 보면 버퍼를 생성했음( 스왑 체인이 관리하는 렌더 텍스쳐가 생성됨(옛날에 DC로 생성한 bitmap이라 생각하면됨 )
  • 해당 버퍼는 GPU안에 있는 메모리에 적재됨 예전 API 프로젝트 같은 경우 RAM에 저장되었는데
  • GPU 상에 존재하는 리소스를 관리해주는 역할을 함
  • ID3D11Resource(부모 클래스) 자식 - > buffer , texture2d 등이 있음
  • swapchain으로 부터 만들어진 buffer resource를 가리키기 위해 사용함
// 렌더타켓 텍스쳐를 스왑체인으로 부터 얻어온다.
	// 스왑 체인을 보면 버퍼를 생성했음( 스왑 체인이 관리하는 렌더 텍스쳐가 생성됨(옛날에 DC로 생성한 bitmap이라 생각하면됨 )
	// 해당 버퍼는 GPU안에 있는 메모리에 적재됨 예전 API 프로젝트 같은 경우 RAM에 저장되었는데
	// GPU 상에 존재하는 리소스를 관리해주는 역할을 함
	// ID3D11Resource(부모 클래스) 자식 - > buffer , texture2d 등이 있음
	// swapchain으로 부터 만들어진 buffer resource를 가리키기 위해 사용함
	if (FAILED(m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)m_RTTex.GetAddressOf())))
	{
		return E_FAIL;
	}

	// RenderTargetView
	// DepthStencilView texture는 없음
	// ShaderResourceView 
	// UnorderedAccessView

	// 리소스 객체를 이용해서 중간에 view가 생성됨 리소스가 필요한 곳은 view를 달라함
	// 이유 : 텍스터를 하나 만들때도 용도가 정해져있음 즉, 그 용도에 맞는 view를 달라해야 그 용도에 맞게 가져올 수 있음
	// 이유는 해당 리소스 뷰는 그 리소스로 밖에 생성하지 못하기 때문
	// 하지만 예외로 용도에 맞는 뷰를 만들 수 있는 리소스 객체도 있음
	// rendertargettview : 그림이 그려질 곳(rendertarget texture를 가리키고 있음)
	// shaderview : 저장해놓고 그림을 그릴곳에 복사할 원본
	// 왠만하면 해당 함수는 실패할 일이 없음 그 전에 texture가 오류가 날 수는 있지만 
	// 그 전에 함수 역시 swapchain이 오류를 내지 해당 함수는 오류를 낼 경우가 없음
	if (FAILED(m_Device->CreateRenderTargetView(m_RTTex.Get(), nullptr, m_RTView.GetAddressOf())))
	{
		return E_FAIL;
	}
DepthStencilView
  • DepthStencil 텍스쳐는 렌더타켓 텍스쳐와 1대1 매칭 되어야 하므로 크기는 같아야한다.
  • 해당 pixel의 depth와 stencil 정보를 담고 있는 texture를 가리키는 view객체이다.
  • rendertarget texture처럼 자동으로 생성되지 않기 때문에 임의로 texture를 만들어서 view객체를 만들어야한다.
  • 깊이를 나타내는 정보는 3바이트 스텐실을 나타내는 정보는 1바이트로
  • 깊이를 나타내는 3바이트의 정보는 카메라 구도에서 가까운 픽셀을 렌더링하고 먼 픽셀을 렌더링하지 않는 과정에 필요
  • 스텐실 데이터는 렌더링을 할지 안할지에 대한 정보를 표시하는 거 같다.(확실치 않음 내일 질문?)
  • 스텐실 데이터는 거울과같은 물체를 비추는 사물을 거울에 투영할때 사용할 수 있다는듯하다.
// DepthStencilTexture
	// pixel 하나당 4바이트
	// 4바이트는 깊이를 저장한 것
	// 1바이트는 stencil 정보를 저장한 것
	D3D11_TEXTURE2D_DESC Desc = {};

	Desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;

	// DepthStencilState 텍스쳐 해상도는 반드시 RenderTargetTexture와 동일해야한다.
	Desc.Width = (UINT)m_vRenderResolution.x;
	Desc.Height = (UINT)m_vRenderResolution.y;

	// 깊이를 저장하는 texture다라고 용도를 정해주는것
	Desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;

	// GPU 메모리를 사용하여 만들어진다고 했으나, 
	// CPU (주메모리)와 연락을 위한 flag
	Desc.CPUAccessFlags = 0;
	Desc.Usage = D3D11_USAGE_DEFAULT;

	// 샘플링은 고정
	Desc.SampleDesc.Count = 1;
	Desc.SampleDesc.Quality = 0;

	// 저퀄리티 버전의 사본 샘플
	// 원본에 해상도를 점점 낮추는것
	// 거리에 따른 해상도에 활용함
	Desc.MipLevels = 1;
	Desc.MiscFlags = 0;

	Desc.ArraySize = 1;
	if (FAILED(m_Device->CreateTexture2D(&Desc, nullptr, m_DSTex.GetAddressOf())))
	{
		return E_FAIL;
	}
	//	DepthStencilView 

	if (FAILED(m_Device->CreateDepthStencilView(m_DSTex.Get(), nullptr, m_DSView.GetAddressOf())))
	{

		return E_FAIL;
	}
OM Stage
  • OMSetRenderTargets()
  • 렌더링 파이프라인에 최종단계
  • 최종적으로 가져온 fragment 들의 depth, stencil에 따라 화면에 출력해주는 단계
profile
게임프로그래머 지망!

0개의 댓글