본문 바로가기
Win32 API/기초

Win32 API 기초 : Camera (2)

글: 시플마 2024. 10. 5.

 

이제는 정말 입력을 받아서 

카메라를 이동시켜 보겠습니다.

 

먼저 애니메이션 클래스의 render 함수를 보면

 

50번째 줄에 코드가 추가되었습니다.

 

기존에는 애니메이션이 실제 오브젝트가 생기는 위치에

그대로 출력되었습니다.

 

그러나 이제는 카메라라는 개념이 생겼기 때문에 

오브젝트가 존재하는 위치에 바로 애니메이션을

렌더링하는 것이 아니라 카메라 위치까지 고려한

위치에 렌더링이 되어야겠죠.

 

그래서 카메라 클래스에 존재하는

GetRenderPos 함수가 카메라가 현재 중앙에서 

얼마나 떨어졌는지 구한 뒤, 오브젝트가 그려질 위치를

반환해줄 겁니다. 이를 통해 오브젝트를 렌더링하면 되죠.

 

 

Collider 클래스의 render 함수에서도

 

마찬가지로 진행해 줍니다. 

 

이때 중요한 점은 충돌체가 존재하는 실제 위치인

m_vFinalPos의 값을 바꾸면 안된다는 점이죠.

 

우리는 카메라를 이동시켰을 뿐,

오브젝트가 이동하여 충돌체의 위치까지

바뀌는 것은 아니니까요.

 

그래서 GetRenderPos 함수가 반환하는 값을 

지역 변수로 받아 이를 통해 충돌체를 렌더링해줄 겁니다.

 

 

애니메이션이 따로 존재하지 않는

오브젝트들은 자신의 render 함수 쪽에서 

Collider와 마찬가지로 렌더링할 위치를

설정해 주면 됩니다.

 

 

 


 

 

카메라 클래스의 update 함수에서

 

방향키 입력을 받아 

화면을 움직일 수 있도록 코드를 추가했습니다.

 

KEY_HOLD 매크로를 사용하였기 때문에

쭉 누르고 있으면 해당 방향으로 카메라가

쭉 이동합니다.

 

 

마우스 좌클릭 시,

카메라가 클릭한 위치로 이동하도록 하기 위해서

Scene Start 클래스의 update 함수에

 

코드를 추가하였습니다.

 

카메라 클래스의 GetRealPos 함수의 인자로

MOUSE_POS를 넣어 호출하고 반환된 값을 인자로,

SetLookAt 함수를 통해 카메라 위치를 설정합니다.

 

 

여기서 GetRealPos 함수의 내용을 보면

 

인자로 받은 위치에 m_vDiff 값을 더하고 있습니다.

 

이것이 의미하는 것은 

오브젝트의 실제 위치를 얻어 오겠다는 것이죠.

 

사실 화면에 보이는 오브젝트는 실제 위치가 아니죠.

 

왜냐하면 카메라가 움직인다고

오브젝트의 위치가 움직이지는 않기 때문에

카메라의 위치에 따라 오브젝트의 모습을 따로 

화면상에 출력해 주고 있을 뿐입니다.

 

그래서 화면상에 보이는 몬스터 오브젝트에

카메라를 이동시키고 싶어 몬스터 오브젝트를

클릭하면 어긋난 위치에 카메라가 이동될 겁니다.

 

카메라를 제대로 이동시키려면 오브젝트가 렌더링되는 

위치가 아닌 실제 위치를 얻어야 하죠.

 

그래서 렌더링 위치를 구할 때와는 반대로 

오브젝트의 위치에서 m_vDiff값을 더하는 겁니다.

 

즉 카메라가 이동하여 오브젝트가 렌더링되면서

뺀 m_vDiff값을 다시 더하여 원래 위치를 구하는 것이죠.

 

 

그렇게 얻은 실제 위치를 지역 변수로 받아

SetLookAt 함수를 통해 카메라 위치를 설정하는 겁니다.

 

 

GetRealPos 함수에 인자로 넣은 MOUSE_POS 매크로는 

 

키 매니저 클래스의 멤버 m_CursorPos를

반환하는 함수를 호출하는 매크로입니다.

 

 

m_CursorPos의 값은 키 매니저의 update 함수에서

 

설정이 됩니다.

 

기본적으로 제공되는 GetCursorPos 함수를 통해 

인자로 넣은 pCursor의 값을 현재 마우스 커서

위칫값으로 세팅합니다.

 

근데 이 값을 그대로 사용할 수는 없습니다.

 

우리가 얻고 싶은 마우스 커서의 위칫값은

우리가 실행시키는 프로그램상의 마우스 커서 위칫값인데,

GetCursorPos 함수가 반환하는 것은 윈도우 전체를 

기준으로 마우스 커서의 위칫값을 반환합니다.

 

그래서 ScreenToClient 함수를 통해 

우리가 실행시키는 프로그램의 HWND을 인자로 넣어

윈도우 전체를 기준으로 GetCursorPos 함수가 반환한

마우스 커서의 위칫값을 우리가 실행시키는 프로그램상의

위칫값으로 변환합니다.

 

이렇게 얻은 위칫값을 m_CursorPos에 대입합니다.

 

 

이렇게 한 후, 프로그램을 실행하여

좌클릭을 하면 해당 위치로 정확히

카메라가 이동하게 됩니다.

 

 

 

 


 

 

 

 

기존에는 좌클릭을 통해

카메라를 이동할 때 확 이동이 되었죠.

 

이번에는 서서히 좌클릭한 위치로

이동하게 구현하겠습니다.

 

 

카메라 클래스의 CalDiff 함수를 보면

 

카메라 클래스에 멤버 m_vPrevLookAt과

m_vCurLookAt이 추가되었음을 

알 수 있습니다.

 

m_vPrevLookAt은 카메라의 이전 위칫값을,

m_vCurLookAt은 카메라의 이전 위칫값과 현재 위칫값

사이의 보정 위치를 나타냅니다.

 

 

우선 m_vLookAt에서 m_vPrevLookAt을 뺍니다.

 

그 값을 vLookDir에 저장하여 벡터를 하나 구성합니다.

 

이를 Normalize 함수를 통해 정규화합니다. 

 

그러면 방향을 얻을 수 있죠.

 

즉 카메라의 이전 위칫값을 나타내는 m_vPrevLookAt에서

현재 위칫값을 나타내는 m_vLookAt으로의 방향을 얻는 겁니다.

 

그리고 500을 곱하여 속력을 설정해 줍니다. 

 

이후 매크로 fDT( Delta Time )을 곱하면

1초에 500만큼 이동하도록 설정할 수 있겠죠.

 

 

이 값과 m_vPrevLookAt을 더하여 

m_vCurLookAt에 대입합니다.

 

 

m_vDiff을 구할 때에는 이제 

현재 프레임의 카메라 위치는

m_vCurLookAt이므로  m_vCurLookAt에서

vCenter를 빼주어야겠죠?

 

 

프레임이 끝나면 m_vPrevLookAt에

m_vCurLookAt을 대입하여 이전 카메라의

위칫값을 갱신해 줍니다.

 

 

CalDiff 함수는 카메라 클래스의

update 함수에서 호출하고 있습니다.

 

즉 매 프레임마다 호출되며

vLookDir을 정규화하여 얻은 방향으로,

초당 500만큼 이동하는 속력으로,

이전 카메라 위치, 즉 m_vPrevLookAt가 갖고 있는 위칫값에서

현재 카메라 위치, 즉 m_vCurLookAt가 갖고 있는 위칫값으로

이동합니다.

 

그러다가

m_vLookAt에서 m_vPrevLookAt를 뺐을 때,

0에 가까워지면 카메라가 거의 멈추게 되겠죠.

 

근데 카메라가 완전히 멈추지는 않습니다.

 

왜냐하면 소수점 단위 계산이 딱 맞아

떨어지지 않기도 하고 Delta Time이 순간적으로

확 오른다거나 하면 목표 위칫값을 넘어가게 되겠죠.

 

그럼 카메라가 반대로 움직이며 목표 위칫값으로

이동하게 될테고 또 그 위칫값을 넘어 다시 반대로 움직여 

카메라가 작게 흔들리는 현상이 발생합니다.

 

 

이를 개선하려면 목표 위칫값에 도달했을 때

카메라 위칫값을 딱 설정해 주어 카메라를 

멈춰야 하는데 500의 속력으로 

목표 위칫값으로 이동하도록 구현하였으니

이는 불가능하다고 볼 수 있습니다.

 

애초에 도달하지 못하고 넘게 되면서 

발생하는 문제이기 때문이죠.

 

500의 속력으로 목표 위칫값으로

이동하도록 구현하기보다는

이전 카메라의 위칫값과

목표 카메라의 위칫값과 차이가 발생하면,

즉 카메라가 움직여야 하는 상황이면

몇 초안에 목표 위칫값으로 카메라가 

일정 비율로 움직이게 설정하는 것이 좋겠죠.

 

이렇게 하면 설정한 시간이 넘어갔을 때,

카메라 위칫값을 세팅하여 카메라가

더 이상 이동하지 않도록 해 주면 되겠죠. 

 

 


강의 출처 : https://www.youtube.com/watch?v=R45WWi8JLOg


'Win32 API > 기초' 카테고리의 다른 글

Win32 API 기초 : Camera (3)  (0) 2024.10.06
Win32 API 기초 : Camera (1)  (2) 2024.10.04
Win32 API 기초 : Animation (4)  (0) 2024.09.01
Win32 API 기초 : Animation (3)  (0) 2024.09.01
Win32 API 기초 : Animation (2)  (0) 2024.08.28