KoreanFoodie's Study

DirectX 11 2D 게임 프로그래밍 - 6. Input Assembler Stage 세팅하기 본문

Game Dev/DirectX

DirectX 11 2D 게임 프로그래밍 - 6. Input Assembler Stage 세팅하기

GoldGiver 2021. 10. 24. 11:05


DirectX 11 2D 게임 프로그래밍 - 6. Input Assembler Stage 세팅하기

Rendering Pipeline에는 다음과 같은 스테이지가 있다.

IA - VS - RS - PS - OM : 이 중, 오늘은 IA 스테이지인 Input Assembler Stage를 세팅하도록 하겠다.

먼저, DirectX의 기본 데이터인 정점(Vertex)를 만들고, 그 정점들을 파이프라인에 연결할 Buffer형 자원들 만든다. 그 후, Device Context를 활용하여 파이프라인에 Buffer형 자원을 세팅한다. 마지막으로 Primitive Topology 정보로 어떻게 정점을 연결할지 세팅할 수 있다.

 

알아두어야 할 개념 :

1. vector 란 무엇인가?

2. D3D11_USAGE에 대해 조사하기

3. Primitive Topology에 대해 조사하기

자세한 내용은 주석을 통해 알아보자.

 

Execute.h

#pragma once

// Rendering Pipeline : 렌더링을 하기 위해 수행되어야 하는 단계들
// IA - VS - RS - PS - OM

// IA : Input Assembler Stage : 기본 데이터가 들어가는 입력 조립기 단계
// - Vertex : DirectX의 기본 데이터는 정점이다! - 사용자마다 정보가 다양하기에 기본 자료형을 제공하지 않는다! -> 커스터마이징 필요

struct VertexColor
{
	D3DXVECTOR3 position; 
	D3DXCOLOR clear_color;

};

class Execute final
{
public:
	Execute();
	~Execute();

	void Update();
	void Render();

private:
	class Graphics* graphics = nullptr;

	// VertexColor는 우리가 만든 데이터... Ram에 들어감.
	
	VertexColor* vertices = nullptr;

	// CPU 자원을 GPU에 입력하기 위해 변환해야 한다!
	ID3D11Buffer* vertex_buffer = nullptr;

	// 0, 0, 0, 0, 0, 0, 0 이런 식으로 좌표 3개와 색깔 데이터 4개가 들어왔을때...?
	// 컴퓨터가 어떻게 읽고 구획을 나누어야 하는지 -> Layout으로 설정!
	// Layout 데이터는 혼자 생성될 수가 없다. 단계 별로 일치해야 한다는 뜻.
	ID3D11InputLayout* input_layout = nullptr;

};

 

Execute.cpp

#include "stdafx.h"
#include "Execute.h"

#include "Graphics.h"

Execute::Execute()
{
	// 그냥 쓰면 불완전한 형식은 사용할 수 없다고 나옴. 따라서 해당 자료형의 헤더파일을 include 해주어야 한다.
	graphics = new Graphics();
	graphics->Initialize();
	graphics->CreateBackBuffer(static_cast<uint>(Settings::Get().GetWidth()), static_cast<uint>(Settings::Get().GetHeight()));

	// 시계방향으로 회전하는 직각삼각형 만들기
	vertices = new VertexColor[3];

	// Vertex Data
	{

		vertices[0].position = D3DXVECTOR3(-0.5f, -0.5f, 0.0f);
		vertices[0].clear_color = D3DXCOLOR(1.01f, 0.0f, 0.0f, 1.0f);

		vertices[1].position = D3DXVECTOR3(+0.5f, +0.5f, 0.0f);
		vertices[1].clear_color = D3DXCOLOR(1.01f, 0.0f, 0.0f, 1.0f);

		vertices[2].position = D3DXVECTOR3(+0.5f, -0.5f, 0.0f);
		vertices[2].clear_color = D3DXCOLOR(1.01f, 0.0f, 0.0f, 1.0f);

	}


	// Vertex Buffer
	{
		D3D11_BUFFER_DESC desc;

		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		
		// Usage란? : GPU와 CPU 중 누가 데이터를 읽거나 쓸 것인지 결정하는 플래그
		// D3D11_USAGE_DEFAULT : GPU만 데이터를 읽고 쓸 수 있다.
		// D3D11_USAGE_IMMUTABLE : GPU만 데이터를 읽을 수 있다. (쓰기는 불가)
		desc.Usage = D3D11_USAGE_DEFAULT; 
		
		// Buffer형 데이터를 어느 스테이지에서 사용할 건지 지정해주는 플래그다.
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

		// Vertex 버퍼를 어느 정도 크기로 생성할 것인지?
		desc.ByteWidth = sizeof(VertexColor) * 3;

		// 부가적인 데이터.. CPU데이터를 GPU에 연결할 수 있다.
		D3D11_SUBRESOURCE_DATA sub_data;
		ZeroMemory(&sub_data, sizeof(D3D11_SUBRESOURCE_DATA));
		sub_data.pSysMem = vertices;

		auto hr = graphics->GetDevice()->CreateBuffer(&desc, &sub_data, &vertex_buffer);

		assert(SUCCEEDED(hr));
	}

}

Execute::~Execute()
{
	SAFE_RELEASE(vertex_buffer);

	SAFE_DELETE_ARRAY(vertices);
	SAFE_DELETE(graphics);
}

void Execute::Update()
{
}

void Execute::Render()
{
	// stride : 정점 하나의 크기에 대한 정보
	uint stride = sizeof(VertexColor);

	// offset : 정점 정보 중에 어떤 정점부터 사용할 것인지에 대한 정보
	uint offset = 0;

	graphics->Begin();

	// Rendering Part
	// 자원을 만들때는 device, GPU에 연동할 때는 device_context
	{
		graphics->GetDeviceContext()->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
		
		// TODO : input layout
		
		// 정점을 어떻게 연결할 것인가에 대한 연결성 정보. 여기서는 삼각형으로 이어라...
		graphics->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST)	;

	}

	graphics->End();

}

//

 

 


더 자세한 내용이 궁금하시다면 직접 들어보시는 걸 추천드립니다!

Comments