서의 공간
[T16.2] Draw Triangle 본문
핵심 개념
도형이 그려지기 위한 과정은 다음과 같다.
1.
- 정점 타입 정의, 정점의 개수 결정
- 정점들을 저장하는 정점 버퍼 생성
- 정점 버퍼를 파이프라인의 IA단계에 바인드
2.
- 셰이더의 바이트 코드를 관리하는 ID3DBlob 인터페이스로 셰이더 파일 읽기
- 정점 및 픽셀 셰이더 생성
- 정점 및 픽셀 셰이더 파이프라인의 각 셰이더 단계에 바인드(VS, PS)
3.
- 정점의 각 속성에 대한 정보를 작성한다. Semantic name에 주목
- InputLayout 생성, 필요 파라미터로 blob을 필요로 함(셰이더 바이트 코드).
- InputLayout을 파이프라인의 IA단계에 바인드
4. 백버퍼를 파이프라인의 OM단계에 바인드
5. 정점의 기본 기하 구조를 설정하여 파이프라인의 IA단계에 바인드
6.
- 뷰포트 생성
- 뷰포트를 파이프라인의 RS단계에 바인드
7. 그리기 함수 호출
Graphics.cpp
더보기
void Graphics::DrawTestTriangle()
{
namespace wrl = Microsoft::WRL;
HRESULT hr;
struct Vertex
{
float x;
float y;
};
// create vertex buffer (1 2d triangle at center of screen)
const Vertex vertices[] =
{
{ 0.0f,0.5f },
{ 0.5f,-0.5f },
{ -0.5f,-0.5f },
};
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 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
// 픽셀 셰이더를 PS에 바인딩
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)
/*
InputLayout을 만들기 전에 INPUT_ELEMENT_DESC 먼저 작성한다.
Description에는 정점의 각 속성의 정보를 설정한다.
또한 가장 중요한 Semantic name정보를 기억하자. GPU와의 통신하기 위해
필요한 정보이다. 그리고 CreateInputLayout에서 파라미터로 pBlob의 정보를 넘기는데
pBlob에는 셰이더 코드들이 들어있다. GPU에 그릴 정점들을
제출할 때 정점들을 이렇게 계산해주세요 라는 의미인 듯 싶다.
*/
wrl::ComPtr<ID3D11InputLayout> pInputLayout;
const D3D11_INPUT_ELEMENT_DESC ied[] =
{
{ "Position",0,DXGI_FORMAT_R32G32_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() );
// bind render target
// Target은 앞서 백버퍼의 뷰이고, 그것을 OM에 바인드 한다. 최종적으로 계산된
// 그려지는 부분을 백버퍼에 그리기 위해서이다.
pContext->OMSetRenderTargets( 1u,pTarget.GetAddressOf(),nullptr );
// 입력되는 정점의 기본 기하 구조를 설정한다.
// Set primitive topology to triangle list (groups of 3 vertices)
pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
// 이제 백버퍼를 Window에 출력할텐데 뷰포트는 바로 Window에 출력 될 한 영역이다.
// 따라서 뷰포트에 따라 window의 전체에 그려질지 부분적으로 그려질지 결정할 수 있다.
// 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->Draw( (UINT)std::size( vertices ),0u ) );
}
PixelShader.hlsl
더보기
float4 main() : SV_Target
{
return float4(1.0f,1.0f,1.0f,1.0f);
}
'Graphics API > DirectX 11 - Chili' 카테고리의 다른 글
[T18] Constant buffer (0) | 2020.11.29 |
---|---|
[T17] Draw Indexed Triangle (0) | 2020.11.29 |
[T16.1] Draw Triangle (0) | 2020.11.28 |
[T16.0] DirectX 11 파이프라인 (0) | 2020.11.28 |
[T11] Graphics class (0) | 2020.11.27 |
Comments