수업


주제

  • DirectX11 기반 사각형(Quad) 렌더링 구현
  • VertexColorData 구조를 이용한 색상 렌더링
  • GeometryHelper를 통한 정점/인덱스 버퍼 구성
  • FX11 기반 .fx 셰이더 파일을 이용한 technique/pass 셋업
  • Wireframe 렌더링을 위한 RasterizerState 사용

개념

  • Quad(사각형) 는 두 개의 삼각형으로 구성되며, 인덱스 버퍼를 사용하면 정점 네 개로 효율적으로 표현할 수 있다.
  • 정점 구조(VertexColorData) 는 위치와 색상 정보를 함께 갖는 구조체이며, 셰이더를 통해 렌더링에 반영된다.
  • FX11 기반 Shader 구성은 technique과 pass를 활용하여 다양한 렌더링 상태를 정의할 수 있다.
  • RasterizerState 는 FillMode 설정을 통해 Wireframe 모드로 출력할 수 있게 해준다.
  • GeometryHelper 클래스는 정점 및 인덱스 정보를 Geometry 객체에 자동으로 세팅하는 헬퍼 유틸리티이다.
  • 정점 버퍼(VertexBuffer)와 인덱스 버퍼(IndexBuffer)는 GPU 자원으로 설정되어 DrawIndexed 호출로 최적화된 렌더링이 가능하다.

용어정리

용어설명
Quad네 개의 꼭짓점으로 이루어진 사각형
VertexColorData위치(Vec3)와 색상(Color)를 가진 정점 데이터 구조체
Geometry정점(Vertex)과 인덱스(Index)를 포함하는 제너릭 렌더링 데이터 클래스
IndexBuffer정점을 조합하여 도형을 구성하는 인덱스 순서를 저장하는 GPU 자원
VertexBuffer정점 정보를 저장하고 GPU에 전달하는 버퍼
FX11Microsoft에서 제공하는 HLSL 기반의 Shader 효과 처리 시스템
technique / passFX11에서 셰이더의 상태 묶음 (pass는 실행 단위, technique는 그룹)
RasterizerState삼각형을 채우는 방식(FillMode)을 지정하는 상태 객체
Wireframe메시의 외곽선을 선으로만 렌더링하는 방식
DCDeviceContext. 렌더링 명령을 GPU에 전달하는 DirectX 객체

코드 분석

GeometryHelper 구현

void GeometryHelper::CreateQuad(shared_ptr<Geometry<VertexColorData>> geometry, Color color)
{
	vector<VertexColorData> vtx(4);
	vtx[0].position = Vec3(-0.5f, -0.5f, 0.f); vtx[0].color = color;
	vtx[1].position = Vec3(-0.5f, 0.5f, 0.f);  vtx[1].color = color;
	vtx[2].position = Vec3(0.5f, -0.5f, 0.f);  vtx[2].color = color;
	vtx[3].position = Vec3(0.5f, 0.5f, 0.f);   vtx[3].color = color;
	geometry->SetVertices(vtx);

	vector<uint32> idx = { 0, 1, 2, 2, 1, 3 }; // 시계방향 순서 유지
	geometry->SetIndices(idx);
}

Quad.fx Shader 구성

struct VertexInput {
	float4 position : POSITION;
	float4 color : COLOR;
};

struct VertexOutput {
	float4 position : SV_POSITION;
	float4 color : COLOR;
};

VertexOutput VS(VertexInput input) {
	VertexOutput output;
	output.position = input.position;
	output.color = input.color;
	return output;
}

float4 PS(VertexOutput input) : SV_TARGET {
	return input.color;
}

RasterizerState FillModeWireFrame {
	FillMode = Wireframe;
};

technique11 T0 {
	pass P0 {
		SetVertexShader(CompileShader(vs_5_0, VS()));
		SetPixelShader(CompileShader(ps_5_0, PS()));
	}
	pass P1 {
		SetRasterizerState(FillModeWireFrame);
		SetVertexShader(CompileShader(vs_5_0, VS()));
		SetPixelShader(CompileShader(ps_5_0, PS()));
	}
};

QuadDemo.h 핵심 멤버

class QuadDemo : public IExecute {
public:
	void Init() override;
	void Update() override;
	void Render() override;

	shared_ptr<Shader> _shader;
	shared_ptr<Geometry<VertexColorData>> _geometry;
	shared_ptr<VertexBuffer> _vertexBuffer;
	shared_ptr<IndexBuffer> _indexBuffer;
};

QuadDemo.cpp 렌더링 구성

void QuadDemo::Init() {
	_shader = make_shared<Shader>(L"02. Quad.fx");
	_geometry = make_shared<Geometry<VertexColorData>>();
	GeometryHelper::CreateQuad(_geometry, Color(1.f, 0.f, 0.f, 1.f));

	_vertexBuffer = make_shared<VertexBuffer>();
	_vertexBuffer->Create(_geometry->GetVertices());

	_indexBuffer = make_shared<IndexBuffer>();
	_indexBuffer->Create(_geometry->GetIndices());
}

void QuadDemo::Render() {
	uint32 stride = _vertexBuffer->GetStride();
	uint32 offset = _vertexBuffer->GetOffset();

	DC->IASetVertexBuffers(0, 1, _vertexBuffer->GetComPtr().GetAddressOf(), &stride, &offset);
	DC->IASetIndexBuffer(_indexBuffer->GetComPtr().Get(), DXGI_FORMAT_R32_UINT, 0);

	_shader->DrawIndexed(0, 0, _indexBuffer->GetCount(), 0, 0);  // 기본 채움
	// _shader->DrawIndexed(0, 1, _indexBuffer->GetCount(), 0, 0);  // 와이어프레임 출력
}

Main.cpp 실행 단위 설정

int WINAPI WinMain(...) {
	GameDesc desc;
	desc.app = make_shared<QuadDemo>();
	GAME->Run(desc);
	return 0;
}

핵심

  1. GeometryHelper를 사용하여 Quad의 정점(Vertex)과 인덱스(Index)를 자동 생성한다.
  2. VertexColorData를 통해 정점별 색상 정보를 전달하고 Shader에서 처리한다.
  3. FX11 기반의 .fx 파일을 활용하여 Vertex/Pixel Shader를 한 파일에서 구성하고, pass별로 렌더링 상태를 제어한다.
  4. pass P1을 통해 Wireframe 모드를 출력할 수 있으며 RasterizerState로 설정 가능하다.
  5. DrawIndexed 함수는 GPU에 정점 및 인덱스를 기반으로 도형을 효율적으로 그리도록 명령을 전달한다.
  6. Shader 클래스 내부에서 pipeline과 material 기능을 통합적으로 관리하며 사용자는 로직 구현에 집중할 수 있다.
  7. Main에서 실행 단위를 QuadDemo로 설정하여 실습 단위 프로그램을 교체해가며 테스트 가능하다.

profile
李家네_공부방

0개의 댓글