서의 공간
[T20] Solid cube, Depth and stencil 본문
핵심 개념
정점의 색상이 아닌 면의 색상 설정
z-buffering 기법을 통한 물체 그리기(컬링) - Depth stencil을 사용해야하는 이유
Graphics.cpp
더보기
Graphics::Graphics( HWND hWnd )
{
// ...
// create depth stensil state
D3D11_DEPTH_STENCIL_DESC dsDesc = {};
dsDesc.DepthEnable = TRUE;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
wrl::ComPtr<ID3D11DepthStencilState> pDSState;
GFX_THROW_INFO( pDevice->CreateDepthStencilState( &dsDesc,&pDSState ) );
// bind depth state
pContext->OMSetDepthStencilState( pDSState.Get(),1u );
// create depth stensil texture
wrl::ComPtr<ID3D11Texture2D> pDepthStencil;
D3D11_TEXTURE2D_DESC descDepth = {};
descDepth.Width = 800u;
descDepth.Height = 600u;
descDepth.MipLevels = 1u;
descDepth.ArraySize = 1u;
descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = 1u;
descDepth.SampleDesc.Quality = 0u;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
GFX_THROW_INFO( pDevice->CreateTexture2D( &descDepth,nullptr,&pDepthStencil ) );
// create view of depth stensil texture
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV = {};
descDSV.Format = DXGI_FORMAT_D32_FLOAT;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0u;
GFX_THROW_INFO( pDevice->CreateDepthStencilView(
pDepthStencil.Get(),&descDSV,&pDSV
) );
// bind depth stensil view to OM
pContext->OMSetRenderTargets( 1u,pTarget.GetAddressOf(),pDSV.Get() );
}
void Graphics::ClearBuffer( float red,float green,float blue ) noexcept
{
const float color[] = { red,green,blue,1.0f };
pContext->ClearRenderTargetView( pTarget.Get(),color );
pContext->ClearDepthStencilView( pDSV.Get(),D3D11_CLEAR_DEPTH,1.0f,0u );
}
void Graphics::DrawTestTriangle( float angle,float x,float z )
{
HRESULT hr;
struct Vertex
{
struct
{
float x;
float y;
float z;
} pos;
};
// create vertex buffer (1 2d triangle at center of screen)
Vertex vertices[] =
{
{ -1.0f,-1.0f,-1.0f },
{ 1.0f,-1.0f,-1.0f },
{ -1.0f,1.0f,-1.0f },
{ 1.0f,1.0f,-1.0f },
{ -1.0f,-1.0f,1.0f },
{ 1.0f,-1.0f,1.0f },
{ -1.0f,1.0f,1.0f },
{ 1.0f,1.0f,1.0f },
};
wrl::ComPtr<ID3D11Buffer> pVertexBuffer;
D3D11_BUFFER_DESC bd = {};
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.CPUAccessFlags = 0u;
bd.MiscFlags = 0u;
bd.ByteWidth = sizeof( vertices );
bd.StructureByteStride = sizeof( Vertex );
D3D11_SUBRESOURCE_DATA sd = {};
sd.pSysMem = vertices;
GFX_THROW_INFO( pDevice->CreateBuffer( &bd,&sd,&pVertexBuffer ) );
// Bind vertex buffer to pipeline
const UINT stride = sizeof( Vertex );
const UINT offset = 0u;
pContext->IASetVertexBuffers( 0u,1u,pVertexBuffer.GetAddressOf(),&stride,&offset );
// create index buffer
const unsigned short indices[] =
{
0,2,1, 2,3,1,
1,3,5, 3,7,5,
2,6,3, 3,6,7,
4,5,7, 4,7,6,
0,4,2, 2,4,6,
0,1,4, 1,5,4
};
wrl::ComPtr<ID3D11Buffer> pIndexBuffer;
D3D11_BUFFER_DESC ibd = {};
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.Usage = D3D11_USAGE_DEFAULT;
ibd.CPUAccessFlags = 0u;
ibd.MiscFlags = 0u;
ibd.ByteWidth = sizeof( indices );
ibd.StructureByteStride = sizeof( unsigned short );
D3D11_SUBRESOURCE_DATA isd = {};
isd.pSysMem = indices;
GFX_THROW_INFO( pDevice->CreateBuffer( &ibd,&isd,&pIndexBuffer ) );
// bind index buffer
pContext->IASetIndexBuffer( pIndexBuffer.Get(),DXGI_FORMAT_R16_UINT,0u );
// create constant buffer for transformation matrix
struct ConstantBuffer
{
dx::XMMATRIX transform;
};
const ConstantBuffer cb =
{
{
dx::XMMatrixTranspose(
dx::XMMatrixRotationZ( angle ) *
dx::XMMatrixRotationX( angle ) *
dx::XMMatrixTranslation( x,0.0f,z + 4.0f ) *
dx::XMMatrixPerspectiveLH( 1.0f,3.0f / 4.0f,0.5f,10.0f )
)
}
};
wrl::ComPtr<ID3D11Buffer> pConstantBuffer;
D3D11_BUFFER_DESC cbd;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0u;
cbd.ByteWidth = sizeof( cb );
cbd.StructureByteStride = 0u;
D3D11_SUBRESOURCE_DATA csd = {};
csd.pSysMem = &cb;
GFX_THROW_INFO( pDevice->CreateBuffer( &cbd,&csd,&pConstantBuffer ) );
// bind constant buffer to vertex shader
pContext->VSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
// lookup table for cube face colors
struct ConstantBuffer2
{
struct
{
float r;
float g;
float b;
float a;
} face_colors[6];
};
const ConstantBuffer2 cb2 =
{
{
{1.0f,0.0f,1.0f},
{1.0f,0.0f,0.0f},
{0.0f,1.0f,0.0f},
{0.0f,0.0f,1.0f},
{1.0f,1.0f,0.0f},
{0.0f,1.0f,1.0f},
}
};
wrl::ComPtr<ID3D11Buffer> pConstantBuffer2;
D3D11_BUFFER_DESC cbd2;
cbd2.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd2.Usage = D3D11_USAGE_DEFAULT;
cbd2.CPUAccessFlags = 0u;
cbd2.MiscFlags = 0u;
cbd2.ByteWidth = sizeof( cb2 );
cbd2.StructureByteStride = 0u;
D3D11_SUBRESOURCE_DATA csd2 = {};
csd2.pSysMem = &cb2;
GFX_THROW_INFO( pDevice->CreateBuffer( &cbd2,&csd2,&pConstantBuffer2 ) );
// bind constant buffer to pixel shader
pContext->PSSetConstantBuffers( 0u,1u,pConstantBuffer2.GetAddressOf() );
// create pixel shader
wrl::ComPtr<ID3D11PixelShader> pPixelShader;
wrl::ComPtr<ID3DBlob> pBlob;
GFX_THROW_INFO( D3DReadFileToBlob( L"PixelShader.cso",&pBlob ) );
GFX_THROW_INFO( pDevice->CreatePixelShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(),nullptr,&pPixelShader ) );
// bind pixel shader
pContext->PSSetShader( pPixelShader.Get(),nullptr,0u );
// create vertex shader
wrl::ComPtr<ID3D11VertexShader> pVertexShader;
GFX_THROW_INFO( D3DReadFileToBlob( L"VertexShader.cso",&pBlob ) );
GFX_THROW_INFO( pDevice->CreateVertexShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(),nullptr,&pVertexShader ) );
// bind vertex shader
pContext->VSSetShader( pVertexShader.Get(),nullptr,0u );
// input (vertex) layout (2d position only)
wrl::ComPtr<ID3D11InputLayout> pInputLayout;
const D3D11_INPUT_ELEMENT_DESC ied[] =
{
{ "Position",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0 },
};
GFX_THROW_INFO( pDevice->CreateInputLayout(
ied,(UINT)std::size( ied ),
pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
&pInputLayout
) );
// bind vertex layout
pContext->IASetInputLayout( pInputLayout.Get() );
// Set primitive topology to triangle list (groups of 3 vertices)
pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
// configure viewport
D3D11_VIEWPORT vp;
vp.Width = 800;
vp.Height = 600;
vp.MinDepth = 0;
vp.MaxDepth = 1;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
pContext->RSSetViewports( 1u,&vp );
GFX_THROW_INFO_ONLY( pContext->DrawIndexed( (UINT)std::size( indices ),0u,0u ) );
}
Shader
더보기
VertexShader.hlsl
cbuffer CBuf
{
matrix transform;
};
float4 main( float3 pos : Position ) : SV_Position
{
return mul( float4(pos,1.0f),transform );
}
PixelShader.hlsl
cbuffer CBuf
{
float4 face_colors[6];
};
float4 main( uint tid : SV_PrimitiveID ) : SV_Target
{
return face_colors[tid / 2];
}
'Graphics API > DirectX 11 - Chili' 카테고리의 다른 글
[T21.2] Drawble System (0) | 2020.11.30 |
---|---|
[T21.1] Bindable System (0) | 2020.11.29 |
[T18] Constant buffer (0) | 2020.11.29 |
[T17] Draw Indexed Triangle (0) | 2020.11.29 |
[T16.2] Draw Triangle (0) | 2020.11.28 |
Comments