[D3D] Camera

vector·2025년 11월 20일

이전 2D때 사용했던 Camera코드를 가져와서 3D에 맞게 원근투영(Persperctive)만 되는 카메라로 수정하기

Camera

Camera.h

#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);
}

카메라의 움직임을 가지고 있는 CameraScript 만들기

CameraScript.h

#pragma once
#include "Engine/MonoBehaviour.h"

class CameraScript : public MonoBehaviour
{
public:
	virtual void Start() override;
	virtual void Update() override;

	float _speed = 10.f;
};

CameraScript.cpp

#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);
	}
}

Main과 CameraDemo 수정

CameraDemo에 카메라GameOjbect를 만들고 Component로 Camera와 CameraScript를 붙여준다.

CameraDemo.h

#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;
};

CameraDemo.cpp

#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);
}

결과

참고강의

https://www.inflearn.com/courses/lecture?courseId=329791&type=LECTURE&unitId=161120&tab=curriculum&subtitleLanguage=ko

profile
게임 클라이언트 프로그래머 준비중 (공부 및 기록용)

0개의 댓글