본문 바로가기
Develop/Win32 API와 게임 엔진

[개발] 공부하며 정리한 "Delta Time"

by Tarra 2023. 10. 24.

개인 공부 후 자료를 남겨놓기 위한 목적이므로,
생략되거나 오류가 있을 수 있음을 알립니다.

잘못된 부분이 있다면 댓글로 상냥하게 가르쳐주시면 감사하겠습니다!

 

 

"Delta Time"이란 프레임 간의 시간 간격을 의미한다. (1프레임당 시간)

이를 구현하지 않는다면, 다양한 환경에서 프로그램은 일정한 속도로 실행될 수 없다.

 

TimeMgr를 이용하여 Delta Time을 구현해보고,

이를 이용하여 오브젝트가 어느 환경에서든 일정한 속도로 움직일 수 있도록 구현해보자.

 

 

보며 공부한 곳! // 어소트락 아카데미 Win32 API 무료강의

https://youtu.be/dlFr-OnHlWU?si=K8UpK8CwSOddqFZ5


델타 타임 구현, 즉 시간 동기화를 위한 매니저인 TimeMgr 클래스를 만들어보자.

 

일단 해당 매니저도 프로그램내에서 단 하나만의 객체를 가지고 작동해야하므로, 이전과 동일하게 싱글톤을 이용하여 

 

구현해주도록 하자.

 

 

구현을 하기전에 어떻게 시간을 측정할 것인지 생각해보자.

 

다행스럽게도 Win32 api에서는 현재 시간을 측정하는 함수와, 초당 몇번 카운트가 발생하는지를 알려주는 함수가 존재한다.

 

 

QueryPerformanceCounter()

시간 측정용 함수로 64비트 정수로 시간을 저장한다. 반환 값은 LARGE_INTEGER

 

QueryPerformanceFrequency()

QueryPerformanceCounter의 주파수를 반환해준다. 이 또한 LARGE_INTEGER로 값을 반환해준다.

 

이를 이용하여 현재 불러오는 카운터 값을 m_llCurCount, 이전 루프에서 불러오는 카운터 값을 m_llPrevCount

그리고 매초 불러오는 초당 카운트 횟수를 m_llFrequency로 명명하자.

 

Win32 api에서 프레임 값의 시간 간격인 델타 타임을 구현하기 위한 모든 것을 알려주었다.

 

우리는 현재 값인 m_llCurCount에서 m_llPrevCount를 뺀 뒤, 이것을 주파수인 m_llFrequency로 나눠주게 되면

시간 간격을 알 수 있게 된다.

 

 

델타 타임을 m_dDT로 선언하고 이를 코드상에서 구현해보자.

 

사용하는 멤버 변수와 함수를 선언해주자.

 

프로그램이 실행되고 Core가 각 매니저들을 초기화하는 과정에서 init()을 호출하게 되고 자연스럽게 초기 값이 세팅이 될 것이다.

init() 구현

 

Core::init()

 

초기 값을 세팅해주었으니 이제 매 루프마다 호출되는 CTimeMgr::update()를 구현해보자.

 

위와 같은 코드를 이용하여 델타 타임인 m_dDT를 구할 수 있게 된다.

 

~.QuadPart는 무엇인가요?

QueryPerformanceCount의 반환 값인 구조체 LARGE_INTEGER는 다음과 같이 정의되어 있다.

여기서 
"LowPart" 는 32비트 정수로, 값의 낮은 32비트를 저장한다.
"HighPart" 는 32비트 정수로, 값의 높은 32비트를 저장한다.
"QuadPart" 는 64비트 정수로, 값의 전체 64비트를 저장한다.

따라서 우리는 타이머의 전체 값을 필요로 하기 때문에 QuadPart를 불러와 사용하면 된다.

 

이제 매 호출시마다 m_dDT를 계산하고, 실시간으로 반영하고 있으므로 이를 사용하기 위해 반환함수 GetDT를 구현한 뒤

직접 사용해보자.

 

두가지 타입의 GetDT()를 구현해주었다.

값을 얻어올 수 있는 함수를 구현했으므로 이제 화면에 사각형을 그리는 CCore::render()로 돌아오자.

 

이전의 render()는 다음과 같이 구현되어 있어 초당 어느 정도로 사각형이 움직이는지 파악하기 어려웠다.

 

이전의 CCore::render()

 

이제는 델타 타임을 이용하여 초당 100.f의 속도로 이동하도록 구현할 수 있게 되었다.

 

 

이전의 이동속도와 현재의 이동속도를 비교해보도록 하자.

 

델타 타임을 적용하기 전

 

델타 타임을 적용한 후. 초당 100.f의 이동속도를 가지게 되었다.

 

 

지금까지 엔진에서 가장 기본인 "Singleton", "Manager", "Double Buffering", "Delta Time"에 대해서 알아보았다.

 

이후에는 유용한 빌드 방식인 "unity build"나 싱글톤 이외의 여러 디자인 패턴에 대해 알아보도록 하자.