서의 공간

[T16.2] Draw Triangle 본문

Graphics API/DirectX 11 - Chili

[T16.2] Draw Triangle

홍서의 2020. 11. 28. 12:21

핵심 개념

도형이 그려지기 위한 과정은 다음과 같다.

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