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

      게임 개발자 유정룡

      포트폴리오

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

DirectX11 공부 10일차(Component 패턴 - Camera, MeshRenderer)

10 Jun 2021

Reading time ~3 minutes

어예 10일!

바뀐것

Graphics 클래스를 싱글톤으로 바꿨다.

  • 다른 곳에서 사용하는 곳이 많기 때문에

Camera

Camera 컴포넌트이다.

이제 누구나 카메라를 달면 보인다.

물론 가장 마지막에 업데이트 되는 카메라만 보인다.

Transform.h

#pragma once
#include "IComponent.h"

struct CAMERA_DATA
{
	D3DXMATRIX view;
	D3DXMATRIX projection;
};

class CameraComponent final : public IComponent
{
public:
	CameraComponent(class Actor* const actor, class Transform* const transform);
	~CameraComponent() = default;

	void Initialize() override;
	void Update() override;
	void Destroy() override;

	const D3DXMATRIX& GetView() { return view; }
	const D3DXMATRIX& GetProjection() { return proj; }

	std::shared_ptr<class D3D11_ConstantBuffer> GetConstantBuffer() const { return gpu_buffer; }
	void UpdateConstantBuffer();

private:
	void UpdateViewMatrix();
	void UpdateProjectionMatrix();

private:
	D3DXMATRIX view;
	D3DXMATRIX proj;

	std::shared_ptr<class D3D11_ConstantBuffer> gpu_buffer;
};

Transform.cpp

#include "stdafx.h"
#include "CameraComponent.h"
#include "Transform.h"

CameraComponent::CameraComponent(Actor* const actor, Transform* const transform)
	: IComponent(actor, transform)
{

}

void CameraComponent::Initialize()
{
	D3DXMatrixIdentity(&view);
	D3DXMatrixIdentity(&proj);

	UpdateViewMatrix();
	UpdateProjectionMatrix();
}

void CameraComponent::Update()
{
	UpdateViewMatrix();
	UpdateProjectionMatrix();
}

void CameraComponent::Destroy()
{
}

void CameraComponent::UpdateConstantBuffer()
{
	if (!gpu_buffer)
	{
		gpu_buffer = std::make_shared<D3D11_ConstantBuffer>(&Graphics::Get());
		gpu_buffer->Create<CAMERA_DATA>();

		CAMERA_DATA* gpu_data = gpu_buffer->Map<CAMERA_DATA>();
		{
			D3DXMatrixTranspose(&gpu_data->view, &view);
			D3DXMatrixTranspose(&gpu_data->projection, &proj);
		}
		gpu_buffer->UnMap();
	}
}

void CameraComponent::UpdateViewMatrix()
{
	D3DXVECTOR3 position = transform->GetPosition();
	D3DXVECTOR3 forward = transform->GetForward();
	D3DXVECTOR3 up = transform->GetUp();

	D3DXVECTOR3 eye = position + forward;

	D3DXMatrixLookAtLH(&view, &position, &eye, &up);
}

void CameraComponent::UpdateProjectionMatrix()
{
	D3DXMatrixOrthoLH(&proj, Settings::Get().GetWidth(), Settings::Get().GetHeight(), 0.0f, 1.0f);
}

뭐 딱히 전에 있던걸 갖고오는 것이라 딱히 바뀐건 없다.

MeshRendererComponent

MeshRendererComponent.h

#pragma once
#include "IComponent.h"

enum class MeshType : uint
{
	Quad,
	ScreenQuad
};

class MeshRendererComponent final : public IComponent
{
public:
	MeshRendererComponent(class Actor* const actor, class Transform* const transform);
	~MeshRendererComponent() = default;

	void Initialize() override;
	void Update() override;
	void Destroy() override;

	/*
	* Mesh
	*/
	std::shared_ptr<D3D11_VertexBuffer> GetVertexBuffer() const { return vertex_buffer; }
	std::shared_ptr<D3D11_IndexBuffer> GetIndexBuffer() const { return index_buffer; }
	void SetStandardMesh();

	/*
	* Material
	*/
	std::shared_ptr<D3D11_Shader> GetVertexShader() const { return vertex_shader; }
	std::shared_ptr<D3D11_Shader> GetPixelShader() const { return pixel_shader; }
	std::shared_ptr<D3D11_InputLayout> GetInputLayout() const { return input_layout; }
	void SetStandardMaterial();

private:
	MeshType mesh_type = MeshType::Quad;
	std::shared_ptr<D3D11_VertexBuffer> vertex_buffer = nullptr;
	std::shared_ptr<D3D11_IndexBuffer> index_buffer = nullptr;
	std::shared_ptr<D3D11_InputLayout> input_layout = nullptr;
	std::shared_ptr<D3D11_Shader> vertex_shader = nullptr;
	std::shared_ptr<D3D11_Shader> pixel_shader = nullptr;
};

역시 이 부분도 바뀐건 없다.

MeshRendererComponent.cpp

#include "stdafx.h"
#include "MeshRendererComponent.h"

MeshRendererComponent::MeshRendererComponent(Actor* const actor, Transform* const transform)
	:IComponent(actor, transform)
{
}

void MeshRendererComponent::Initialize()
{
	SetStandardMesh();
	SetStandardMaterial();
}

void MeshRendererComponent::Update()
{
}

void MeshRendererComponent::Destroy()
{
}

void MeshRendererComponent::SetStandardMesh()
{
	D3D11_Geometry<D3D11_VertexColor> geometry;
	Geometry_Generator::CreateQuad(geometry, D3DXCOLOR{ 1.0f, 0.0f, 1.0f, 1.0f });

	// Vertex Buffer
	vertex_buffer = std::make_shared<D3D11_VertexBuffer>(&Graphics::Get());
	vertex_buffer->Create(geometry.GetVertices());

	// IndexBuffer
	index_buffer = std::make_shared<D3D11_IndexBuffer>(&Graphics::Get());
	index_buffer->Create(geometry.GetIndices());
}

void MeshRendererComponent::SetStandardMaterial()
{	// VertexShader
	vertex_shader = std::make_shared<D3D11_Shader>(&Graphics::Get());
	vertex_shader->Create(ShaderScope_VS, "_Assets/Shader/Color.hlsl");
	// Pixel Shader
	pixel_shader = std::make_shared<D3D11_Shader>(&Graphics::Get());
	pixel_shader->Create(ShaderScope_PS, "_Assets/Shader/Color.hlsl");
	// Input Layout
	input_layout = std::make_shared<D3D11_InputLayout>(&Graphics::Get());
	input_layout->Create(D3D11_VertexColor::descs, D3D11_VertexColor::count, vertex_shader->GetShaderBlob());

}

Execute

마지막으로 적용하는 부분이다.

각 엑터를 추가하게끔

const std::shared_ptr<class Actor> Execute::CreateActor(const bool& is_active)
{
	std::shared_ptr<class Actor> actor = std::make_shared<class Actor>();
	actor->SetActive(is_active);
	AddActor(actor);

	return actor;
}

void Execute::AddActor(const std::shared_ptr<class Actor>& actor)
{
	actors.emplace_back(actor);
}

이 함수를 만든뒤

생성자에서

	std::shared_ptr<Actor> camera = CreateActor();
	camera->AddComponent<CameraComponent>();
	camera->SetName("MainCamera");

	std::shared_ptr<Actor> player = CreateActor();
	player->AddComponent<MeshRendererComponent>();
	player->GetComponent<Transform>()->SetScale(D3DXVECTOR3(100.0f, 100.0f, 1.0f));
	player->GetComponent<Transform>()->SetPosition(D3DXVECTOR3(100.0f, 0.0f, 0.0f));
	player->SetName("Player");

	std::shared_ptr<Actor> monster = CreateActor();
	monster->AddComponent<MeshRendererComponent>();
	monster->GetComponent<Transform>()->SetScale(D3DXVECTOR3(100.0f, 100.0f, 1.0f));
	monster->GetComponent<Transform>()->SetPosition(D3DXVECTOR3(-100.0f, 0.0f, 0.0f));
	monster->SetName("Monster");

각 엑터를 생성하고

void Execute::Update()
{
	for (const std::shared_ptr<Actor> actor : actors)
	{
		actor->Update();
	}
}

void Execute::Render()
{
	uint stride = sizeof(D3D11_VertexTexture);
	uint offset = 0;

	Graphics::Get().Begin();

	{

		for (const std::shared_ptr<Actor> actor : actors)
		{
			if (std::shared_ptr<CameraComponent> camera = actor->GetComponent<CameraComponent>())
			{
				camera->UpdateConstantBuffer();
				pipeline->SetConstantBuffer(0, ShaderScope_VS, camera->GetConstantBuffer().get());
			}
			actor->Render(pipeline.get());
		}
	}

	Graphics::Get().End();
}

업데이트와 랜더링을 해주면 된다.

이제 유동적으로 액터를 추가할 수 있다.



DirectX Share Tweet +1