03 장치 초기화

한경식·2024년 12월 17일
  • COM(Component Object Model) 객체
    • 정의
      • 컴포넌트들이 상호 통신할 수 있도록 하는 메커니즘
      • 인터페이스(IUnknown 인터페이스)를 통해 상호작용이 가능
    • 특징
      • 언어 독립성: 어떤 언어로 만들던 다른 언어로 만든 프로그램 모듈처럼 동작 가능
      • Binary Standard: 바이너리로 되어있어 이걸 사용하기 위해 특정 언어의 소스가 필요 없음
      • Version Control: 예전 버전에서도 사용 가능하고, 새로운 기능 업데이트 되면 버전에 상관없이 호환 가능
      • Location Transparency: 해당 컴포넌트의 관계없이 다른 컴포넌트나 프로그램에 의해 사용 가능
  • 스마트 포인터 ComPtr<>
    • COM 객체들을 할당, 해제할 땐 AddRef(), Release() 함수를 사용하여 하는데 이를 편하고 한번에 관리하기 위해 제공되는 스마트 포인터이다
    • wrl.h와 using namespace Microsoft::WRL 을 추가하여 사용이 가능하다
  • ID3D11Device
    • 정의
      • GPU와 통신, 그래픽 리소스 생성하는 핵심 객체
    • 리소스 만드는 법
      • CreateDevice()
        • 하나의 리소스만을 생성
      • CreateDeviceAndSwapChain()
        • 여러개의 리소스를 동시 생성
  • ID3D11DeviceContext
    • 정의
      • 만들어진 리소스를 렌더링 파이프라인에 연결시켜주는 객체
  • IDXGI
    • 정의
      • 그래픽 소프트웨어의 발전보다 출력하는 하드웨어의 발전이 느리기 때문에 이를 보완하기 위해 만든 인터페이스를 제공하는 API
      • 그래픽 관련 리소스 관리와 디스플레이 출력을 관리
    • IDXGISwapChain
      • 정의
        • 프레임을 렌더링 할 버퍼의 연결(큐)로, 주로 이중, 삼중 버퍼링을 설정하는데 사용
        • 인터페이스는 프레임을 화면에 출력하는 데 필요한 스왑 체인을 생성 관리. 이 기능은 프레임 간의 전환과 동기화 담당
  • CreateDeviceAndSpawnChain
void Game::CreateDeviceAndSpwaChain()
{
	DXGI_SWAP_CHAIN_DESC desc;
	ZeroMemory(&desc, sizeof(desc));//== memset과 같다
	{
		//버퍼의 해상도를 지정
		desc.BufferDesc.Width = width;
		desc.BufferDesc.Height = height;

		//분자/분모를 통해 해상도를 만듦
		desc.BufferDesc.RefreshRate.Numerator = 60;
		desc.BufferDesc.RefreshRate.Denominator = 1;

		desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

		//멀티샘플링시 보간을 위해 사용
		desc.SampleDesc.Count = 1;

		desc.SampleDesc.Quality = 0;

		//GPU가 연산이 끝났을 때 최종 결과물을 그려주는 역할로 사용하겠다 라는 옵션
		desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

		//후면버퍼 갯수
		desc.BufferCount = 1;
		//윈도우 헨들
		desc.OutputWindow = hwnd;

		desc.Windowed = true;
		desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	}

	////스마트 포인터를 사용하기 때문에 함수를 통해 꺼내야함, D3D11Device* a;
	//device.Get();//현재 D3D11Device의 값을 꺼내줌, a
	//device.GetAddressOf();//현재 D3D11Device의 값의 주소값을 꺼내줌, &a

	HRESULT hr = ::D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &desc, swapChain.GetAddressOf(), device.GetAddressOf(), nullptr, deviceContext.GetAddressOf());
	//D3D_DRIVER_TYPE_ 내가가진 그래픽을 그릴 수 있는 놈을 선택

	CHECK(hr);//->assert 메크로를 CHECK 메크로로 만듦
}
  • CreateRenderTargetView
//ID3D11RenderTargetView 우리가 만든 후면 버퍼를 묘사하는 객체
ComPtr<ID3D11RenderTargetView> renderTargetView;

//View가 달린 함수들은 어떤 자원에 대해 태그를 달아 GPU에게 설명을 하기위한 부연설명으로 이해하기
void Game::CreateRenderTargetView()
{
	HRESULT hr;

	ComPtr<ID3D11Texture2D> backBuffer{};
	//swapChain에 만들어 놓은 백버퍼에서 texture 리소스를  ID3D11Texture2D로 넘겨줌
	hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuffer.GetAddressOf());
	CHECK(hr);
	device->CreateRenderTargetView(backBuffer.Get(), nullptr, renderTargetView.GetAddressOf());
}
  • SetViewport
//화면의 크기를 묘사해줌
D3D11_VIEWPORT viewport;
float clearColor[4] = { 1.0f,0.5f ,0.5f ,0.5f };

void Game::SetViewport()
{
	viewport.TopLeftX = 0.0f;
	viewport.TopLeftY = 0.0f;
	viewport.Width = static_cast<float>(width);
	viewport.Height = static_cast<float>(height);
	viewport.MinDepth = 0.0f;
	viewport.MaxDepth = 1.0f;
}

void Game::Render()
{
	RenderBegin();

	//TODO

	RenderEnd();
}

void Game::RenderBegin()
{
	//GPU가 그림을 그리는 것까지 성공하며 렌더링파이프라인에 OM에 후면버퍼나 전면버퍼에 그려달라고 전해주는 함수
	deviceContext->OMSetRenderTargets(1, renderTargetView.GetAddressOf(), nullptr);

	deviceContext->ClearRenderTargetView(renderTargetView.Get(), clearColor);
	deviceContext->RSSetViewports(1, &viewport);
}

void Game::RenderEnd()
{
	//후면 버퍼에서 전면 버퍼로 복사해서 출력해주는 함수로 중요하다
	HRESULT hr = swapChain->Present(1, 0);
	CHECK(hr);
}
  • 결과
    • 리소스를 만들어 GPU로 백버퍼에 그림을 그린 뒤 전면 버퍼로 복사해 주어 출력해준 것이다
profile
게임 개발 지망생

0개의 댓글