https://docs.microsoft.com/en-us/previous-versions//ff729721(v=vs.85)?redirectedfrom=MSDN
μ λ΄μ©μ μ°Έκ³ νμ¬ μ 리ν λ΄μ©μ λλ€.
μ»΄ν¨ν° κ·Έλν½μ€μμλ 3D 곡κ°μ μ£Όλ‘ λ°μΉ΄λ₯΄νΈ μ’νκ³(Cartesian coordinate system)μμ κ°μ₯ ννλ€.
μ΄ μ’νκ³λ μΌμ μ’νκ³μ μ€λ₯Έμ μ’νκ³λ‘ λλλ€.
object spaceλ 3D λͺ¨λΈμ λ§λ€ λ μ¬μ©νλ 곡κ°μ λ§νλ€.
World Spaceλ μ¬μ λͺ¨λ μ¬λ¬Όμ΄ 곡μ νλ 곡κ°μ΄λ€. λ λλ§νλ €λ κ°μ²΄λ€μ μμΉλ₯Ό μ μνλ€.
View space(camera space)λ μ 체 μ¬μ΄ μ¬μ©λλ€λ μ μμ World spaceμ μ μ¬νλ€. κ·Έλ¬λ μμ μ΄ viewerλ cameraλ κ° λ€λ₯΄λ€. (World Spaceλ viewerμ μ’νκ° μμ , Camera Spaceμ camera μ’νκ° μμ )
ν¬μ 곡κ°μ λ·° μ€νμ΄μ€μμ ν¬μ λ³νμ μ μ©ν νμ 곡κ°μ λ§νλ€.
X, Yλ -1~1 μ΄κ³ , Zλ 0~1 μ΄λ€.
μ€ν¬λ¦° 곡κ°μ νλ μ λ²νΌμ μμΉλ₯Ό μ°Έμ‘°νλλ° μ¬μ©λλ€. νλ μ λ²νΌλ λ³΄ν΅ 2D ν
μ€μ²μ΄κΈ° λλ¬Έμ μ€ν¬λ¦° κ³΅κ° μμ 2D 곡κ°μ΄λ€.
μΌμͺ½ μλ¨ λͺ¨μλ¦¬κ° 0,0 μ΄λ€.
νμ΄νλΌμΈμ World, View, Projection transfrom 3κ°μ§ λ³νμ΄ μλ€.
μ μ μ κ°μ²΄ 곡κ°(Object Space)μμ μλ 곡κ°(World Space)λ‘ λ³ννλ€. ν¬κΈ° μ‘°μ , νμ , μ΄λ λ±μ΄ μλ€. μ¬μ 물체λ€μ κ°κ° κ³ μ ν μλ λ³ν νλ ¬μ κ°μ§λ€.
μ μ μ μλ 곡κ°μμ λ·° 곡κ°μΌλ‘ λ³ννλ€. λ·° λ³ν νλ ¬μ viewerλ μΉ΄λ©λΌκ° μλ μ μ μ μ μ©λλ€. μ¦ μΉ΄λ©λΌμ κ΄μ μμ μ μ μ μ΄λμν¨λ€.
XNA Mathμλ view matrixλ₯Ό κ³μ°νκΈ° μν΄ XMMatrixLookAtLH()λΌλ APIκ° μ’
μ’
μ¬μ©λλ€. μΉ΄λ©λΌκ° μ΄λμ μλμ§, μ΄λλ₯Ό λ³΄κ³ μλμ§, μ
λ²‘ν° λ±μ μλ €μ£Όλ©΄ μ΄μ μμνλ λ·° 맀νΈλ¦μ€λ₯Ό μ»μ μ μλ€.
ν¬μ λ³νμ μλ, λ·° 곡κ°κ³Ό κ°μ 3D 곡κ°μμ ν¬μ 곡κ°μΌλ‘ μ μ μ λ³ννλ€. ν¬μ 곡κ°μμ μ μ μ X, Y μ’νλ 3μ°¨μ 곡κ°μμ μ μ μ X/Z, Y/Z λΉμ¨μ μν΄ κ΅¬ν΄μ§λ€.
3D 곡κ°μ μ μνλ λ§€κ° λ³μ μ€ νλλ₯Ό FOV(Field-Of-View)λΌκ³ νλ€. FOVλ νΉμ λ°©ν₯μ λ°λΌλ³Ό λ νΉμ μμΉμμ μ΄λ€ λ¬Όμ²΄κ° λ³΄μ΄λμ§λ₯Ό λνλΈλ€.
μ»΄ν¨ν° κ·Έλν½μ€μμ FOVλ view frustumμ ν¬ν¨λμ΄ μλ€. view frustumμ 3Dμμ 6κ°μ νλ©΄μΌλ‘ μ μλλ€.
GPUλ view frustum λ°μ μλ κ°μ²΄λ λΊλ€. μ΄ κ³Όμ μ ν΄λ¦¬ν(clipping) μ΄λΌκ³ νλ€. ν΄λ¦¬ν κ²°κ³Ό view frustumμ μ‘면체(μμ)κ° λλ€.
Direct3D 11μμ ν¬μ νλ ¬μ μ»λ κ°μ₯ μ¬μ΄ λ°©λ²μ XMMatrixPerspectiveFovLH() λ©μλλ₯Ό νΈμΆνλ κ²μ΄λ€. 맀κ°λ³μλ FOVy, Aspect, Zn, Zf 4κ° μ΄λ€.
μμ νλμ μΌκ°νμ νλ©΄μ λ λλ§ ν λλ μ μ λ²νΌκ° λ°λ‘ ν¬μ 곡κ°μ μλλ‘ νκΈ° λλ¬Έμ λ³νμ ν νμκ° μμλ€.
μ΄μ μ μ λ²νΌκ° κ°μ²΄ 곡κ°μ μ μλλλ‘ ν νμ μ μ μ
°μ΄λλ₯Ό μμ νμ¬ μ μ μ κ°μ²΄ 곡κ°μμ ν¬μ 곡κ°μΌλ‘ λ³νν΄λ³΄μ.
π νλΈ
SimpleVertex vertices[] =
{
{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) },
};
μ΄ 8κ°μ μ μ ν΅ν΄ μ μ‘면체λ₯Ό νμ±νλ μΌκ°νμ μ§μ ν΄μΌ νλ€.
λ§μ μΌκ°νλ€μ κ°μ κΌμ§μ μ 곡μ ν κ²μ΄λ―λ‘ 8κ°μ μ λ§ μ§μ ν λ€μ Driect3Dκ° μΌκ°νμ λν΄ μ΄λ€ μ μ μ νν΄μΌ νλμ§ μλ €μ£Όλ λ°©λ²μ μμν κ²μ΄λ€. μ΄λ μΈλ±μ€ λ²νΌ(index buffer)λ₯Ό ν΅ν΄ μνλλ€. μΈλ±μ€ λ²νΌλ λ²νΌμ μ μ μΈλ±μ€λ₯Ό μ°Έμ‘°νμ¬ κ° μΌκ°νμμ μ¬μ©ν μ μ μ§μ νλ 리μ€νΈλ₯Ό ν¬ν¨νλ€.
μΈλ±μ€ λ²νΌλ μ μ λ²νΌμ λ§€μ° μ μ¬νλ€.
π index buffer
// Create index buffer
WORD indices[] =
{
3,1,0,
2,1,3,
0,5,4,
1,5,0,
3,4,7,
0,4,3,
1,6,5,
2,6,1,
2,7,6,
3,7,2,
6,4,5,
7,4,6,
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle list
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
InitData.pSysMem = indices;
if( FAILED( g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer ) ) )
return FALSE;
arrayλ₯Ό WORDλ₯Ό μ΄μ©νμ¬ μ μΈν΄μ£ΌμμΌλ―λ‘ sizeof(WORD)λ₯Ό μ΄μ©νμ¬ bdμ ByteWidthλ₯Ό μ§μ ν΄μ£Όμλ€.
Direct3Dκ° μΌκ°νμ μμ±ν λ μ΄ μΈλ±μ€ λ²νΌλ₯Ό μ°Έμ‘°νλλ‘ μ€μ ν΄μΌ νλ€.
// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
μ μ μ °μ΄λμμ κ°μ²΄μμ μλ 곡κ°μΌλ‘, μλμμ λ·° 곡κ°μΌλ‘, λ·° 곡κ°μμ ν¬μ곡κ°μΌλ‘ λ³νμ μ§νν΄μΌ νλ€.
κ°μ₯ λ¨Όμ ν μΌμ 3κ°μ μμ λ²νΌ(constant buffer) λ³μλ₯Ό μ μνλ κ²μ΄λ€. μμ λ²νΌλ μ΄ν리μΌμ΄μ μ΄ μ °μ΄λμ μ λ¬ν΄μΌ νλ λ°μ΄ν°λ₯Ό μ μ₯νλλ° μ¬μ©λλ€.
μ°λ¦¬κ° μ¬μ©ν μΈκ°μ§ λ³μλ μλ, λ·°, ν¬μ λ³ν νλ ¬μ΄λ€.
μ΄ νλ ¬λ€μ μ΄μ©νμ¬ μ μ μ °μ΄λμμ μμΉλ₯Ό λ³ννλ€.
π λ³μ μ μΈ λ° μλ‘μ΄ μ μ μ °μ΄λ
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}
//
// Vertex Shader
//
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul( Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Color = Color;
return output;
}
λ λλ§ ν λ μ¬μ©ν λ³νμ μ μ₯ν μΈ κ°μ νλ ¬λ μ μν΄μΌ νλ€. λ λλ§νκΈ° μ μ μ΄λ¬ν νλ ¬μ κ°μ Constant bufferμ 볡μ¬νλ€. κ·Έλ¬κ³ λ ν Draw()λ₯Ό νΈμΆνμ¬ λ λλ§μ μμνλ©΄, μ μ μ °μ΄λλ Constant Bufferμ μ μ₯λ νλ ¬μ μ½λλ€.
ID3D11Buffer* g_pConstantBuffer = NULL;
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;
ID3D11Buffer κ°μ²΄λ₯Ό λ§λ€κΈ° μν΄μλ ID3D11Device::CreateBuffer()λ₯Ό μ¬μ©νκ³ D3D11_BIND_CONSTANT_BUFFERλ₯Ό λͺ μν΄μΌ νλ€.
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
if( FAILED(g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer ) ) )
return hr;
λ€μμΌλ‘ ν μΌμ λ³νμ μννκΈ° μν΄ μ¬μ©ν μΈ κ°μ§ νλ ¬μ λ§λλ κ²μ΄λ€. μ°λ¦¬λ μΌκ°νμ΄ XY νλ©΄μ νννκ² μμ μ μμΉνκΈ°λ₯Ό μνλ€. κ°μ²΄ 곡κ°μ μ μ λ²νΌμμ μ΄λ°μμΌλ‘ μ΄λ―Έ μ μ₯λμ΄ μμΌλ―λ‘ μλ λ³νμ κΈ°λ³Έ νλ ¬μ΄ λλ€.
μΉ΄λ©λΌκ° [0 1 -5]μ μμΉνλ©° [0 1 0]μ λ°λΌλ³΄κ² νκ³ μ, XMMatrixLookAtLH()λ₯Ό νΈμΆνμ¬ κ³μ°ν μ μλ€. +Y λ°©ν₯μ΄ μμͺ½μΌλ‘ μ μ§λμ΄μΌ νλ€.
λ§μ§λ§μΌλ‘ ν¬μ νλ ¬μ μ»κΈ° μν΄ XMMatrixPerspectiveFovLH()λ₯Ό νΈμΆνλ€.
μ΄ μΈκ°μ§ νλ ¬μ μ μ λ³μ g_World, g_View, g_Projectionμ μ μ₯λλ€.
νλ ¬μ μμ λ²νΌμ κΈ°λ‘ν΄μΌ λ λλ§ν λ GPUκ° μ½μ μ μλ€. ID3D11DeviceContext::UpdateSubresource() APIλ₯Ό μ¬μ©νμ¬ μ °μ΄λμ μμ λ²νΌμ λμΌν μμλ‘ μ μ₯λ νλ ¬μ ν¬μΈν°λ₯Ό μ λ¬ ν μ μλ€. μ΄λ₯Ό μν΄ μ °μ΄λμ μμ λ²νΌμ λμΌν λ μ΄μμμ κ°μ§ ꡬ쑰체λ₯Ό λ§λ€ κ²μ΄λ€.
//
// Update variables
//
ConstantBuffer cb;
cb.mWorld = XMMatrixTranspose( g_World );
cb.mView = XMMatrixTranspose( g_View );
cb.mProjection = XMMatrixTranspose( g_Projection );
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb, 0, 0 );