Post

[RasterTek/DirectX 11] #3 DirectX 11 ์ดˆ๊ธฐํ™”

[RasterTek/DirectX 11] #3 DirectX 11 ์ดˆ๊ธฐํ™”

๐Ÿ“– ์ฐธ๊ณ ์ž๋ฃŒ


๐Ÿ–ฅ๏ธ ๊ฐœ๋ฐœํ™˜๊ฒฝ

  • Window 11
  • Visual Studio 2022


Updated Framework

---
title: Framework
config:
  look: handDrawn
  theme: neutral
---
graph TD
	WinMain --- SystemClass
	SystemClass --- InputClass
	SystemClass --- ApplicationClass
    ApplicationClass --- D3DClass

Direct3D ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค(D3DClass).

ApplicationClass ๋‚ด๋ถ€์— ๊ทธ๋ž˜ํ”ฝ ๊ด€๋ จ ํด๋ž˜์Šค๊ฐ€ ์บก์Šํ™”๋˜๋ฏ€๋กœ, D3DClass๋„ ApplicationClass ๋‚ด๋ถ€์— ํฌํ•จ๋œ๋‹ค.


ApplicationClass.h

1
2
3
4
5
////////////////////////////////////////////////////////////////////////////////
// Filename:  applicationclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _APPLICATIONCLASS_H_
#define _APPLICATIONCLASS_H_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
///////////////////////
// MY CLASS INCLUDES //
///////////////////////
#include "d3dclass.h"

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


////////////////////////////////////////////////////////////////////////////////
// Class name: ApplicationClass
////////////////////////////////////////////////////////////////////////////////
class ApplicationClass
{
public:
	ApplicationClass();
	ApplicationClass(const ApplicationClass&);
	~ApplicationClass();

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

private:
	bool Render();

private:
	D3DClass* m_Direct3D;
};

#endif

๋ณ€๊ฒฝ์ 

  1. windows.h ๋Œ€์‹  d3dclass.h๋ฅผ include
  2. D3DClass์˜ ์ƒˆ private ํฌ์ธํ„ฐ(m_Direct3D) ์ถ”๊ฐ€
    • m_: ํด๋ž˜์Šค ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ธ์ง€ ๊ตฌ๋ณ„


ApplicationClass.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "applicationclass.h"


ApplicationClass::ApplicationClass()
{
	m_Direct3D = 0;
}


ApplicationClass::ApplicationClass(const ApplicationClass& other)
{
}


ApplicationClass::~ApplicationClass()
{
}


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

	// D3D ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™”
	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;
}


void ApplicationClass::Shutdown()
{
	// D3D ๊ฐ์ฒด ํ•ด์ œ

	if (m_Direct3D)
	{
		m_Direct3D->Shutdown();
		delete m_Direct3D;
		m_Direct3D = 0;
	}

	return;
}


bool ApplicationClass::Frame()
{
	bool result;

	// ๊ทธ๋ž˜ํ”ฝ ๋ Œ๋”๋ง
	result = Render();
	if (!result)
	{
		return false;
	}

	return true;
}


bool ApplicationClass::Render()
{
	// ๋ฒ„ํผ๋ฅผ ๋น„์šฐ๊ณ  scene ์‹œ์ž‘
	m_Direct3D->BeginScene(0.5f, 0.5f, 0.5f, 1.0f);

	// ๋ Œ๋”๋ง๋œ scene์„ ํ™”๋ฉด์— ํ‘œ์‹œ
	m_Direct3D->EndScene();

	return true;
}

๋ณ€๊ฒฝ์ 

  1. ์ƒ์„ฑ์ž

    • ํฌ์ธํ„ฐ nullptr ์ดˆ๊ธฐํ™”

      ํฌ์ธํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด ๋ณ€์ˆ˜๋ฅผ ํ•ญ์ƒ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค!

  2. Initialize

    • D3DClass ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜ ํ˜ธ์ถœ
      • ํ™”๋ฉด ๋„ˆ๋น„, ๋†’์ด, ํ•ธ๋“ค, ApplicationClass์ „์—ญ ๋ณ€์ˆ˜ ์ „๋‹ฌ
      • D3D๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ D3D System ์„ค์ •
  3. shutdown

    • D3DClass ์ข…๋ฃŒ ์ฝ”๋“œ ์ถ”๊ฐ€

      ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ ๊ฐ์ฒด๋Š” ์ด ํ•จ์ˆ˜์—์„œ ์ข…๋ฃŒ๋œ๋‹ค!

    • ํฌ์ธํ„ฐ๋ฅผ nullptr๋กœ ์ดˆ๊ธฐํ™”

      • ํฌ์ธํ„ฐ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜์ง€ ์•Š์Œ

      • ํฌ์ธํ„ฐ๊ฐ€ ์œ ํšจํ•œ ๊ฒฝ์šฐ shutdown()์„ ํ˜ธ์ถœํ•˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ

        ๋งŒ์•ฝ, ์ด๋ฏธ nullptr์ด๋ฉด ์•„์ง ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ, ๋ถˆํ•„์š”ํ•œ shutdown ํ˜ธ์ถœx

  4. Frame
    • ๊ฐ ํ”„๋ ˆ์ž„๋งˆ๋‹ค Render ํ•จ์ˆ˜ ํ˜ธ์ถœ => ๊ทธ๋ž˜ํ”ฝ ๋ Œ๋”๋ง
  5. Render
    • D3D๋ฅผ ์‚ฌ์šฉํ•ด ํ™”๋ฉด์„ ํšŒ์ƒ‰์œผ๋กœ ์ดˆ๊ธฐํ™”
    • ์ดˆ๊ธฐํ™” ํ›„ EndScene์„ ํ˜ธ์ถœํ•ด ๋ Œ๋”๋ง๋œ ์”ฌ์„ ์œˆ๋„์šฐ์— ํ‘œ์‹œ


D3dclass.h

1
2
3
4
5
////////////////////////////////////////////////////////////////////////////////
// Filename: d3dclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _D3DCLASS_H_
#define _D3DCLASS_H_


LINKING

1
2
3
4
5
6
/////////////
// LINKING //
/////////////
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3dcompiler.lib")

ํ—ค๋”์—์„œ ์ฒซ ๋ฒˆ์งธ๋กœ ํ•  ์ผ: ์˜ค๋ธŒ์ ํŠธ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋งํฌํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ง€์ •

  1. d3d11.lib: D3D์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ ํฌํ•จ
    • DX11์—์„œ 3D ๊ทธ๋ž˜ํ”ฝ์„ ์„ค์ •ํ•˜๊ณ  ๊ทธ๋ฆฌ๋Š”๋ฐ ์‚ฌ์šฉ
  2. dxgi.lib: ์ปดํ“จํ„ฐ์˜ ํ•˜๋“œ์›จ์–ด์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋„๊ตฌ ํฌํ•จ
    • ๋ชจ๋‹ˆํ„ฐ์˜ ์ฃผ์‚ฌ์œจ(refresh rate), ๊ทธ๋ž˜ํ”ฝ์นด๋“œ ์ •๋ณด ๋“ฑ์„ ์ œ๊ณต๋ฐ›์Œ
  3. d3dcompiler.lib: ์…ฐ์ด๋” ์ปดํŒŒ์ผ ๊ธฐ๋Šฅ ํฌํ•จ


INCLUDE

1
2
3
#include <d3d11.h>
#include <directxmath.h>
using namespace DirectX;
  • d3d11.h: ์˜ค๋ธŒ์ ํŠธ ๋ชจ๋“ˆ์— ๋งํฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • directxmath.h: DX ํƒ€์ž… ์ •์˜, ์ˆ˜ํ•™ ์—ฐ์‚ฐ ๊ธฐ๋Šฅ

    e.g.) ์ˆ˜ํ•™ ์—ฐ์‚ฐ, ๊ทธ๋ž˜ํ”ฝ ๋ฐ์ดํ„ฐ ๋“ฑ -> ๋ฒกํ„ฐ, ํ–‰๋ ฌ, ์ขŒํ‘œ, ์ƒ‰์ƒ ๋“ฑ


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class D3DClass
{
public:
	D3DClass();
	D3DClass(const D3DClass&);
	~D3DClass();

	/* D3D ์ดˆ๊ธฐํ™” ๋ฐ ํ•ด์ œ */
	bool Initialize(int, int, bool, HWND, bool, float, float);	 // D3D ์ดˆ๊ธฐํ™”
	void Shutdown();	// D3D ๊ฐ์ฒด/๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ

	/* getter / setter */ 
	
	// Scene ์‹œ์ž‘ ๋ฐ ์ถœ๋ ฅ
	void BeginScene(float, float, float, float);	// ํ™”๋ฉด ๊ทธ๋ฆฌ๊ธฐ ์ „, ๋ฒ„ํผ ์ดˆ๊ธฐํ™”
	void EndScene();	// ๋ Œ๋”๋ง ํ›„ ๋ฒ„ํผ ์ถœ๋ ฅ

	ID3D11Device* GetDevice();	// D3D ๋””๋ฐ”์ด์Šค ๊ฐ์ฒด(๊ทธ๋ž˜ํ”ฝ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ)
	ID3D11DeviceContext* GetDeviceContext();	// D3D ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ(ํŒŒ์ดํ”„๋ผ์ธ ์Šคํ…Œ์ด์ง€๋กœ ์ ‘๊ทผํ•ด GPU์— ๋ Œ๋”๋ง ๋ช…๋ น)

	// ํ–‰๋ ฌ ๋ฐ˜ํ™˜
	void GetProjectionMatrix(XMMATRIX&);	// 3D ํˆฌ์˜ ํ–‰๋ ฌ
	void GetWorldMatrix(XMMATRIX&);			// 3D ์›”๋“œ ๋ณ€ํ™˜ ํ–‰๋ ฌ(3D ์˜ค๋ธŒ์ ํŠธ ์œ„์น˜ ๋ฐ ํšŒ์ „ ๋ณ€ํ™˜)
	void GetOrthoMatrix(XMMATRIX&);			// 2D ์ง๊ต ํ–‰๋ ฌ (2D ๋ Œ๋”๋ง ์œ„ํ•จ)

	void GetVideoCardInfo(char* cardName, int& memory);	// ๋น„๋””์˜ค ์นด๋“œ ์ •๋ณด(์ด๋ฆ„, ํฌ๊ธฐ)
	
	void SetBackBufferRenderTarget();	// ๋ฐฑ ๋ฒ„ํผ๋ฅผ ํ˜„์žฌ ๋ Œ๋” ํƒ€๊ฒŸ์œผ๋กœ ์„ค์ •(๋ Œ๋”๋ง ๋Œ€์ƒ)
    
	void ResetViewport();	// ๋ทฐํฌํŠธ ์ดˆ๊ธฐํ™”(ํฌ๊ธฐ, ์œ„์น˜)

private:
	bool m_vsync_enabled;	// ์ˆ˜์ง ๋™๊ธฐํ™” ํ™œ์„ฑํ™”

	int m_videoCardMemory;	// ๋น„๋””์˜ค ์นด๋“œ ๋ฉ”๋ชจ๋ฆฌ(mb)
	char m_videoCardDescription[128];	// ๋น„๋””์˜ค ์นด๋“œ ์ด๋ฆ„

	IDXGISwapChain* m_swapChain;	// ์Šค์™‘ ์ฒด์ธ(๋”๋ธ” ๋ฒ„ํผ๋ง์šฉ)

	ID3D11Device* m_device;	// D3D ๋””๋ฐ”์ด์Šค ๊ฐ์ฒด (GPU๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ)
	ID3D11DeviceContext* m_deviceContext;	// D3D ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ (์ด์นœ๊ตฌ๊ฐ€ ๋ Œ๋”๋ง ๋ช…๋ น ๋‚ด๋ฆผ)

	ID3D11RenderTargetView* m_renderTargetView;	// ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ(๋ Œ๋”๋ง ์ถœ๋ ฅ)
	
	ID3D11Texture2D* m_depthStencilBuffer;	// ๊นŠ์ด ์Šคํ…์‹ค ๋ฒ„ํผ
	ID3D11DepthStencilState* m_depthStencilState;	// ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ
	ID3D11DepthStencilView* m_depthStencilView;	// ๊นŠ์ด ์Šคํ…์‹ค ๋ทฐ

	ID3D11RasterizerState* m_rasterState;	// ๋ž˜์Šคํ„ฐ๋ผ์ด์ € ์ƒํƒœ(์ปฌ๋ง, ์™€์ด์–ดํ”„๋ ˆ์ž„ ๋“ฑ)

	XMMATRIX m_projectionMatrix;	// ํˆฌ์˜ ํ–‰๋ ฌ
	XMMATRIX m_worldMatrix;	// ์›”๋“œ ํ–‰๋ ฌ
	XMMATRIX m_orthoMatrix;	// ์ง๊ต ํ–‰๋ ฌ

	D3D11_VIEWPORT m_viewport;	// ๋ทฐํฌํŠธ ์„ค์ •(๊ตฌ์กฐ์ฒด)
};

#endif

D3DClass์˜ ํด๋ž˜์Šค ์ •์˜๋Š” ์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑ๋˜์—ˆ๋‹ค.

  • ๊ธฐ๋ณธ ์ƒ์„ฑ์ž, ๋ณต์‚ฌ ์ƒ์„ฑ์ž, ์†Œ๋ฉธ์ž

์ด๋ฒˆ ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” Initialize, Shutdown ํ•จ์ˆ˜๋ฅผ ์ค‘์ ์œผ๋กœ ํ•œ๋‹ค.

๋ทฐ ํ–‰๋ ฌ(View Matrix)๋Š” ์นด๋ฉ”๋ผ ํด๋ž˜์Šค์— ํฌํ•จ๋  ์˜ˆ์ •์ด๋ฏ€๋กœ, ํ•ด๋‹น ํด๋ž˜์Šค์— ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์•˜๋‹ค.


D3dclass.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
D3DClass::D3DClass()
{
	m_swapChain = 0;
	m_device = 0;
	m_deviceContext = 0;
	m_renderTargetView = 0;
	m_depthStencilBuffer = 0;
	m_depthStencilState = 0;
	m_depthStencilView = 0;
	m_rasterState = 0;
}

D3DClass::D3DClass(const D3DClass&)
{
}

D3DClass::~D3DClass()
{
}

์ƒ์„ฑ์ž์—์„œ ๋ชจ๋“  ๋ฉค๋ฒ„ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๋ฅผ null์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.


Initialize()


๋งค๊ฐœ ๋ณ€์ˆ˜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear)
{
	HRESULT result;
    
	IDXGIFactory* factory;
	IDXGIAdapter* adapter;
	IDXGIOutput* adapterOutput;
    
	unsigned int numModes, i, numerator, denominator;
	unsigned long long stringLength;
    
	DXGI_MODE_DESC* displayModeList;
	DXGI_ADAPTER_DESC adapterDesc;
    
	int error;
    
	DXGI_SWAP_CHAIN_DESC swapChainDesc;
    
	D3D_FEATURE_LEVEL featureLevel;
    
	ID3D11Texture2D* backBufferPtr;
	D3D11_TEXTURE2D_DESC depthBufferDesc;
    
	D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
    
	D3D11_RASTERIZER_DESC rasterDesc;
    
	float fieldOfView, screenAspect;


	// vsync ์„ค์ • ์ €์žฅ
	m_vsync_enabled = vsync;

D3DClass::Initialize: DX11 ์ „์ฒด ์„ค์ •

  • ๋งค๊ฐœ๋ณ€์ˆ˜
    • ScreenWidth: ์œˆ๋„์šฐ ๋„ˆ๋น„
    • ScreenHeight: ์œˆ๋„์šฐ ๋†’์ด
    • hwnd: ์œˆ๋„์šฐ ํ•ธ๋“ค(D3D๊ฐ€ ์œˆ๋„์šฐ์— ์ ‘๊ทผ)
    • fullscreen: ์ „์ฒด ํ™”๋ฉด ๋ชจ๋“œ
    • screenDepth: 3Dํ™”๋ฉด์˜ ๊นŠ์ด(์›๊ทผ ํˆฌ์˜) ์„ค์ •. Z-Far
    • screenNear: 3Dํ™”๋ฉด์˜ ๊นŠ์ด(์›๊ทผ ํˆฌ์˜) ์„ค์ •. Z-Near
    • vsync: ์ˆ˜์ง ๋™๊ธฐํ™” ์„ค์ •(t: ์ฃผ์‚ฌ์œจ์— ๋งž์ถฐ ๋ Œ๋”๋ง, f: ์ตœ๋Œ€ํ•œ ๋น ๋ฅด๊ฒŒ ๋ Œ๋”๋ง)



๋ชจ๋‹ˆํ„ฐ ์ฃผ์‚ฌ์œจ ํ™•์ธ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    // DX ๊ทธ๋ž˜ํ”ฝ ์ธํ„ฐํŽ˜์ด์Šค ํŒฉํ† ๋ฆฌ ์ƒ์„ฑ
    result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
    if(FAILED(result))
    {
        return false;
    }

    // ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ๋ณธ ๊ทธ๋ž˜ํ”ฝ ์ธํ„ฐํŽ˜์ด์Šค(๋น„๋””์˜ค ์นด๋“œ) ์–ด๋Œ‘ํ„ฐ ์ƒ์„ฑ
    result = factory->EnumAdapters(0, &adapter);
    if(FAILED(result))
    {
        return false;
    }

    // ๊ธฐ๋ณธ ์–ดํƒญํ„ฐ ์ถœ๋ ฅ(๋ชจ๋‹ˆํ„ฐ) ์—ด๊ฑฐ
    result = adapter->EnumOutputs(0, &adapterOutput);
    if(FAILED(result))
    {
        return false;
    }

    // ์–ด๋Œ‘ํ„ฐ ์ถœ๋ ฅ(๋ชจ๋‹ˆํ„ฐ)์— ๋Œ€ํ•ด DXGI_FORMAT_R8G8B8A8_UNORM ๋””์Šคํ”Œ๋ ˆ์ด ํฌ๋งท์„ ์ง€์›ํ•˜๋Š” ๋ชจ๋“œ ๊ฐœ์ˆ˜ ๊ฐ€์ ธ์˜ด
    result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
    if(FAILED(result))
    {
        return false;
    }

    // ํ˜„์žฌ ๋ชจ๋‹ˆํ„ฐ, ๋น„๋””์˜ค ์นด๋“œ ์กฐํ•ฉ์— ๋Œ€ํ•ด ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ๋ฅผ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ
    displayModeList = new DXGI_MODE_DESC[numModes];
    if(!displayModeList)
    {
        return false;
    }

    // ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ ๊ตฌ์กฐ์ฒด์— ์ •๋ณด ์ €์žฅ
    result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
    if(FAILED(result))
    {
        return false;
    }

    // ๋ชจ๋“  ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ ๊ฒ€์‚ฌ -> ํ™”๋ฉด ๋„ˆ๋น„์™€ ๋†’์ด๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“œ ํƒ์ƒ‰
    // ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“œ๋ฅผ ์ฐพ์œผ๋ฉด -> ๋ชจ๋‹ˆํ„ฐ ์ฃผ์‚ฌ์œจ์˜ ๋ถ„์ž(Numerator)์™€ ๋ถ„๋ชจ(Denominator)๋ฅผ ์ €์žฅ
    for(i=0; i<numModes; i++)
    {
        if(displayModeList[i].Width == (unsigned int)screenWidth)
        {
            if(displayModeList[i].Height == (unsigned int)screenHeight)
            {
                numerator = displayModeList[i].RefreshRate.Numerator;
                denominator = displayModeList[i].RefreshRate.Denominator;
            }
        }
    }

๋น„๋””์˜ค ์นด๋“œ/์ฃผ์‚ฌ์œจ ์ •๋ณด

  • D3D ์ดˆ๊ธฐํ™” ์ „, ๋น„๋””์˜ค ์นด๋“œ ๋ฐ ๋ชจ๋‹ˆํ„ฐ์˜ ์ฃผ์‚ฌ์œจ ์ •๋ณด ์š”์ฒญ

    ์™œ? ์ปดํ“จํ„ฐ๋งˆ๋‹ค ์ฃผ์‚ฌ์œจ์ด ๋‹ค๋ฅด๋ฏ€๋กœ, ์ด๋ฅผ ์ฟผ๋ฆฌํ•ด ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค!

    • ๋ถ„์ž, ๋ถ„๋ชจ๊ฐ’์„ ์ฟผ๋ฆฌํ•œ ํ›„, DX ์„ค์ •์—์„œ ํ•ด๋‹น ๊ฐ’ ์ „๋‹ฌ
      • DX๋Š” ๋ถ„์ž/๋ถ„๋ชจ๊ฐ’์„ ํ† ๋Œ€๋กœ ์ •ํ™•ํ•œ ์ฃผ์‚ฌ์œจ์„ ๊ณ„์‚ฐ

    ๐ŸŒฑ ๋งŒ์•ฝ, ์ฃผ์‚ฌ์œจ ๊ณ„์‚ฐ ๊ณผ์ •์„ ์ƒ๋žตํ•œ๋‹ค๋ฉด(๊ธฐ๋ณธ๊ฐ’ ์„ค์ •)?

    => DX๊ฐ€ ๋ฒ„ํผ ํ”Œ๋ฆฝ ๋Œ€์‹  blit์„ ์ˆ˜ํ–‰ํ•ด ๋ Œ๋”๋ง ์„ฑ๋Šฅ ์ €ํ•˜, ๋””๋ฒ„๊ทธ ์ถœ๋ ฅ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ’ก Buffer filp VS blit

  • buffer filp(DXGI_SWAP_EFFECT_FLIP_DISCARD): ํ”„๋ก ํŠธ ๋ฒ„ํผ์™€ ๋ฐฑ ๋ฒ„ํผ ์Šค์œ„์นญ

  • blit(DXGI_SWAP_EFFECT_DISCARD): ํ”„๋ ˆ์ž„์„ ์ง์ ‘ ๋ณต์‚ฌํ•ด ํ™”๋ฉด์— ๊ทธ๋ฆผ

BitBlit ๋ชจ๋ธ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๋ณต์‚ฌ์— ํ™”๋ฉด์— ๊ทธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— GPU ์—ฐ์‚ฐ์ด ๋ถ€๊ณผ๋œ๋‹ค.

GPU ์—ฐ์‚ฐ ๋ถ€๋‹ด์„ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•ด UWP ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ Flip ์Šค์™‘์„ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ๋‹ค. DXGI_SWAP_EFFECT_DISCARD๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, UWP ํ™˜๊ฒฝ์œผ๋กœ ํฌํŒ…ํ•˜๋ฉด Win32 ํ™˜๊ฒฝ๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. => GPU ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.


์ฐธ๊ณ :

Microsoft Learn: BitBlt function (wingdi.h)

Microsoft Learn: DXGI_SWAP_EFFECT enumeration (dxgi.h)



๋น„๋””์˜ค ์นด๋“œ ์ •๋ณด

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    // ์–ด๋Œ‘ํ„ฐ(๋น„๋””์˜ค ์นด๋“œ) ์„ค๋ช… ์ •๋ณด ๊ฐ€์ ธ์˜ด
    result = adapter->GetDesc(&adapterDesc);
    if(FAILED(result))
    {
        return false;
    }

    // ๋น„๋””์˜ค ์นด๋“œ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ(๋‹จ์œ„: megabytes)
    m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);

    // ๋น„๋””์˜ค ์นด๋“œ ์ด๋ฆ„์„ char ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ ํ›„ ์ €์žฅ
    error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128);
    if(error != 0)
    {
        return false;
    }

์–ด๋Œ‘ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋””์˜ค ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ(m_videoCardMemory)์™€ ์ด๋ฆ„(m_videoCardDescription)์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.



์‚ฌ์šฉํ•œ ๊ตฌ์กฐ์ฒด์™€ ์ธํ„ฐํŽ˜์ด์Šค ํ•ด์ œ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    // ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ ๋ฆฌ์ŠคํŠธ ํ•ด์ œ
    delete [] displayModeList;
    displayModeList = 0;

    // ์–ด๋Œ‘ํ„ฐ ์ถœ๋ ฅ ํ•ด์ œ
    adapterOutput->Release();
    adapterOutput = 0;

    // ์–ด๋Œ‘ํ„ฐ ํ•ด์ œ
    adapter->Release();
    adapter = 0;

    // DXGI ํŒฉํ† ๋ฆฌ ํ•ด์ œ
    factory->Release();
    factory = 0;

์ฃผ์‚ฌ์œจ ๋ถ„์ž, ๋ถ„๋ชจ ๊ฐ’๊ณผ ๋น„๋””์˜ค์นด๋“œ ์ •๋ณด๋ฅผ ์ €์žฅํ–ˆ์œผ๋ฏ€๋กœ, ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ๋˜ ๊ตฌ์กฐ์ฒด์™€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•ด์ œํ•œ๋‹ค.



์Šค์™‘ ์ฒด์ธ ์ดˆ๊ธฐํ™”

1
2
3
4
5
6
7
8
9
10
11
12
    // ์Šค์™‘ ์ฒด์ธ Desc ์ดˆ๊ธฐํ™”
    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));

    // ์‹ฑ๊ธ€ ๋ฐฑ ๋ฒ„ํผ ์„ค์ •
    swapChainDesc.BufferCount = 1;

    // ๋ฐฑ ๋ฒ„ํผ์˜ ๋„ˆ๋น„ ๋ฐ ๋†’์ด ์„ค์ •
    swapChainDesc.BufferDesc.Width = screenWidth;
    swapChainDesc.BufferDesc.Height = screenHeight;

    // ๋ฐฑ ๋ฒ„ํผ์˜ ์ƒ‰์ƒ ํ˜•์‹์„ ์ผ๋ฐ˜ 32-bit์œผ๋กœ ์ง€์ •
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;

SwapChainDesc

  • SwapChain: ํ”„๋ก ํŠธ ๋ฒ„ํผ - ๋ฐฑ ๋ฒ„ํผ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ
    • ๋ฐฑ ๋ฒ„ํผ์—์„œ ๋ Œ๋”๋งํ•œ ํ›„ ํ”„๋ก ํŠธ ๋ฒ„ํผ๋กœ ์Šค์™‘ํ•ด ํ™”๋ฉด์— ํ‘œ์‹œ



์ฃผ์‚ฌ์œจ(Refresh rate) ์„ค์ •

1
2
3
4
5
6
7
8
9
10
11
// ๋ฐฑ ๋ฒ„ํผ์˜ ์ฃผ์‚ฌ์œจ ์„ค์ •
if (m_vsync_enabled)
{
	swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
	swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
}
else
{
	swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
	swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
}

์ฃผ์‚ฌ์œจ: ๋ฐฑ ๋ฒ„ํผ๋ฅผ ํ”„๋ก ํŠธ ๋ฒ„ํผ๋กœ ์ดˆ๋‹น ๋ช‡ ๋ฒˆ ์ „ํ™˜ํ•˜๋Š”์ง€ ๋‚˜ํƒ€๋‚ด๋Š” ๋น„์œจ

  • vsync == true
    • ์ฃผ์‚ฌ์œจ์ด ์‹œ์Šคํ…œ ์„ค์ •์— ๋”ฐ๋ฆ„ (e.g.) 60Hz)
  • vsync == false
    • DX๊ฐ€ ์ฃผ์‚ฌ์œจ์„ ๋ฌด์‹œํ•˜๊ณ  ์ตœ๋Œ€ํ•œ ๋น ๋ฅธ ์†๋„๋กœ ํ™”๋ฉด ๊ฐฑ์‹ 
    • ๋‹จ, ์‹œ๊ฐ์  ์•„ํ‹ฐํŒฉํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ (e.g. Screen Tearing)


๐Ÿ’ก Hz VS FPS

  • ์ฃผ์‚ฌ์œจ(Hz): ๋ชจ๋‹ˆํ„ฐ๊ฐ€ 1์ดˆ๋งˆ๋‹ค ํ™”๋ฉด์— ์ƒ์„ฑํ•˜๋Š” ์ด๋ฏธ์ง€ ๊ฐœ์ˆ˜
  • ํ”„๋ ˆ์ž„ ๋ ˆ์ดํŠธ(FPS): GPU๊ฐ€ 1์ดˆ๋งˆ๋‹ค ์ƒ์„ฑํ•˜๋Š” ํ”„๋ ˆ์ž„ ๊ฐœ์ˆ˜



์Šค์™‘ ์ฒด์ธ ์„ค์ •

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
	// ๋ฐฑ ๋ฒ„ํผ์˜ ์‚ฌ์šฉ ๋ชฉ์  ์„ค์ •
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;	// ๋ Œ๋” ํƒ€๊ฒŸ ์ถœ๋ ฅ(GPU๊ฐ€ ๋ฐฑ ๋ฒ„ํผ์— ๊ทธ๋ฆฌ๊ธฐ ๊ฐ€๋Šฅ)

	// ๋ Œ๋”๋งํ•  ์œˆ๋„์šฐ ํ•ธ๋“ค ์„ค์ •
	swapChainDesc.OutputWindow = hwnd;
	
	// ๋ฉ€ํ‹ฐ ์ƒ˜ํ”Œ๋ง ๋น„ํ™œ์„ฑํ™”
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;


	// Fullscreen | Windowed ์„ค์ •
	if (fullscreen)
	{
		swapChainDesc.Windowed = false;
	}
	else
	{
		swapChainDesc.Windowed = true;
	}

	// scan line ์ˆœ์„œ ๋ฐ ์Šค์ผ€์ผ๋ง์„ ๋ฏธ์ง€์ •์œผ๋กœ ์„ค์ •
	swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

	// ์‚ฌ์šฉ ํ›„ ๋ฐฑ ๋ฒ„ํผ ๋‚ด์šฉ ์‚ญ์ œ
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	// ๊ณ ๊ธ‰ ํ”Œ๋ž˜๊ทธ ์„ค์ •x
	swapChainDesc.Flags = 0;

DXGI_USAGE: ๋ฐฑ ๋ฒ„ํผ์˜ ์‚ฌ์šฉ ๋ชฉ์  ์„ค์ •

  • DXGI_USAGE_BACK_BUFFER: ๋ฐฑ ๋ฒ„ํผ ์‚ฌ์šฉ
    • ์Šค์™‘ ์ฒด์ธ์„ ์‚ฌ์šฉํ•  ๋•Œ ํ•ด๋‹น ํ”Œ๋ž˜๊ทธ๋ฅผ ์ „๋‹ฌํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ๋ฆฌ์†Œ์Šค๊ฐ€ ์Šค์™‘ ์ฒด์ธ์— ์†ํ•ด ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค!
  • DXGI_USAGE_DISCARD_ON_PRESENT: ์ƒˆ ํ”„๋ ˆ์ž„์„ ๊ทธ๋ฆฐ ํ›„ ๋ฐฑ ๋ฒ„ํผ๋Š” ์ž๋™ ์‚ญ์ œ
  • DXGI_USAGE_READ_ONLY: ๋ฆฌ์†Œ์Šค๋ฅผ ์ฝ๊ธฐ ์ „์šฉ ๋ฆฌ์†Œ์Šค๋กœ ์‚ฌ์šฉ
  • DXGI_USAGE_RENDER_TARGET_OUTPUT: GPU๊ฐ€ ๋ Œ๋”๋ง ํƒ€๊ฒŸ/๋ฆฌ์†Œ์Šค๋ฅผ ์ถœ๋ ฅ (ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋ฐฑ ๋ฒ„ํผ)
  • DXGI_USAGE_SHADER_INPUT: ์…ฐ์ด๋”์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ…์Šค์ฒ˜, ๋ฒ„ํผ ๋ฐ์ดํ„ฐ
  • DXGI_USAGE_SHARED: ๋ Œ๋” ํƒ€๊ฒŸ์ด๋‚˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ 
  • DXGI_USAGE_UNORDERED_ACCESS: GPU๋กœ ์—ฐ์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์†Œ์Šค
    • GPU ๋ณ‘๋ ฌ ์—ฐ์‚ฐ -> ์ˆœ์„œ๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๋น ๋ฅด๊ฒŒ ๋ฐ์ดํ„ฐ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋„๋ก!



Feature Level

1
2
	// DX11์„ Feature Level๋กœ ์ง€์ •
	featureLevel = D3D_FEATURE_LEVEL_11_0;

Feature Level

  • DirectX์—์„œ ์‚ฌ์šฉํ•  ๋ฒ„์ „ ์„ ํƒ



swap chain, D3D device ์ƒ์„ฑ

1
2
3
4
5
6
7
8
// ์Šค์™‘ ์ฒด์ธ, D3D ๋””๋ฐ”์ด์Šค, D3D ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
                                       &featureLevel, 1, D3D11_SDK_VERSION,
                                       &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);
if (FAILED(result))
{
	return false;
}

์•ž์„œ ์Šค์™‘ ์ฒด์ธ๊ณผ Feature Level์„ ์„ค์ •์„ ์™„๋ฃŒํ–ˆ๋‹ค. ์Šค์™‘ ์ฒด์ธ๊ณผ Direct3D ๋””๋ฐ”์ด์Šค, ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

Direct3D ๋””๋ฐ”์ด์Šค, ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋Š” ๋ชจ๋“  Direct3D ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋œ๋‹ค. ๋งค์šฐ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ž„!

๊ฑฐ์˜ ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ ์ฝ”๋”ฉ ๊ณผ์ •์—์„œ ๋””๋ฐ”์ด์Šค์™€ ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.


DX11 ์ด์ „ ๋ฒ„์ „์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, Direct3D ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋Š” ์ƒ์†Œํ•  ๊ฒƒ์ด๋‹ค. ์ด์ „ ๋ฒ„์ „์˜ ๊ธฐ์กด ๊ธฐ๋Šฅ์„ ๋””๋ฐ”์ด์Šค์™€ ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋กœ ๋ถ„๋ฆฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ.

๋‘ ๊ธฐ๋Šฅ์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.


DirectX 11 ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ, ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด๋„ ๋””๋ฐ”์ด์Šค์™€ ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.

๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๊ฐ€ ์—†๋‹ค๋ฉด, D3D_DRIVER_TYPE_HARDWARE๋ฅผ D3D_DRIVER_TYPE_REFERENCE๋กœ ๋ฐ”๊พธ์–ด CPU๊ฐ€ ๋Œ€์‹  ๋ Œ๋”๋งํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‹จ, ์„ฑ๋Šฅ์ด 1/1000 ์ •๋„๋‹ค.)


๋””๋ฐ”์ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ์ฃผ ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๊ฐ€ DirectX11์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์‹คํŒจํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ์ฃผ ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๊ฐ€DirectX10, ๋ณด์กฐ ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๊ฐ€ DirectX11์ธ ๊ฒฝ์šฐ

  2. ์ผ๋ถ€ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ(์ฃผ๋ฅผ ์ €์ „๋ ฅ Intel, ๋ณด์กฐ๋ฅผ ๊ณ ์ „๋ ฅ Nvidia๋กœ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ)

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๊ธฐ๋ณธ ๋””๋ฐ”์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๋ฅผ ๋‚˜์—ดํ•œ ํ›„, ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ GPU๋ฅผ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.



Back Buffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	// ๋ฐฑ ๋ฒ„ํผ ํฌ์ธํ„ฐ ๊ฐ€์ ธ์˜ด
	result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
	if (FAILED(result))
	{
		return false;
	}

	// ๋ฐฑ ๋ฒ„ํผ๋ฅผ ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ๋กœ ์„ค์ •
	result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView);
	if (FAILED(result))
	{
		return false;
	}

	// ๋ฐฑ ๋ฒ„ํผ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๊ฐ€ ๋”์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•ด์ œ
	backBufferPtr->Release();
	backBufferPtr = 0;

์ฐจํ›„ ๋ฒ„ํผ ์Šค์™‘์„ ์œ„ํ•ด, ๋ฐฑ ๋ฒ„ํผ์˜ ํฌ์ธํ„ฐ๋ฅผ ์Šค์™‘ ์ฒด์ธ์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

  • CreateRenderTargetView ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐฑ ๋ฒ„ํผ๋ฅผ ๋ Œ๋” ํƒ€๊ฒŸ์œผ๋กœ ์„ค์ •
  • ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ๋ฐฑ ๋ฒ„ํผ ํฌ์ธํ„ฐ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ ํ•ด์ œ
    • Release() ํ˜ธ์ถœ ์‹œ DirectX ๋‚ด๋ถ€์—์„œ ์ฐธ์กฐ ์นด์šดํŠธ ๊ฐ์†Œ(๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ)


๐ŸŒฑ ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ (Render Target View)

  • ๋ฐฑ ๋ฒ„ํผ๋Š” ๋ฉ”๋ชจ๋ฆฌ์—๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ, ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
  • ๋ Œ๋”๋ง์„ ์œ„ํ•ด ๋ฐฑ ๋ฒ„ํผ๋ฅผ ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ๋กœ ์„ค์ • (CreateRenderTargetView)
    • ๋ Œ๋” ํƒ€๊ฒŸ(๋ Œ๋”๋งํ•  ๊ณต๊ฐ„)์„ GPU๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค!
    • Direct3D์—์„œ ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ๋ฅผ ํ†ตํ•ด ๊ทธ๋ž˜ํ”ฝ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•ด์ง
  • RTV๋Š” OM ์Šคํ…Œ์ด์ง€์—์„œ ์‚ฌ์šฉ๋จ
    • OMSetRenderTargets๋กœ ์ ์šฉํ•ด์•ผ ์‹ค์งˆ์ ์ธ ๋ Œ๋”๋ง์ด ์ด๋ฃจ์–ด์ง



Depth Buffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	// Depth Buffer Desc ์ดˆ๊ธฐํ™”
	ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));

	// Depth Buffer Desc ์„ค์ •
	depthBufferDesc.Width = screenWidth;
	depthBufferDesc.Height = screenHeight;
	depthBufferDesc.MipLevels = 1;
	depthBufferDesc.ArraySize = 1;
	depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthBufferDesc.SampleDesc.Count = 1;
	depthBufferDesc.SampleDesc.Quality = 0;
	depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthBufferDesc.CPUAccessFlags = 0;
	depthBufferDesc.MiscFlags = 0;

	// ์ดˆ๊ธฐํ™”ํ•œ Desc๋ฅผ ์‚ฌ์šฉํ•ด ๊นŠ์ด ๋ฒ„ํผ ์ƒ์„ฑ
    result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
    if (FAILED(result))
    {
        return false;
    }

Depth Buffer (๊นŠ์ด ๋ฒ„ํผ, Z-๋ฒ„ํผ)

  • ํด๋ฆฌ๊ณค์ด 3D ํ™˜๊ฒฝ์—์„œ ์ œ๋Œ€๋กœ ๋ Œ๋”๋ง๋  ์ˆ˜ ์žˆ๋„๋ก ๊นŠ์ด ๋ฒ„ํผ ์ƒ์„ฑ
  • ๊นŠ์ด ๋ฒ„ํผ์— ์Šคํ…์‹ค ๋ฒ„ํผ ์ถ”๊ฐ€
    • ๋ชจ์…˜ ๋ธ”๋Ÿฌ, Volumetric Shadows ๊ฐ™์€ ๊ทธ๋ž˜ํ”ฝ ํšจ๊ณผ ๊ตฌํ˜„ ๊ฐ€๋Šฅ


์™œ ๊นŠ์ด ๋ฒ„ํผ๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ CreateTexture2D ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ์„๊นŒ?

  • ๊นŠ์ด ๋ฒ„ํผ๋Š” 2D ํ…์Šค์ฒ˜๋กœ ์ด๋ฃจ์–ด์ง
    • ํด๋ฆฌ๊ณค์ด ์ •๋ ฌ๋˜๊ณ  ๋ž˜์Šคํ„ฐํ™”๋œ ํ›„, 2D๋กœ ๋งคํ•‘๋˜์–ด ํ™”๋ฉด์— ์ถœ๋ ฅ๋˜๊ธฐ ๋•Œ๋ฌธ!



Depth Stencil ์„ค์ •

Depth Stencil Desc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	// Depth Stencil Desc ์ดˆ๊ธฐํ™”
	ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

	// Depth Stencil Desc ์„ค์ •
	depthStencilDesc.DepthEnable = true;
	depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

	depthStencilDesc.StencilEnable = true;
	depthStencilDesc.StencilReadMask = 0xFF;
	depthStencilDesc.StencilWriteMask = 0xFF;

	// ํ”ฝ์…€์ด Front-Facing์ธ ๊ฒฝ์šฐ ์Šคํ…์‹ค ์—ฐ์‚ฐ
	depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
	depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// ํ”ฝ์…€์ด Back-Facing์ธ ๊ฒฝ์šฐ ์Šคํ…์‹ค ์—ฐ์‚ฐ
	depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
	depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

๊นŠ์ด ์Šคํ…์‹ค ์„ค๋ช…(Depth Stencil Desc)์„ ์„ค์ •ํ•œ๋‹ค.

D3D๊ฐ€ ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด ์–ด๋–ค ์œ ํ˜•์˜ ๊นŠ์ด ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ• ์ง€ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.


Depth Stencil State

1
2
3
4
5
6
7
8
9
    // ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ ์ƒ์„ฑ (๋””๋ฐ”์ด์Šค ์‚ฌ์šฉ)
    result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
    if (FAILED(result))
    {
        return false;
    }

    // ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ ์ ์šฉ (๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ ์‚ฌ์šฉ)
    m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);

Desc๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ(Depth Stencil State) ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์ƒ์„ฑ๋œ ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ๋ฅผ OM ์Šคํ…Œ์ด์ง€์— ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ, ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์„ค์ •ํ•œ๋‹ค.


๐ŸŒฑ ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ

desc๋กœ ์ €์žฅํ•œ ์„ค์ •๊ฐ’์„ ์ƒํƒœ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด ๊นŠ์ด-์Šคํ…์‹ค ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.


๐ŸŒฑ ์™œ ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ ์‚ฌ์šฉ?

๋ Œ๋”๋ง ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜, ์–ด๋– ํ•œ ๊ทธ๋ž˜ํ”ฝ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ!

cf) ๊นŠ์ด ์Šคํ…์‹ค ์ƒํƒœ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ๋””๋ฐ”์ด์Šค์˜ ๋‚ด์žฅ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋‹ค.


Depth Stencil View

1
2
3
4
5
6
7
8
9
10
	// Depth Stencil View ์ดˆ๊ธฐํ™”
	ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));

	// Depth Stencil View Desc ์„ค์ •
	depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	depthStencilViewDesc.Texture2D.MipSlice = 0;

	// Depth Stencil View Desc ์ƒ์„ฑ
	result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);

๊นŠ์ด ์Šคํ…์‹ค ๋ทฐ ์„ค๋ช…(Depth Stencil View Desc)๋ฅผ ์„ค์ •ํ•œ๋‹ค.

D3D๋Š” Depth Stencil Buffer๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๊นŠ์ด ์Šคํ…์‹ค ๋ทฐ๋ฅผ ๋งŒ๋“ค์–ด D3D๊ฐ€ ๊นŠ์ด ๋ฐ ์Šคํ…์‹ค ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค!


1
2
    // ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ์™€ ๊นŠ์ด ์Šคํ…์‹ค ๋ฒ„ํผ๋ฅผ Output Merger ํŒŒ์ดํ”„๋ผ์ธ์— ๋ฐ”์ธ๋”ฉ
    m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);

Depth Stencil View๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์œผ๋ฏ€๋กœ, OMSetRenderTargets๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ์™€ ๊นŠ์ด-์Šคํ…์‹ค ๋ฒ„ํผ๋ฅผ ์ถœ๋ ฅ ๋ Œ๋” ํŒŒ์ดํ”„๋ผ์ธ์— ๋ฐ”์ธ๋”ฉ
  • ํŒŒ์ดํ”„๋ผ์ธ์ด ๋ Œ๋”๋งํ•œ ๊ทธ๋ž˜ํ”ฝ์ด ์ด์ „์— ์ƒ์„ฑํ•œ ๋ฐฑ ๋ฒ„ํผ์— ๊ทธ๋ ค์ง
  • ๊ทธ๋ž˜ํ”ฝ์ด ๋ฐฑ ๋ฒ„ํผ์— ๊ธฐ๋ก๋˜๋ฉด ํ”„๋ก ํŠธ ๋ฒ„ํผ๋กœ ์Šค์™‘ => ์‚ฌ์šฉ์ž ํ™”๋ฉด์— ๊ทธ๋ž˜ํ”ฝ ์ถœ๋ ฅ!


๐ŸŒฑ ํ๋ฆ„ ์ดํ•ดํ•ด๋ณด์ž!

  1. D3D11_DEPTH_STENCIL_DESC ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ๊นŠ์ด/์Šคํ…์‹ค ํ…Œ์ŠคํŠธ ์„ค์ •

    • ๊นŠ์ด ๋น„๊ต ํ•จ์ˆ˜, ์Šคํ…์‹ค ์—ฐ์‚ฐ ๋“ฑ ์ •์˜
  2. ์ƒ์„ฑํ•œ D3D11DepthStencilState ๊ฐ์ฒด๋ฅผ OM stage์— ์„ค์ • -> ํ…Œ์ŠคํŠธ ๊ทœ์น™์ด ํ™œ์„ฑํ™”๋จ

    • ๊ฐ์ฒด ์ƒ์„ฑ: Device->CreateDepthStencilState()
    • ๊ทœ์น™ ์ ์šฉ:DeviceContext->OMSetDepthStencilState()
  3. D3D11_DEPTH_STENCIL_VIEW_DESC๋ฅผ ์„ค์ •ํ•ด ๊นŠ์ด/์Šคํ…์‹ค ๋ฒ„ํผ ๋ทฐ ์ •์˜

    • ํ…์Šค์ฒ˜(๊นŠ์ด-์Šคํ…์‹ค ๋ฒ„ํผ)์˜ ํŠน์ • ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
  4. ID3D11DepthStencilView ๊ฐ์ฒด๋ฅผ OM stage์— ์—ฐ๊ฒฐํ•ด ํ…์Šค์ฒ˜ ํ™œ์šฉ(์•ž์„œ ์ ์šฉํ•œ ํ…Œ์ŠคํŠธ ๊ทœ์น™์ด ์ˆ˜ํ–‰๋จ)

    • ๊ฐ์ฒด ์ƒ์„ฑ: device->CreateDepthStencilView()

    • ๊นŠ์ด/์Šคํ…์‹ค ๋ทฐ, ๋ Œ๋” ํƒ€๊ฒŸ ๋ทฐ ์ ์šฉ: deviceContext->OMSetRenderTargets()



Rasterizer State

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    // Raster Desc์„ ์„ค์ •ํ•ด ํด๋ฆฌ๊ณค์ด ์–ด๋–ป๊ฒŒ ๊ทธ๋ ค์งˆ์ง€ ๊ฒฐ์ •
    rasterDesc.AntialiasedLineEnable = false;
    rasterDesc.CullMode = D3D11_CULL_BACK;
    rasterDesc.DepthBias = 0;
    rasterDesc.DepthBiasClamp = 0.0f;
    rasterDesc.DepthClipEnable = true;
    rasterDesc.FillMode = D3D11_FILL_SOLID;
    rasterDesc.FrontCounterClockwise = false;
    rasterDesc.MultisampleEnable = false;
    rasterDesc.ScissorEnable = false;
    rasterDesc.SlopeScaledDepthBias = 0.0f;

    // desc๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Rasterizer state ์ƒ์„ฑ
    result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);
    if (FAILED(result))
    {
        return false;
    }

    // Rasterizer ์ƒํƒœ ์„ค์ •
    m_deviceContext->RSSetState(m_rasterState);

๋ Œ๋” ํƒ€๊ฒŸ์ด ์„ค์ •๋˜์—ˆ์œผ๋ฏ€๋กœ, ์”ฌ์„ ๋”์šฑ ์ปจํŠธ๋กค ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ž˜์Šคํ„ฐ๋ผ์ด์ € ์ƒํƒœ(Rasterizer State) ์ƒ์„ฑ
    • ํด๋ฆฌ๊ณค์ด ๋ Œ๋”๋ง๋˜๋Š” ๋ฐฉ์‹ ์ œ์–ด
    • e.g. ์”ฌ์„ ์™€์ด์–ดํ”„๋ ˆ์ž„ ๋ชจ๋“œ๋กœ ๋ Œ๋”๋ง, DirectX๊ฐ€ ํด๋ฆฌ๊ณค์˜ ์•ž๋ฉด๊ณผ ๋’ท๋ฉด์„ ๋ชจ๋‘ ๊ทธ๋ฆฌ๊ธฐ
    • ๊ธฐ๋ณธ์ ์œผ๋กœ DirectX๋Š” ์ผ๋ฐ˜์ ์ธ ๋ž˜์Šคํ„ฐ๋ผ์ด์ € ์ƒํƒœ๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์Œ
      • ๋‹จ, ์ง์ ‘ ๋ž˜์Šคํ„ฐ๋ผ์ด์ € ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ œ์–ดํ•  ์ˆ˜ ์—†๋‹ค



Viewport ์„ค์ •

1
2
3
4
5
6
7
8
9
10
	// ๋ Œ๋”๋ง์„ ์œ„ํ•ด ๋ทฐํฌํŠธ ์„ค์ •
	m_viewport.Width = (float)screenWidth;
	m_viewport.Height = (float)screenHeight;
	m_viewport.MinDepth = 0.0f;
	m_viewport.MaxDepth = 1.0f;
	m_viewport.TopLeftX = 0.0f;
	m_viewport.TopLeftY = 0.0f;

	// ๋ทฐํฌํŠธ ์ƒ์„ฑ
	m_deviceContext->RSSetViewports(1, &m_viewport);

๋ทฐํฌํŠธ(Viewport) ์„ค์ •

  • Direct3D๊ฐ€ ํด๋ฆฝ ๊ณต๊ฐ„ ์ขŒํ‘œ๋ฅผ ๋ Œ๋” ํƒ€๊ฒŸ ๊ณต๊ฐ„์— ๋งคํ•‘ ๊ฐ€๋Šฅ
  • ๋ทฐํฌํŠธ ํฌ๊ธฐ๋ฅผ ์ฐฝ ์ „์ฒด๋กœ ์„ค์ •



ํ–‰๋ ฌ ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    // ํˆฌ์˜ ํ–‰๋ ฌ ์„ค์ •
    fieldOfView = 3.141592654f / 4.0f;
    screenAspect = (float)screenWidth / (float)screenHeight;

    // 3D ๋ Œ๋”๋ง์„ ์œ„ํ•ด ํˆฌ์˜ ํ–‰๋ ฌ ์ƒ์„ฑ (projection matrix)
    m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth);

    // ์›”๋“œ ํ–‰๋ ฌ ์ƒ์„ฑ (world matrix)
    m_worldMatrix = XMMatrixIdentity();

    // 2D ๋ Œ๋”๋ง์„ ์œ„ํ•ด ์ง๊ต ํˆฌ์˜ ํ–‰๋ ฌ ์ƒ์„ฑ (orthographic projection matrix)
    m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth);


	return true;
}

ํˆฌ์˜ ํ–‰๋ ฌ (projection matrix)

  • 3D ์”ฌ์„ 2D ๋ทฐํฌํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

  • ํ–‰๋ ฌ ์‚ฌ๋ณธ ์œ ์ง€(m_projectionMatrix)

    => ๋ Œ๋”๋งํ•  ์”ฌ์„ ์…ฐ์ด๋”๋กœ ์ „๋‹ฌํ•  ๋•Œ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ!

XMMatrixPerspectiveFovLH: ์™ผ์† ์ขŒํ‘œ๊ณ„์—์„œ ์›๊ทผ ํˆฌ์˜ ํ–‰๋ ฌ ์ƒ์„ฑ(perspective projection matrix)

  • ์›๊ทผ๊ฐ ์œ ์ง€ => ๊ฐ€๊นŒ์šด ๊ฐ์ฒด๋ฅผ ํฌ๊ฒŒ, ๋จผ ๊ฐ์ฒด๋ฅผ ์ž‘๊ฒŒ ๋ณด์ด๊ฒŒ ํ•จ


์›”๋“œ ํ–‰๋ ฌ (world matrix)

  • ๊ฐ์ฒด์˜ ์ •์ ์„ 3D ์”ฌ์—์„œ์˜ ์ •์ ์œผ๋กœ ๋ณ€ํ™˜ํ•จ
    • 3D ๊ณต๊ฐ„์—์„œ ๊ฐ์ฒด๋ฅผ ํšŒ์ „, ์ด๋™, ํฌ๊ธฐ ์กฐ์ •ํ•˜๋Š” ๋ฐ์—๋„ ์‚ฌ์šฉ๋œ๋‹ค!
  • ์ดˆ๊ธฐ ๋‹จ๊ณ„์—์„œ๋Š” ๋‹จ์œ„ ํ–‰๋ ฌ๋กœ ์„ค์ •
  • ๋ Œ๋”๋ง์„ ์œ„ํ•ด ์…ฐ์ด๋”์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ๋ณธ ์œ ์ง€(m_worldMatrix)


๋ทฐ ํ–‰๋ ฌ (View matrix)

  • ์”ฌ์„ ์–ด๋–ค ์œ„์น˜์—์„œ ๋ฐ”๋ผ๋ณผ์ง€ ๊ณ„์‚ฐ(์นด๋ฉ”๋ผ ์—ญํ• )
  • ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Initialize ํ•จ์ˆ˜์—์„œ ์ƒ์„ฑํ•˜๋‚˜, ์นด๋ฉ”๋ผ ํด๋ž˜์Šค์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์ด ์‹ค์ œ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์— ์šฉ์ดํ•จ! (ํŠนํžˆ ์นด๋ฉ”๋ผ ์ด๋™, ํšŒ์ „ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ)


์ง๊ต ํˆฌ์˜ ํ–‰๋ ฌ (orthographic projection matrix)

  • 2D UI ์š”์†Œ๋ฅผ ํ™”๋ฉด์— ๋ Œ๋”๋งํ•  ๋•Œ ์‚ฌ์šฉ
    • 3D ๋ Œ๋”๋ง์„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  2D ๊ทธ๋ž˜ํ”ฝ์„ ์ง์ ‘ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋‹ค!
  • 2D ๊ทธ๋ž˜ํ”ฝ ๋ฐ ํฐํŠธ ๋ Œ๋”๋ง์„ ๋‹ค๋ฃฐ ๋•Œ ์‚ฌ์šฉ๋จ



Shutdown()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void D3DClass::Shutdown()
{
	// D3D ์ข…๋ฃŒ ์ „์— ์œˆ๋„์šฐ ๋ชจ๋“œ๋กœ ๋ณ€๊ฒฝ(์˜ˆ์™ธ ๋ฐฉ์ง€)
	if (m_swapChain)
	{
		m_swapChain->SetFullscreenState(false, NULL);
	}

	if (m_rasterState)
	{
		m_rasterState->Release();
		m_rasterState = 0;
	}

	if (m_depthStencilView)
	{
		m_depthStencilView->Release();
		m_depthStencilView = 0;
	}

	if (m_depthStencilState)
	{
		m_depthStencilState->Release();
		m_depthStencilState = 0;
	}

	if (m_depthStencilBuffer)
	{
		m_depthStencilBuffer->Release();
		m_depthStencilBuffer = 0;
	}

	if (m_renderTargetView)
	{
		m_renderTargetView->Release();
		m_renderTargetView = 0;
	}

	if (m_deviceContext)
	{
		m_deviceContext->Release();
		m_deviceContext = 0;
	}

	if (m_device)
	{
		m_device->Release();
		m_device = 0;
	}

	if (m_swapChain)
	{
		m_swapChain->Release();
		m_swapChain = 0;
	}

	return;
}

D3DClass::Shutdown()

  • Initialize ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋œ ํฌ์ธํ„ฐ ํ•ด์ œ ๋ฐ ์ •๋ฆฌ
    1. D3D ๊ฐ์ฒด๋งˆ๋‹ค Release() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด ํ•ด์ œ
    2. ํฌ์ธํ„ฐ๋ฅผ 0 (nullptr)์œผ๋กœ ์„ค์ •
  • ์ฃผ์˜ํ•  ์ 
    • ์Šค์™‘ ์ฒด์ธ์€ ํ•ด์ œํ•˜๊ธฐ ์ „์— ์œˆ๋„์šฐ ๋ชจ๋“œ๋กœ ์ „ํ™˜ํ•  ๊ฒƒ! (SetFullscreenState(false, NULL))
    • ํ’€ ์Šคํฌ๋ฆฐ ์ƒํƒœ์—์„œ ์Šค์™‘ ์ฒด์ธ์„ ํ•ด์ œํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ


๐ŸŒฑ ํ’€ ์Šคํฌ๋ฆฐ์—์„œ ์Šค์™‘ ์ฒด์ธ์„ ํ•ด์ œํ•˜๋ฉด ์–ด๋–ค ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ• ๊นŒ?

  • Windowed VS Full Screen

    • Windowed: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์šด์˜ ์ฒด์ œ๊ฐ€ ๋””์Šคํ”Œ๋ ˆ์ด ๊ณต์œ 
    • Full Screen: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์œˆ๋„์šฐ๋ฅผ ๋ชจ๋‘ ์ฐจ์ง€ํ•จ => ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ OS์˜ UI๊ฐ€ ์ ‘๊ทผx
  • ์ „์ฒดํ™”๋ฉด์€ D3D๊ฐ€ ์ง์ ‘ ๋””์Šคํ”Œ๋ ˆ์ด ์ œ์–ด

    • ๋ฐ”๋กœ ์Šค์™‘ ์ฒด์ธ์„ ํ•ด์ œํ•˜๋ฉด ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ ์ถฉ๋Œ ๋ฐœ์ƒ
  • ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ ์ถฉ๋Œ

    • e.g.1) OS ์ถฉ๋Œ: D3D๊ฐ€ ์ „์ฒดํ™”๋ฉด์—์„œ ํ•ด์ƒ๋„ ๋“ฑ์„ ๋ณ€๊ฒฝํ•œ ํ›„, OS๊ฐ€ ์›๋ž˜ ๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ •์œผ๋กœ ๋ณต์›ํ•˜์ง€ ๋ชปํ•จ
    • e.g.2) ํ”„๋กœ๊ทธ๋žจ ๊ฐ•์ œ ์ข…๋ฃŒ: D3D๊ฐ€ ๋””์Šคํ”Œ๋ ˆ์ด๋ฅผ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ์–ด, ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด ๋””์Šคํ”Œ๋ ˆ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ์Œ
  • SetFullscreenState(false, NULL)

    • ์ „์ฒดํ™”๋ฉด์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ํ•ด์ƒ๋„์™€ ์ฃผ์‚ฌ์œจ ๋ณต์›
    • D3D ๋…์  ํ•ด์ œ => OS์™€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด ๋””์Šคํ”Œ๋ ˆ์ด ์ ‘๊ทผ


๐Ÿ“– ์ฐธ๊ณ 

Microsoft Learn - DXGI flip model

  • ํ’€์Šคํฌ๋ฆฐ ๋ชจ๋“œ -> WindowManager๊ฐ€ ๊ด€๋ฆฌ X, DXGI๊ฐ€ ์ง์ ‘ ๋””์Šคํ”Œ๋ ˆ์ด์™€ ํ†ต์‹ 
    • ํ”„๋ ˆ์ž„ ๋ฒ„ํผ ์ถœ๋ ฅ ๋ฐ VSync ์„ค์ •์„ DXGI๊ฐ€ ์ฒ˜๋ฆฌ

Microsoft Learn - IDXGISwapChain::SetFullscreenState method (dxgi.h)

  • ๋””์Šคํ”Œ๋ ˆ์ด ๋ชจ๋“œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก SetFullscreenState(FALSE, NULL); ํ˜ธ์ถœ
    • ์ „์ฒดํ™”๋ฉด => ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋””์Šคํ”Œ๋ ˆ์ด์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ• ์„ ๋…์ ์œผ๋กœ ๊ฐ€์ง
  • DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
    • OS์—์„œ ํ’€์Šคํฌ๋ฆฐ๋ชจ๋“œ๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ๊ณผ ์ถฉ๋Œ
  • DXGI_STATUS_MODE_CHANGE_IN_PROGRESS
    • ์Šค์™‘์ฒด์ธ์„ ํ•ด์ œํ•˜์ง€ ์•Š๊ณ  ์ฐฝ-์ „์ฒดํ™”๋ฉด์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ



BeginScene, EndScene

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void D3DClass::BeginScene(float red, float green, float blue, float alpha)
{
	float color[4];

	// ๋ฐฑ ๋ฒ„ํผ๋ฅผ ์ง€์šธ ์ƒ‰์ƒ ์„ค์ •
	color[0] = red;
	color[1] = green;
	color[2] = blue;
	color[3] = alpha;

	// ๋ฐฑ ๋ฒ„ํผ ์ •๋ฆฌ
	m_deviceContext->ClearRenderTargetView(m_renderTargetView, color);

	// ๊นŠ์ด ๋ฒ„ํผ ์ •๋ฆฌ
	m_deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);

	return;
}

D3DClass::BeginScene

  • ํ”„๋ ˆ์ž„์˜ ์‹œ์ž‘์—์„œ, ์ƒˆ 3D๋ฅผ ๊ทธ๋ฆด ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ
  • ๋ฒ„ํผ๋ฅผ ์ดˆ๊ธฐํ™”์‹œ์ผœ ์ƒˆ ํ”„๋ ˆ์ž„์— ๊ทธ๋ฆฌ๊ธฐ ์ค€๋น„


1
2
3
4
5
6
7
8
9
10
11
12
13
14
void D3DClass::EndScene()
{
	// ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฏ€๋กœ, ๋ฐฑ ๋ฒ„ํผ๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅ
	if (m_vsync_enabled)
	{
		// ์ฃผ์‚ฌ์œจ์— ๋งž๊ฒŒ ์ถœ๋ ฅ
		m_swapChain->Present(1, 0);
	}
	else
	{
		// ์ตœ๋Œ€ํ•œ ๋น ๋ฅด๊ฒŒ ์ถœ๋ ฅ (VSync ๋น„ํ™œ์„ฑํ™”)
		m_swapChain->Present(0, 0);
	}
}

D3DClass::EndScene

  • ํ”„๋ ˆ์ž„ ์ž‘์—… ๋งˆ์ง€๋ง‰์— ํ˜ธ์ถœ(๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋œ ์ดํ›„)
    • ๋ฐฑ ๋ฒ„ํผ๋ฅผ ํ”„๋ก ํŠธ ๋ฒ„ํผ๋กœ ์Šค์™‘ํ•˜๋Š” ์—ญํ• !
  • ๊ทธ๋ฆฌ๊ธฐ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์Šค์™‘ ์ฒด์ธ์— 3D ์”ฌ์„ ์ถœ๋ ฅํ•˜๋ผ๊ณ  ๋ช…๋ น
  • m_vsync_enabled: ์ฃผ์‚ฌ์œจ ๋™๊ธฐํ™” ์—ฌ๋ถ€
    • true: ๋ชจ๋‹ˆํ„ฐ ์ฃผ์‚ฌ์œจ์— ๋งž๊ฒŒ ํ”„๋ ˆ์ž„ ์ถœ๋ ฅ
    • false ์ฃผ์‚ฌ์œจ์„ ๋ฌด์‹œํ•˜๊ณ  ์ตœ๋Œ€ํ•œ ๋น ๋ฅด๊ฒŒ ํ”„๋ ˆ์ž„ ์ถœ๋ ฅ



Device/Context getter

1
2
3
4
5
6
7
8
9
ID3D11Device* D3DClass::GetDevice()
{
	return m_device;
}

ID3D11DeviceContext* D3DClass::GetDeviceContext()
{
	return m_deviceContext;
}

Direct3D Device์™€ Device Context์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์œ„ ํ—ฌํผ ํ•จ์ˆ˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ž์ฃผ ํ˜ธ์ถœ๋œ๋‹ค.



ํ–‰๋ ฌ ๊ด€๋ จ getter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void D3DClass::GetProjectionMatrix(XMMATRIX& projectionMatrix)
{
	projectionMatrix = m_projectionMatrix;
	return;
}

void D3DClass::GetWorldMatrix(XMMATRIX& worldMatrix)
{
	worldMatrix = m_worldMatrix;
	return;
}

void D3DClass::GetOrthoMatrix(XMMATRIX& orthoMatrix)
{
	orthoMatrix = m_orthoMatrix;
	return;
}

๊ฐ ํ–‰๋ ฌ์˜ ์‚ฌ๋ณธ์„ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ๋Œ€๋ถ€๋ถ„์˜ ์…ฐ์ด๋”๊ฐ€ ๋ Œ๋”๋ง์„ ํ•˜๊ธฐ ์œ„ํ•ด ํ–‰๋ ฌ์ด ํ•„์š”
    • ์™ธ๋ถ€ ๊ฐ์ฒด๊ฐ€ ํ–‰๋ ฌ์˜ ์‚ฌ๋ณธ์„ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก getter ์ œ๊ณต

(ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์œ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์ง€๋งŒ, ์ฝ”๋“œ์— ์™œ ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š”์ง€ ์„ค๋ช…ํ–ˆ๋‹ค!)


๐ŸŒฑ ํ–‰๋ ฌ getter๊ฐ€ ์“ฐ์ด๋Š” ๋ถ€๋ถ„

  • GetProjectionMatrix: ์…ฐ์ด๋”์—์„œ ์›๊ทผ ํˆฌ์˜ ๋ Œ๋”๋ง์— ์‚ฌ์šฉ

  • GetWorldMatrix: ๋ชจ๋ธ ์ขŒํ‘œ๊ณ„๋ฅผ์„ ์›”๋“œ ์ขŒํ‘œ๊ณ„๋กœ ๋งคํ•‘ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ (Model Space -> World Space)
  • GetOrthoMatrix: 2D ๋ Œ๋”๋ง์— ํ•„์š”ํ•œ ํ–‰๋ ฌ



๋น„๋””์˜ค์นด๋“œ ์ •๋ณด getter

1
2
3
4
5
6
void D3DClass::GetVideoCardInfo(char* cardName, int& memory)
{
	strcpy_s(cardName, 128, m_videoCardDescription);
	memory = m_videoCardMemory;
	return;
}
  • ๋น„๋””์˜ค ์นด๋“œ ์ด๋ฆ„, ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ์ฐธ์กฐ๋กœ ๋ฐ˜ํ™˜
  • ๋น„๋””์˜ค ์นด๋“œ ์ด๋ฆ„์€ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ ๋””๋ฒ„๊น…ํ•  ๋•Œ ๋„์›€์„ ์คŒ


๐ŸŒฑ ๋น„๋””์˜ค ์นด๋“œ ์ •๋ณด๊ฐ€ ์–ด๋””์— ์“ฐ์ผ๊นŒ?

  • cardName์— m_videoCardDescription ๋‚ด์šฉ ์ €์žฅ
    • strcpy_s ์‚ฌ์šฉ: ์•ˆ์ „ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ!
      • ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€ => ๋ฒ„ํผ ํฌ๊ธฐ(128byte)๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ
  • ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ? ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ์˜ ์ด๋ฆ„์„ ์•Œ๋ฉด ์—ฌ๋Ÿฌ GPU ํ™˜๊ฒฝ์—์„œ ๊ฐ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค!



๋ฒ„ํผ ๋ฐ ๋ทฐํฌํŠธ ์„ค์ •

1
2
3
4
5
6
7
8
9
10
11
12
13
void D3DClass::SetBackBufferRenderTarget()
{
	// ๋ Œ๋” ํƒ€์ผ“ ๋ทฐ์™€ ์Šคํ…์‹ค ๋ฒ„ํผ๋ฅผ ์ถœ๋ ฅ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์— ๋ฐ”์ธ๋”ฉ
	m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);

	return;
}

void D3DClass::ResetViewport()
{
	// ๋ทฐํฌํŠธ ์„ค์ •
	m_deviceContext->RSSetViewports(1, &m_viewport);
}

์ถ”ํ›„ Render To Texture์—์„œ ์‚ฌ์šฉ๋  ํ—ฌํผ ํ•จ์ˆ˜.


๐ŸŒฑ ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜ ์“ฐ์ž„

OMSetRenderTargets

  • ๋ Œ๋” ํƒ€์ผ“ ๋ทฐ์™€ ์Šคํ…์‹ค ๋ฒ„ํผ๋ฅผ OM Stage์— ๋ฐ”์ธ๋”ฉ
  • ๋ฐฑ ๋ฒ„ํผ๋ฅผ ๊ธฐ๋ณธ ๋ Œ๋” ํƒ€๊ฒŸ์œผ๋กœ ์„ค์ •
    • ์ตœ๋Œ€ 8๊ฐœ์˜ ๋ Œ๋” ํƒ€๊ฒŸ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ (PS๊ฐ€ ๋™์‹œ์— ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ)
      • ์—ฌ๊ธฐ์„œ ์ค‘๋ณต ์„ค์ • ๋ฐฉ์ง€, ํฌ๊ธฐ์™€ ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ฒŒ ํ•จ
    • OMSetRenderTargets(0, nullptr, nullptr);๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ชจ๋“  ๋ฐ”์ธ๋”ฉํ•ด์ œ


RSSetViewports

  • ๋ทฐํฌํŠธ๋ฅผ RS Stage์— ๋ฐ”์ธ๋”ฉ
  • ๋ชจ๋“  ๋ทฐํฌํŠธ๋Š” ์›์ž์„ฑ ์œ ์ง€ => ํ˜ธ์ถœ๋˜์ง€ ์•Š์€ ๋ทฐํฌํŠธ๋Š” ์‚ฌ์šฉx
  • ์‚ฌ์šฉํ•  ๋ทฐํฌํŠธ๋Š” ๊ธฐํ•˜ ๋„ํ˜• ์„ธ์ด๋”์— ์˜ํ•ด ๊ฒฐ์ •๋จ
    • ์–˜๊ฐ€ ๋”ฐ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด D3D๋Š” ์ฒซ ๋ฒˆ์งธ ๋ทฐํฌํŠธ ์‚ฌ์šฉ



Summary

  • D3D๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด D3D๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ  ์œˆ๋„์šฐ๊ฐ€ ํšŒ์ƒ‰์œผ๋กœ ์ฑ„์›Œ์ง„๋‹ค

Image



To Do Exercises

  1. ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•ด DirectX๊ฐ€ ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธ
    • ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฉด ์ฒ˜์Œ ํŠœํ† ๋ฆฌ์–ผ์„ ์ฐธ๊ณ ํ•ด ๋””๋ฒ„๊น…
    • ์ฐฝ์ด ํ‘œ์‹œ๋˜๋ฉด ESCํ‚ค๋ฅผ ๋ˆŒ๋Ÿฌ ์ข…๋ฃŒ
  2. applicationclass.h์˜ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์ „์ฒดํ™”๋ฉด์œผ๋กœ ๋ณ€๊ฒฝ
  3. ApplicationClass::Render์˜ clear color๋ฅผ ๋…ธ๋ž€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ
  4. ๋น„๋””์˜ค ์นด๋“œ ์ด๋ฆ„์„ ํ…์ŠคํŠธ ํŒŒ์ผ๋กœ ์ €์žฅ
This post is licensed under CC BY 4.0 by the author.

ยฉ yejin. Some rights reserved.