어예 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();
}
업데이트와 랜더링을 해주면 된다.
이제 유동적으로 액터를 추가할 수 있다.