DOTY

DirectX11. 2) D3D11 Initialize 본문

DirectX

DirectX11. 2) D3D11 Initialize

증식세포 2023. 6. 9. 16:27
728x90
반응형

D3DClass는 ApplicationClass 하위에 존재하고 시스템 기능을 처리하게 된다.

이에 따라 ApplicationClass에도 변경점이 존재한다.

 

1. ApplicationClass.h

#ifndef _APPLICATIONCLASS_H_
#define _APPLICATIONCLASS_H_

// #include <windows.h>를 지우고 대체한다.
#include "d3dclass.h"

const bool FULL_SCREEN = false;
const bool VSYNC_ENABLED = true;
const float SCREEN_DEPTH = 1000.0f;
const float SCREEN_NEAR = 0.3f;

class ApplicationClass
{
public:
	ApplicationClass();
	ApplicationClass(const ApplicationClass&);
	~ApplicationClass();

	bool Initialize(int, int, HWND);
	void Shutdown();
	bool Frame();

private:
	bool Render();

private:
	D3DClass* m_Direct3D; // D3DClass를 사용하기 위함.
};

#endif

 

1-1. Initialize

bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
{
	bool result;

	m_Direct3D = new D3DClass;

	result = m_Direct3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);
	if (!result){
		MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK);
		return false;
	}

	return true;
}

0으로 설정된 m_Direct3D를 D3DClass를 사용해주기 위해 클래스 선언을 새로 해준다.

result의 경우 D3DClass의 초기화 부분에서  화면의 크기와 창의 핸들 등을 체크하고 이상이 없으면 true를 반환하게 된다.

 

1-2. Shutdown

D3DClass로 설정된 m_Direct3D를 다시 NULL포인터로 설정하여 초기화시킨다.

 

1-3. Frame

Render함수를 각 프레임마다 호출하여 화면에 그려지게 된다.

 

1-4. Render

m_Direct3D를 호출하여 D3DClass의 BeginScene함수를 활용해 화면의 색을 바꾸고 EndScene함수를 활용하여 창이 표시되도록 한다. 

m_Direct3D->BeginScene(0.5f, 0.5f, 0.5f, 1.0f); // R, G, B, A

위의 코드같은 경우 회색으로 초기화가 된다.

 

2. D3dClass.h

#ifndef _D3DCLASS_H_
#define _D3DCLASS_H_

//Linking
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3dcompiler.lib")

#include <d3d11.h>
#include <directxmath.h>

using namespace DirectX;

class D3DClass
{
public:
	D3DClass();
	D3DClass(const D3DClass&);
	~D3DClass();

	bool Initialize(int, int, bool, HWND, bool, float, float);
	void Shutdown();

	void BeginScene(float, float, float, float);
	void EndScene();

	ID3D11Device* GetDevice();
	ID3D11DeviceContext* GetDeviceContext();

	void GetProjectionMatrix(XMMATRIX&);
	void GetWorldMatrix(XMMATRIX&);
	void GetOrthoMatrix(XMMATRIX&);

	void GetVideoCardInfo(char*, int&);

private:
	bool m_vsync_enabled;
	int m_videoCardMemory;
	char m_videoCardDescription[128];
	IDXGISwapChain* m_swapChain;
	ID3D11Device* m_device;
	ID3D11DeviceContext* m_deviceContext;
	ID3D11RenderTargetView* m_renderTargetView;
	ID3D11Texture2D* m_depthStencilBuffer;
	ID3D11DepthStencilState* m_depthStencilState;
	ID3D11DepthStencilView* m_depthStencilView;
	ID3D11RasterizerState* m_rasterState;
	XMMATRIX m_projectionMatrix;
	XMMATRIX m_worldMatrix;
	XMMATRIX m_orthoMatrix;
};

#endif

 

2-1. D3DClass

D3DClass의 시작은 Private에 있는 모든 멤버 포인터들을 NULL(0)으로 초기화 시켜준다. 

 

2-2. Initialize

bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen,
	float screenDepth, float screenNear)
  • ScreenWidth / ScreenHeight : 창의 너비와 높이로 창 크기를 초기화 시켜준 후에 사용한다.
  • vsync : Direct3D가 사용자 모니터의 프레임에 따라 렌더링이 되도록 하거나 빨리 렌더링 되도록 하거나 설정한다.
  • hwnd : 창에 대한 핸들로 이전에 만들어진 창을 엑세스 하기 위해서 필요하다.
  • fullscreen : 전체 화면으로 보여지는지에 대한 여부이다.
  • ScreenDepth / ScreenNear : 창에서 렌더링 되기 위한 Depth 설정이다.

Initialize의 과정은 다음과 같다.

  1. DirectX 그래픽 인터페이스 팩토리를 생성
  2. 주 그래픽 인터페이스(비디오 카드)용 어댑터를 생성
  3. 어댑터 출력(모니터)을 열거
  4. 지원하는 디스플레이 모드의 목록을 가져옴
  5. 화면의 너비와 높이에 해당하는 디스플레이 모드를 찾고 새로 고침 속도를 저장
  6. 비디오 카드의 설명과 메모리 정보를 얻어옴
  7. DirectX 장치, 스왑 체인, 백 버퍼, 깊이 스텐실 버퍼 등을 생성
  8. 렌더 타겟 뷰, 깊이 스텐실 뷰 등을 생성하고 초기화
  9. 래스터라이저 상태, 뷰포트, 투영 행렬, 월드 행렬 등을 설정

※스왑 체인 : 프레임 버퍼를 관리하는데 사용된다. 화면의 이미지는 프레임 버퍼를 통해 렌더링 되는데 이것을 스왑 체인을 통해서 화면에 표시되도록 한다.

※ 백 버퍼 : 렌더링 된 이미지가 저장되는 메모리 영역. 프레임 버퍼에서 렌더링 된 이미지를 저장한다.

프레임 버퍼에 저장된 값 또는 데이터들(ex. 렌더 버퍼, 지오메트리 버퍼 등)을 그래픽 파이프라인의 일부 과정을 통해 렌더링 되고 렌더링 된 이미지는 백 버퍼에 저장된다. 백 버퍼에 저장된 이미지는 스왑 체인을 통해서 프론트 버퍼로 이동하고 화면에 표시된다. (더욱 명확히 하면 백 버퍼랑 프론트 버퍼가 스왑체인을 통해 스왑된다.)

 

2-3. Shutdown

Initialize함수에서 쓰였던 모든 포인터들을 해제한다. 이때, 전체 화면을 한 상태로 스왑체인을 해제하려고 시도한다면 문제가 일어날 수 있다. 따라서 D3D를 종료하기 전에 창모드를 강제로 적용한다.

// Swapchain 전에 창 모드로 전환
if(m_swapChain)
{
	m_swapChain->SetFullscreenState(false, NULL);
}

 

2-4. BeginScene / EndScene

BeginScene은 각 프레임이 시작할 때 불리는 함수로 새로운 3D장면이 호출될 때마다 버퍼를 초기화 시키는 작업을 한다.

EndScene은 장면을 다 그린 후에 화면에 출력하기 위해 스왑체인을 호출한다. 

 

※ 순서

Main 함수에서 SystemClass의 Run함수를 호출하여 프로그램 시작. Run 함수의 Bool타입 done이 false일 경우 Frame함수가 계속 호출된다. SystemClass의 Frame함수는 ApplicaionClass의 Frame함수를 호출하고 이때 Render함수가 호출된다. Render함수는 D3dClass의 BeginScene EndScene을 호출하고 그림을 그리게 되는데 이때, ESC버튼을 누를 경우 InputClassIsKeyDown함수가 호출되어 SystemClassresult가 false로 바뀌며 Bool타입 done이 true로 바뀌며 While문을 빠져나간다. 후에 모든 Class의 Shutdown함수가 불려지게 되며 프로그램이 종료 된다.

종료 과정에서 PeekMessage(Windows.h에 포함된 함수)를 통해 메세지 큐에 MessageHandler를 통해 저장된 WM_QUIT를 캐치하고 SystemClassRun함수도 종료하게 된다. 

 

2-5. GetDevice / GetDeviceContext

Direct3D 디바이스와 디바이스 컨텍스트 포인터를 가져온다. (도우미 함수)

 

2-6. GetProjectionMatrix / GetWorldMatrix / GetOrthoMatrix

투영행렬, 월드행렬, 직교행렬의 복사본을 호출 함수에 제공한다.

 

2-7. GetVideoCardInfo

비디오카드의 이름과 메모리 양을 참조로 반환한다. 

 

728x90
반응형

'DirectX' 카테고리의 다른 글

DirectX11. 4) Buffer, Shader II  (0) 2023.06.12
DirectX11. 3) Buffer, Shader I  (0) 2023.06.11
DirectX11. 1) 창 띄우기  (0) 2023.06.07
4. DirectXMath - Transform  (1) 2023.05.02
3. DirectXMath - Matrix  (0) 2023.04.24
Comments