๐Ÿ“˜ Direct3D Tutorial1

ํŒŒ์ธยท2022๋…„ 2์›” 5์ผ
0

Directx

๋ชฉ๋ก ๋ณด๊ธฐ
1/8
post-thumbnail

https://docs.microsoft.com/en-us/previous-versions//ff729718(v=vs.85)?redirectedfrom=MSDN

์œ„ ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๐Ÿ“Œ Setting Up The Direct3D 11 Device (Direct3D 11 ์žฅ์น˜ ์„ค์ •)


3D ์žฅ๋ฉด์„ ๋ Œ๋”๋งํ•  ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ํ•ด์•ผ ํ•  ์ผ์€ device, immediate context, swap chain ์„ธ ๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

(immediate context๋Š” direct3d 11์— ์ƒˆ๋กœ ๋“ฑ์žฅํ•œ ๊ฐ์ฒด์ž„)

1) ๋””๋ฐ”์ด์Šค(device) ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŒ๋“ ๋‹ค.

2) immediate context๋Š” ๋ฒ„ํผ์— ๋ Œ๋”๋ง์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

3) ์Šค์™‘ ์ฒด์ธ(swap chain) ์€ ์žฅ์น˜๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ๋ฒ„ํผ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์‹ค์ œ ๋ชจ๋‹ˆํ„ฐ ํ™”๋ฉด์— ์ฝ˜ํ…์ธ ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
์Šค์™‘ ์ฒด์ธ์—๋Š” ๋‘ ๊ฐœ ์ด์ƒ์˜ ๋ฒ„ํผ๊ฐ€ ์žˆ๋Š”๋ฐ, ๋ณดํ†ต ๋ฐฑ ๋ฒ„ํผ์™€ ํ”„๋ก ํŠธ ๋ฒ„ํผ๊ฐ€ ์žˆ๋‹ค. ํ”„๋ก ํŠธ ๋ฒ„ํผ๊ฐ€ ํ˜„์žฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณต๋˜๊ณ  ์žˆ๋Š” ๋ฒ„ํผ์ด๊ณ , ๋ฐฑ ๋ฒ„ํผ๋Š” ์•ž์œผ๋กœ ๊ทธ๋ ค์งˆ ํƒ€๊ฒŸ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค ๊ทธ๋ ค์ง€๊ณ  ๋‚˜๋ฉด ๋ฐฑ ๋ฒ„ํผ๊ฐ€ ํ”„๋ŸฐํŠธ ๋ฒ„ํผ๊ฐ€ ๋œ๋‹ค.

์Šค์™‘ ์ฒด์ธ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ƒ์„ฑํ•˜๋ ค๋Š” ์Šค์™‘ ์ฒด์ธ์„ ์„ค๋ช…ํ•˜๋Š” DXGI_SWAPCHAIN_DESC ๊ตฌ์กฐ์ฒด๋ฅผ ์ฒด์›Œ์•ผ ํ•œ๋‹ค.


๐Ÿ”Ž DXGI_SWAPCHAIN_DESC

BackBufferUsage : ๋ฐฑ ๋ฒ„ํผ๊ฐ€ ์–ด๋–ป๊ฒŒ ์“ธ๊ฑด์ง€.

๋ฐฑ ๋ฒ„ํผ๋กœ ๋ Œ๋”๋ง์„ ํ•ด์ฃผ๊ณ ์ž ํ•˜๋ฏ€๋กœ BackBufferUsage๋กœ DXGI_USAGE_RENDER_TARGET_OUTPUT ์œผ๋กœ ์„ค์ •ํ•ด์ฃผ์—ˆ๋‹ค.

OutputWindow : ์–ด๋–ค ์ฐฝ์— ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œํ•  ๊ฑด์ง€

์ด๋ ‡๊ฒŒ ์„ค์ •์ด ๋‹ค ์ฑ„์›Œ์ง€๊ณ  ๋‚˜๋ฉด ์•„๋ž˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

D3D11CreateDeviceAndSwapChain : ์žฅ์น˜์™€ ์Šค์™‘ ์ฒด์ธ์„ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜



๐Ÿ”Ž ๋””๋ฐ”์ด์Šค์™€ ์Šค์™‘ ์ฒด์ธ์„ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1; 
sd.BufferDesc.Width = 640;
sd.BufferDesc.Height = 480;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60; // 60ํ”„๋ ˆ์ž„
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // swap chain ๋ฐฑ ๋ฒ„ํผ ์šฉ๋„ - ๋ Œ๋”๋ง
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1; // 
sd.SampleDesc.Quality = 0; // ๋‹ค์ค‘ ์ƒ˜ํ”Œ๋ง์„ ์ด์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ
sd.Windowed = TRUE;

if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, numFeatureLevels,
    D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, NULL, &g_pImmediateContext))) 
{
    return FALSE;
}

๋‹ค์Œ์œผ๋กœ ํ•  ์ผ์€ ์Šค์™‘ ์ฒด์ธ์˜ ๋ฐฑ ๋ฒ„ํผ๋ฅผ render target์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•˜๊ธฐ์œ„ํ•ด render target view๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

render target view๋Š”
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=agebreak&logNo=60114584311
์— ์‰ฝ๊ฒŒ ์„ค๋ช…์ด ๋˜์–ด์žˆ๋‹ค.

๋จผ์ € ๋ฐฑ ๋ฒ„ํผ์˜ ๊ฐ์ฒด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด GetBuffer()์„ ํ˜ธ์ถœํ•œ๋‹ค.
์ด๋ฒˆ์—๋Š” ๊ธฐ๋ณธ render target view๋งŒ ์žˆ์œผ๋ฉด ๋˜๋ฏ€๋กœ CreateRenderTargetView์˜ ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” NULL์— ํ•ด๋‹นํ•œ๋‹ค.

render target view๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋ฉด immediate context์—์„œ OMSetRenderTargets()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํŒŒ์ดํ”„๋ผ์ธ์— ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋‹ค.
์ตœ์ข…์ ์œผ๋กœ ํŒŒ์ดํ”„๋ผ์ธ ๋ Œ๋”๋ง์˜ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ฐฑ ๋ฒ„ํผ์— ๊ธฐ๋ก๋œ๋‹ค.


๐Ÿ”Ž render target view๋ฅผ ๋งŒ๋“ค๊ณ  ์„ค์ •

// Create a render target view
ID3D11Texture2D* pBackBuffer;
if (FAILED(g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer)))
	return FALSE;
hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))
	return FALSE;
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);

๋งˆ์ง€๋ง‰์œผ๋กœ ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์€ ๋ทฐํฌํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
๋ทฐํฌํŠธ๋Š” clip space coordinate์ด๋‹ค. (X์™€ Y๋Š” -1~1, Z๋Š” 0~1)
์™ผ์ชฝ ์ƒ๋‹จ ์ ์„ (0, 0)์ด๋‹ค. ๋„ˆ๋น„ ๋ฐ ๋†’์ด๋Š” ๋ Œ๋” ๋Œ€์ƒ์˜ ํฌ๊ธฐ์™€ ๋™์ผํ•˜๊ฒŒ ์„ค์ •ํ•œ๋‹ค.


๐Ÿ”Ž viewport ์ดˆ๊ธฐํ™”

  D3D11_VIEWPORT vp;
  vp.Width = (FLOAT)width;
  vp.Height = (FLOAT)height;
  vp.MinDepth = 0.0f;
  vp.MaxDepth = 1.0f;
  vp.TopLeftX = 0;
  vp.TopLeftY = 0;
  g_pImmediateContext->RSSetViewports( 1, &vp );


๐Ÿ“Œ Modifying the Message Loop (๋ฉ”์„ธ์ง€ ๋ฃจํ”„ ์ˆ˜์ •ํ•˜๊ธฐ)


GetMessage()๋Š” ๋Œ€๊ธฐ์—ด์— ๋ฉ”์„ธ์ง€๊ฐ€ ์—†์œผ๋ฉด GetMessage()๊ฐ€ ์ฐจ๋‹จ๋˜์–ด ๋ฉ”์„ธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋Š”๋‹ค.
๋ฉ”์„ธ์ง€๊ฐ€ ์•ˆ๋“ค์–ด์˜ค๋”๋ผ๋„ ๊ทธ๋™์•ˆ ๋‹ค๋ฅธ ๊ฑธ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋ฏ€๋กœGetMessage()๋Œ€์‹  PeekMessage()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. PeekMessage()๋Š” ๋Œ€๊ธฐ์—ด์— ๋ฉ”์„ธ์ง€๊ฐ€ ์—†์–ด๋„ PeekMessage()๊ฐ€ ์ฆ‰์‹œ ๋ฐ˜ํ™˜๋˜์–ด ๋ Œ๋”๋ง์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ”Ž GetMessage() ๋Œ€์‹  PeekMessage() ์‚ฌ์šฉํ•˜๊ธฐ

    MSG msg = {0};
    while( WM_QUIT != msg.message )
    {
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            Render();  // Do some rendering
        }
    }


๐Ÿ“Œ The Rendering code (๋ Œ๋”๋ง ์ฝ”๋“œ)


๋ Œ๋”๋ง์€ Render() ํ•จ์ˆ˜์—์„œ ์™„๋ฃŒ๋œ๋‹ค.
์˜ˆ์‹œ์—์„œ๋Š” ๋‹จ์ผ ์ƒ‰์œผ๋กœ ํ™”๋ฉด์„ ์น ํ–ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ClearRanderTargetView() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค. ํ™”๋ฉด์„ ์ฑ„์šฐ๊ณ  ์‹ถ์€ ์ƒ‰์ƒ์„ ์„ค์ •ํ•œ๋‹ค์Œ ClearRenderTargetView()์— ์ „๋‹ฌํ•œ๋‹ค. ๋ฐฑ ๋ฒ„ํผ๋ฅผ ์ฑ„์šฐ๋ฉด ์Šค์™‘ ์ฒด์ธ์˜ Present() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ Œ๋”๋ง์„ ์™„๋ฃŒํ•œ๋‹ค.

Present() : ์Šค์™‘ ์ฒด์ธ์˜ ๋ฐฑ ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ์—ญํ• 


๐Ÿ”Ž ๋ Œ๋”๋ง


    void Render()
    {
        //
        // Clear the backbuffer
        //
        float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
        g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    
        g_pSwapChain->Present( 0, 0 );
    }
    
profile
๊ณต๋ถ€์ •๋ฆฌ์šฉ

0๊ฐœ์˜ ๋Œ“๊ธ€