이전 2D때 사용했던 Camera코드를 가져와서 3D에 맞게 원근투영(Persperctive)만 되는 카메라로 수정하기
#pragma once
#include "Component.h"
enum class ProjectionType
{
Perspective, // 원근 투형 (3d, 원근법에 따라 크기 차이)
Orthographic, // 직교 투영 (2d, 화면에 들어온 모든 오브젝트는 같은 크기)
};
class Camera : public Component
{
using Super = Component;
public:
Camera();
virtual ~Camera();
virtual void Update() override;
void UpdateMatrix();
void SetNear(float nearPlane) { _near = nearPlane; }
void SetFar(float farPlane) { _far = farPlane; }
void SetFov(float fov) { _fov = fov; }
void SetWidth(float width) { _width = width; }
void SetHeight(float height) { _height = height; }
Matrix& GetViewMatrix() { return _matView; }
Matrix& GetProjectionMatrix() { return _matProjection; }
private:
Matrix _matView = Matrix::Identity;
Matrix _matProjection = Matrix::Identity;
float _near = 1.f;
float _far = 1000.f;
float _fov = XM_PI / 4.f;
float _width = 0.f;
float _height = 0.f;
public:
static Matrix S_MatView;
static Matrix S_MatProjection;
};
#include "pch.h"
#include "Camera.h"
Matrix Camera::S_MatView = Matrix::Identity;
Matrix Camera::S_MatProjection = Matrix::Identity;
Camera::Camera() : Super(ComponentType::Camera)
{
_width = static_cast<float>(GAME->GetGameDesc().width);
_height = static_cast<float>(GAME->GetGameDesc().height);
}
Camera::~Camera()
{
}
void Camera::Update()
{
UpdateMatrix();
}
void Camera::UpdateMatrix()
{
Vec3 eyePosition = GetTransform()->GetPosition();
Vec3 focusPosition = eyePosition + GetTransform()->GetLook();
Vec3 upDirection = GetTransform()->GetUp();
S_MatView = ::XMMatrixLookAtLH(eyePosition, focusPosition, upDirection);
//S_MatView = GetTransform()->GetWorldMatrix().Invert();
S_MatProjection = ::XMMatrixPerspectiveFovLH(_fov, _width / _height, _near, _far);
}
#pragma once
#include "Engine/MonoBehaviour.h"
class CameraScript : public MonoBehaviour
{
public:
virtual void Start() override;
virtual void Update() override;
float _speed = 10.f;
};
#include "pch.h"
#include "CameraScript.h"
#include "Transform.h"
void CameraScript::Start()
{
}
void CameraScript::Update()
{
float dt = TIME->GetDeltaTime();
Vec3 pos = GetTransform()->GetPosition();
if (INPUT->GetButton(KEY_TYPE::W))
{
pos += GetTransform()->GetLook() * _speed * dt;
}
if (INPUT->GetButton(KEY_TYPE::S))
{
pos -= GetTransform()->GetLook() * _speed * dt;
}
if (INPUT->GetButton(KEY_TYPE::A))
{
pos -= GetTransform()->GetRight() * _speed * dt;
}
if (INPUT->GetButton(KEY_TYPE::D))
{
pos += GetTransform()->GetRight() * _speed * dt;
}
GetTransform()->SetPosition(pos);
if (INPUT->GetButton(KEY_TYPE::Q))
{
Vec3 rotation = GetTransform()->GetLocalRotation();
rotation.x -= dt * 0.5f;
GetTransform()->SetLocalRotation(rotation);
}
if (INPUT->GetButton(KEY_TYPE::E))
{
Vec3 rotation = GetTransform()->GetLocalRotation();
rotation.x += dt * 0.5f;
GetTransform()->SetLocalRotation(rotation);
}
if (INPUT->GetButton(KEY_TYPE::Z))
{
Vec3 rotation = GetTransform()->GetLocalRotation();
rotation.y -= dt * 0.5f;
GetTransform()->SetLocalRotation(rotation);
}
if (INPUT->GetButton(KEY_TYPE::C))
{
Vec3 rotation = GetTransform()->GetLocalRotation();
rotation.y += dt * 0.5f;
GetTransform()->SetLocalRotation(rotation);
}
}
CameraDemo에 카메라GameOjbect를 만들고 Component로 Camera와 CameraScript를 붙여준다.
#pragma once
#include "IExecute.h"
#include "Geometry.h"
class GameObject;
class CameraDemo : public IExecute
{
public:
void Init() override;
void Update() override;
void Render() override;
shared_ptr<Shader> _shader;
// Object
shared_ptr<Geometry<VertexColorData>> _geometry;
shared_ptr<VertexBuffer> _vertexBuffer;
shared_ptr<IndexBuffer> _indexBuffer;
Matrix _world = Matrix::Identity;
// Camera
shared_ptr<GameObject> _camera;
};
#include "pch.h"
#include "04. CameraDemo.h"
#include "GeometryHelper.h"
#include "Camera.h"
#include "GameObject.h"
#include "CameraScript.h"
#include "Transform.h"
void CameraDemo::Init()
{
_shader = make_shared<Shader>(L"03.ConstBuffer.fx");
_geometry = make_shared<Geometry<VertexColorData>>();
GeometryHelper::CreateQuad(_geometry, Color(0.f, 1.f, 0.f, 1.f));
_vertexBuffer = make_shared<VertexBuffer>();
_vertexBuffer->Create(_geometry->GetVertices());
_indexBuffer = make_shared<IndexBuffer>();
_indexBuffer->Create(_geometry->GetIndices());
_camera = make_shared<GameObject>();
_camera->GetOrAddTransform();
_camera->AddComponent(make_shared<Camera>());
_camera->AddComponent(make_shared<CameraScript>());
_camera->GetTransform()->SetPosition(Vec3(0, 0, -2.f));
}
void CameraDemo::Update()
{
_camera->Update();
}
void CameraDemo::Render()
{
//
_shader->GetMatrix("world")->SetMatrix((float*)&_world);
_shader->GetMatrix("view")->SetMatrix((float*)&Camera::S_MatView);
_shader->GetMatrix("projection")->SetMatrix((float*)&Camera::S_MatProjection);
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->Draw(0, 0, 3);
_shader->DrawIndexed(0, 0, _indexBuffer->GetCount(), 0, 0);
}
