๐Ÿ“˜ Direct3D Tutorial2

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

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

Tutorial2 : ์‚ผ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ


๐Ÿ“Œ Elements of a Triangle (์‚ผ๊ฐํ˜•์˜ ์š”์†Œ)

GPU๊ฐ€ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์‚ผ๊ฐํ˜•์˜ ๊ผญ์ง“์  ์œ„์น˜ 3๊ฐœ๊ฐ€ ์ฃผ์–ด์ ธ์•ผ ํ•œ๋‹ค.

์ •์  ๋ฒ„ํผ์— ๊ผญ์ง“์  3๊ฐœ๋ฅผ ์ €์žฅํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ ์ •์ ์„ ๋ฒ„ํผ์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡ ๋ฐ”์ดํŠธ๊ฐ€ ํ•„์š”ํ•œ์ง€ ์•Œ์•„๋ณด์ž. ๋จผ์ € ์ •์  ๋ ˆ์ด์•„์›ƒ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.


๐Ÿ“Œ Input Layout

์ •์ ์€ ์œ„์น˜, ๋…ธ๋ฉ€, ์ƒ‰์ƒ, ํ…์Šค์ฒ˜ ์ขŒํ‘œ(ํ…์Šค์ฒ˜ ๋งคํ•‘์— ์ด์šฉ) ๋“ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ •์  ๋ ˆ์ด์•„์›ƒ์€ ์ด๋Ÿฌํ•œ ์†์„ฑ๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ์— ์–ด๋–ป๊ฒŒ ์œ„์น˜ํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. (๊ฐ ์†์„ฑ๋“ค์ด ์–ด๋–ค ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ด์šฉํ•˜๋Š”์ง€, ๊ฐ ์†์„ฑ์˜ ์‚ฌ์ด์ฆˆ๋Š” ์–ผ๋งˆ์ธ์ง€, ์ €์žฅ๋œ ์ˆœ์„œ ๋“ฑ)

๊ฐ ์†์„ฑ์€ ๋‹ค๋ฅธ ํƒ€์ž…์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ •์ ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌ์กฐ์ฒด๋กœ ํ‘œํ˜„ํ•œ๋‹ค. ์ •์ ์˜ ์‚ฌ์ด์ฆˆ๋Š” ๊ตฌ์กฐ์ฒด์˜ ์‚ฌ์ด์ฆˆ๋กœ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ๊ผญ์ง“์ ์˜ ์œ„์น˜์— ๋Œ€ํ•ด์„œ๋งŒ ์„ค๋ช…ํ•œ๋‹ค.
๋”ฐ๋ผ์„œ XMFLOAT3 ํƒ€์ž…๋งŒ ์ด์šฉํ•˜์—ฌ ์ •์  ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•œ๋‹ค. XMFLOAT3๋Š” float 3๊ฐœ์˜ ๋ฒกํ„ฐ์ด๋‹ค.

struct SimpleVertex
{
	XMFLOAT3 Pos; // Position
};

์ด๊ฑธ GPU์— ๊ณต๊ธ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” input layout์„ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. (GPU๋Š” ์ด๊ฒŒ ์ •์ ์— ๋Œ€ํ•œ ์ •๋ณด๋ผ๋Š”๊ฑธ ๋ชจ๋ฅธ๋‹ค)

Direct3D 11์—์„œ input layout์€ GPU๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ์ •์  ๊ตฌ์กฐ์ฒด๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฐ์ฒด์ด๋‹ค. ๊ฐ ์ •์  ์†์„ฑ๋“ค์€ D3D11_INPUT_ELEMENT_DESC ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ค๋ช…๋  ์ˆ˜ ์žˆ๋‹ค.
์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ D3D11_INPUT_ELEMENT_DESC ๋ฐฐ์—ด์„ ํ•˜๋‚˜ ์ด์ƒ ์ •์˜ํ•œ ๋‹ค์Œ, ์ „์ฒด ์ •์ ์„ ์„œ์ˆ ํ•˜๋Š” input layout ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

D3D11_INPUT_ELEMENT_DESC์— ๋Œ€ํ•ด ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž.


๐Ÿ”Ž D3D11_INPUT_ELEMENT_DESC

  • SemanticName

: Semantic name์€ ์š”์†Œ์˜ ์„ฑ๊ฒฉ์ด๋‚˜ ๋ชฉ์ ์„ ์„ค๋ช…ํ•˜๋Š” ๋ฌธ์ž์—ด์ด๋‹ค. ์—ฌ๊ธฐ์„  POSITION์ด๋‹ค.

  • SemanticIndex

: ์ •์ ์€ ๋™์ผํ•œ ์„ฑ์งˆ์˜ ์—ฌ๋Ÿฌ ์†์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ƒ‰์ƒ์ด 2๊ฐœ ์ผ์ˆ˜๋„ ์žˆ๊ณ  ํ…์Šค์ฒ˜ ์ขŒํ‘œ๊ฐ€ 2๊ฐœ ์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ๋•Œ ๊ฐ™์€ COLOR ์ด๋ผ๋Š” Semantic name์„ ์“ฐ๋ฉด์„œ Semantic index๋ฅผ 0๊ณผ 1๋กœ ์„ค์ •ํ•ด์ค€๋‹ค.

  • Format

: ์š”์†Œ์— ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ •์˜ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด DXGI_FORMAT_R32G32B32_FLOAT์€ 3๊ฐœ์˜ 32๋น„ํŠธ float์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ์ด 12byte๊ฐ€ ๋œ๋‹ค.

  • InputSlot

: Direct3D 11์—์„œ GPU์— ์ตœ๋Œ€ 16๊ฐœ์˜ ์ •์  ๋ฒ„ํผ๊ฐ€ ๋™์‹œ์— ๊ณต๊ธ‰๋  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ์ •์  ๋ฒ„ํผ๋Š” 0๋ถ€ํ„ฐ 15๊นŒ์ง€์˜ ์ˆซ์ž๋ฅผ ๊ฐ€์ง„๋‹ค. InputSlot์ด ์ด ์ˆซ์ž๋ฅผ ์ด์šฉํ•ด์„œ ๋ญ˜ ๊ฐ€์ ธ์˜ฌ๊ฑด์ง€ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • AlignedByteOffset

: AlignedByteOffeset์€ GPU์— ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ ์ •์  ๋ฒ„ํผ๊ฐ€ ์‹œ์ž‘๋˜๋Š” ์œ„์น˜๋ฅผ ์•Œ๋ ค์ค€๋‹ค.

  • InputSlotClass

: ์—ฌ๊ธฐ์—” ์ผ๋ฐ˜์ ์œผ๋กœ D3D11_INPUT_PER_VERTEX_DATA๋ฅผ ์“ด๋‹ค.

  • InstanceDataStepRate

: ์ธ์Šคํ„ด์Šคํ™”์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ์‚ฌ์šฉํ•˜์ง€ 0์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

์ด์ œ input layout์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด D3D11_INPUT_ELEMENT_DESC ๋ฐฐ์—ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
};
UINT numElements = ARRAYSIZE(layout);

๐Ÿ“Œ Vertex Layout

vetex shader๋ž‘ vertex layout์ด ๋ฐ€์ ‘ํ•˜๊ฒŒ ์—ฐ๊ด€๋˜์–ด ์žˆ๋‹ค. vertex layout์„ ๋งŒ๋“ค๋ ค๋ฉด vertext shader์˜ input signature์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

D3DX11CompileFromFile์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” ID3DBlob ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •์  ์…ฐ์ด๋”์˜ input signature์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ์šฐ๋ฆฌ๋Š” ID3D11Device::CreateInputLayout()๋ฅผ ๋ถˆ๋Ÿฌ์„œ vertext layout ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ID3D11DeviceContext::IASetInputLayout()๋กœ ํ™œ์„ฑํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

// Create the input layout
if( FAILED( g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), 
        pVSBlob->GetBufferSize(), &g_pVertexLayout ) ) )
    return FALSE;
// Set the input layout
g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

๐Ÿ“Œ Creating Vertex Buffer

์ดˆ๊ธฐํ™”ํ• ๋™์•ˆ ํ•ด์•ผํ•  ์ผ ์ค‘ ํ•˜๋‚˜๋Š” ์ •์  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ ์ •์  ๋ฒ„ํผ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.
Direct3D 11์—์„œ ์ •์  ๋ฒ„ํผ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด D3D11_BUFFER_DESC, D3D11_SUBRESOURCE_DATA ๋‘๊ฐ€์ง€ ๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ID3D11Device::CreateBuffer()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

  • D3D11_BUFFER_DESC : ์ •์  ๋ฒ„ํผ ๊ฐ์ฒด๋ฅผ ์„œ์ˆ ํ•œ๋‹ค.
  • D3D11_SUBRESOURCE_DATA : ์ •์  ๋ฒ„ํผ์— ๋ณต์‚ฌ๋  ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ์ˆ ํ•œ๋‹ค.

์ •์  ๋ฒ„ํผ์— ๋ณต์‚ฌ๋  ๋ฐ์ดํ„ฐ๋Š” ์•„๋ž˜ ์ฝ”๋“œ์—์„œ SimpleVertex์— ์ €์žฅ๋œ 3๊ฐœ์˜ ์ •์ ๋“ค์ด๋‹ค.
์ •์  ๋ฒ„ํผ๊ฐ€ ์ƒ์„ฑ๋œ ํ›„ ID3D11DeviceContext::IASetVertexBuffers()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋””๋ฐ”์ด์Šค์— ๋ฐ”์ธ๋”ฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ”Ž vertex buffer ๋งŒ๋“ค๊ธฐ

// Create vertex buffer
SimpleVertex vertices[] =
{
    XMFLOAT3( 0.0f, 0.5f, 0.5f ),
    XMFLOAT3( 0.5f, -0.5f, 0.5f ),
    XMFLOAT3( -0.5f, -0.5f, 0.5f ),
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA InitData; 
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
if( FAILED( g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ) ) )
    return FALSE;

// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

๐Ÿ“Œ Primitive Topology

Primitive Topology ๋Š” GPU๊ฐ€ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ 3๊ฐœ์˜ ์ •์ ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ๋งํ•œ๋‹ค.

๋งŒ์•ฝ ์‚ผ๊ฐํ˜•์„ 2๊ฐœ ๊ทธ๋ฆฌ๊ณ  ์‹ถ๋‹ค๋ฉด GPU์— 6๊ฐœ์˜ ์ •์ ์„ ๋ณด๋‚ด๋ฉด ๋˜๊ณ  ์ด ๋•Œ topology๋ฅผ ์‚ผ๊ฐํ˜• ๋ฆฌ์ŠคํŠธ(triangle list)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์‚ผ๊ฐํ˜• ๋ฆฌ์ŠคํŠธ๋Š” ์ดํ•ด๊ฐ€ ์‰ฝ์ง€๋งŒ, ๋น„ํšจ์œจ์ ์ด๋‹ค. ์—ฌ๋Ÿฌ๊ฐœ์˜ ์‚ผ๊ฐํ˜•์ด ์ •์ ์„ ๊ณต์œ ํ•˜๋Š” ๊ฒฝ์šฐ ํ•œ ์ •์ ์ด ์—ฌ๋Ÿฌ๋ฒˆ ์ €์žฅ๋œ๋‹ค.

A B C C B D

์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์‚ผ๊ฐํ˜•์ด ๋‘๊ฐœ์˜ ๊ผญ์ง“์ ์„ ๊ณต์œ ํ•œ๋‹ค๋ฉด ๋จผ์ € ๊ทธ๋ ค์ง„ ์‚ผ๊ฐํ˜•์—์„œ ๋‘ ๊ฐœ์˜ ์ •์ ์„ ์‚ฌ์šฉํ•˜๊ณ  ์ •์  ๋ฒ„ํผ์—์„œ ํ•œ๊ฐœ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค๋ฉด ํ›จ์”ฌ ํšจ์œจ์ ์ผ ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ•  ๋•Œ topology๋Š” triangle strip์ด๋‹ค.
triangle strip์„ ์ด์šฉํ•˜๋ฉด ๋‘๋ฒˆ์งธ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆด ๋•Œ ์ด์ „ ์‚ผ๊ฐํ˜•์—์„œ ๋งˆ์ง€๋ง‰ ๋‘ ์ •์ ์„ ๊ฐ€์ ธ์˜ค๊ณ , ์ •์  ๋ฒ„ํผ์—์„œ ๊ทธ ๋‹ค์Œ ์ •์ ์„ ํ•˜๋‚˜ ๊ฐ€์ ธ์˜จ๋‹ค.

A B C D

์œ„ ๋„ํ˜•์˜ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์ „๋‹ฌ๋œ๋‹ค.

A B C D E

๋‘๋ฒˆ์งธ, ๋„ค๋ฒˆ์งธ, ์—ฌ์„ฏ๋ฒˆ์งธ ์‚ผ๊ฐํ˜• ๋“ฑ์€ ๋ฐ˜์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ์ •์ ์ด ์ฃผ์–ด์ง„๋‹ค.
(๊ธฐ๋ณธ์ ์œผ๋ก  ์‹œ๊ณ„)


๐Ÿ”Ž ์‚ผ๊ฐํ˜• ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ topology ์„ค์ •

// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

๐Ÿ“Œ Rendering the Triangle

์ด์ œ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•ด๋ณด์ž. ๋ Œ๋”๋ง์„ ์œ„ํ•ด ์ •์  ์…ฐ์ด๋”์™€ ํ”ฝ์…€ ์…ฐ์ด๋” ๋‘๊ฐœ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ์ •์  ์…ฐ์ด๋”๋Š” ์‚ผ๊ฐํ˜•์˜ ์ •์ ๋“ค์„ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ํ”ฝ์…€ ์…ฐ์ด๋”๋Š” ์‚ผ๊ฐํ˜•์˜ ๊ฐ ํ”ฝ์…€์˜ ์ƒ‰์ƒ์„ ๊ณ„์‚ฐํ•œ๋‹ค. (์ด๊ฑด ๋‹ค์Œ ํŠœํ† ๋ฆฌ์–ผ์—์„œ)

์ด๋Ÿฌํ•œ ์…ฐ์ด๋”๋“ค์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ฐ๊ฐ ID3D11DeviceContext::VSSetShader(), ID3D11DeviceContext::PSSetShader()์„ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ID3D11DeviceContext::Draw()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ˜„์žฌ ์ •์  ๋ฒ„ํผ, ์ •์  ๋ ˆ์ด์•„์›ƒ, primitive topology ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ GPU๊ฐ€ ๋ Œ๋”๋งํ•˜๋„๋ก ํ•˜๋ฉด ๋œ๋‹ค.

Draw()์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” GPU๋กœ ๋ณด๋‚ผ ์ •์  ์ˆ˜์ด๊ณ , ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋ณด๋‚ผ ์ฒซ๋ฒˆ์งธ ์ •์ ์˜ ์ธ๋ฑ์Šค์ด๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•˜๋‚˜์˜ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๊ณ  ์ •์  ๋ฒ„ํผ์˜ ์ฒ˜์Œ์—์„œ๋ถ€ํ„ฐ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ๊ฐ 3, 0 ์— ํ•ด๋‹นํ•œ๋‹ค.

// Render a triangle 
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->Draw( 3, 0 );

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ