• Home
  • About
    • 게임 개발자 유정룡 photo

      게임 개발자 유정룡

      포트폴리오

    • Learn More
    • Email
    • Github
    • Bitbucket
  • Projects
    • All Projects
    • All Tags

Direct3D11 공부 17일차(DebugLog)

20 Jun 2021

Reading time ~3 minutes

Debug Log

디버깅을 위해 선을 출력하는 클래스이다. 그것 외엔 딱히 기능은 없지만, 있으면 정말 편한 기능이다.

Terrain.cpp

void Terrain::CreateNormalData()
{
	for (UINT i = 0; i < indexCount / 3; i++)
	{
		UINT index0 = indices[i * 3 + 0];
		UINT index1 = indices[i * 3 + 1];
		UINT index2 = indices[i * 3 + 2];

		TerrainVertex v0 = vertices[index0];
		TerrainVertex v1 = vertices[index1];
		TerrainVertex v2 = vertices[index2];

		Vector3 a = v1.Position - v0.Position;
		Vector3 b = v2.Position - v0.Position;

		Vector3 normal;
		D3DXVec3Cross(&normal, &a, &b);

		vertices[index0].Normal += normal;
		vertices[index1].Normal += normal;
		vertices[index2].Normal += normal;
	}

	for (UINT i = 0; i < vertexCount; i++)
	{
		D3DXVec3Normalize(&vertices[i].Normal, &vertices[i].Normal);
	}
}

각 정점의 외적 정규 벡터를 구하는 함수다.

정점마다 외적을 계산하고 평균을 내면 되지만, 그렇게 하면 각 정점마다 몇개의 값이 더해져 몇으로 나눠야 하는지 정확하게 알려면 다른 변수를 넣어 메모리를 더 써야 하지만, 외적을 정규화 시키면 평균과 유사한 값이 나오기 때문에 각 정규화를 더했다.

각 IndexBuffer에 있는 정점으로 구해준다.

DebugLog.h

#pragma once
#define MAX_DEBUG_LINE 150000

class DebugLine
{
public:
	friend class Window;
	static DebugLine* Get();

private:
	static void Create();
	static void Delete();

public:
	void RenderLine(const Vector3& start, const Vector3& end);
	void RenderLine(const Vector3& start, const Vector3& end, float r, float g, float b);
	void RenderLine(const Vector3& start, const Vector3& end, const Color& color);

	void RenderLine(float x, float y, float z, float x2, float y2, float z2);
	void RenderLine(float x, float y, float z, float x2, float y2, float z2, float r, float g, float b);
	void RenderLine(float x, float y, float z, float x2, float y2, float z2, const Color& color);

private:
	void Update();
	void Render();

private:
	DebugLine();
	~DebugLine();

private:
	static DebugLine* instance;

private:
	Shader* shader;
	Matrix world;

	ID3D11Buffer* vertexBuffer;
	VertexColor* vertices;

	UINT drawCount = 0;
};

싱글톤 클래스로 만들었으며, 자세한건 cpp에서 설명

DebugLog.cpp

void DebugLine::Update()
{

	Matrix world;
	D3DXMatrixIdentity(&world);

	shader->AsMatrix("World")->SetMatrix(world);
	shader->AsMatrix("View")->SetMatrix(Context::Get()->View());
	shader->AsMatrix("Projection")->SetMatrix(Context::Get()->Projection());
}

void DebugLine::Render()
{
	if (drawCount < 1)
	{
		return;
	}

	D3D::GetDC()->UpdateSubresource(vertexBuffer, 0, nullptr, vertices, sizeof(VertexColor) * drawCount, 0);

	UINT stride = sizeof(VertexColor);
	UINT offset = 0;

	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
	D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

	shader->Draw(0, 0, drawCount);

	drawCount = 0;
	ZeroMemory(vertices, sizeof(VertexColor) * MAX_DEBUG_LINE);
}

업데이트와 렌더링 부분이다.

각 선들은 VertexColor로 되어있기 때문에 모든 사이즌s VertexColor로 크기를 만들어준다.

void DebugLine::RenderLine(const Vector3 & start, const Vector3 & end, const Color & color)
{
	// 짝 start
	vertices[drawCount].Color = color;
	vertices[drawCount++].Position = start;

	// 홀 end
	vertices[drawCount].Color = color;
	vertices[drawCount++].Position = end;
}

start 에서 end까지 라인을 그어준다.

DebugLine::DebugLine()
{
	shader = new Shader(L"20_DebugLine.fx");
	
	vertices = new VertexColor[MAX_DEBUG_LINE];
	ZeroMemory(vertices, sizeof(VertexColor) * MAX_DEBUG_LINE);

	// Create Vertex Buffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.ByteWidth = sizeof(VertexColor) * MAX_DEBUG_LINE;
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

		// GPU 복사 부분
		D3D11_SUBRESOURCE_DATA subResource = { 0 };
		subResource.pSysMem = vertices;

		Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &vertexBuffer));
	}

	D3DXMatrixIdentity(&world);
}

생성자이다.

최대 Vertex만큼 크기를 정해준다.

이 상태로 Window 부분에 Render()와 Update() 에 넣어준다.

그리고 이 상태로 싱글톤을 사용해서 그어주면

DebugLine::Get()->RenderLine(0, 0, 0, 0, 100, 0, Color(1,0,0,1));
DebugLine::Get()->RenderLine(1, 0, 0, 5, 10, 0, Color(0,1,0,1));

// 그림

그러면 VertexCount만큼 그어주면

for(UINT i = 0; i < vertexCount; i++)
{
	Vector3 start = vertices[i].Position;
	Vector3 end = vertices[i].Position + vertices[i].Normal * 2;

	DebugLine::Get()->RenderLine(start, end, Color(0, 1, 1, 1));
}

굉장히 많은 Vertex와 Line을 렌더링 하기 때문에 프레임이 저하되는것을 볼 수 있다.(모발이 굉장히 많다… 부럽다…)



DirectX Share Tweet +1