WinAPI 10 Timer (1)

CJB_ny·2022년 8월 29일
0

WinAPI

목록 보기
10/79
post-thumbnail

컴퓨터의 속도가 엄청나게 빠르다는 점을 간과했다.

초당 4만 픽셀로 움직일 것이다.

컴퓨터 성능이 좋은 사람은 더 빨리 움직이고

컴퓨터 성능이 조금 안 좋으면 느리게 움직일 것이다.

일단 이게 '정수'값이면 안된다.

우리 회면은 잘게 쪼개진 '픽셀'인데

0.1픽셀이라는 것은 없다.

픽셀이 정확하게 딱 '정수'로 나누어 떨어진다.

우리가 실수로 계산을 하더라도 렌더링 할때는 정수로 캐스팅해서 가져갈 것이다.

내부적으로는 실수로 가지고 있는 것이 좋다.

그래서 POINT구조체를 사용한하고 float를 가지는 구조체를 직접 만들 것이다.

이렇게 해더 만들고

이런 함수들 추가 해주도록 하자.

이후 CCore 에서 Init부분수정을 해야하는데

지금 Vector2의 생성자 중에 인자를 두개를 받는 생성자를 만들어 주지 않았다.

이거 수정 ㄱㄱ.

굿.

우리가 내부 데이터는 실수로 사용할 것인지만 윈도우 '픽셀 단위'는 정수이기 때문에

정수로 초기화 하는 경우도 만든다.

굿.

render부분에서는

Rectangle 함수가 정수를 요구하기 때문에 계산은 실수로하고 정수형으로 형변환 해주자.

에러 ❗

현재 이부분이 문제인데

분명히 Vector2의 생성자 다 파줌. 정수버젼, 실수 버젼

머임??

지금 나눗셈의 결과값이 인자로 들어가는 경우라서 문제가 발생함.

왜?? =>


시간 동기화 ❗

지금 실행은 잘되는데

이게 단순이 단위를 작게 해서 눈에 보일 뿐이지

지금 컴퓨터 성능이 좋으면 빠르게 움직일 것이다.

그래서 컴퓨터의 속도와 우리 현실시간을 맞춰 주어야한다.

실제 현실시간 기준 1초 기준으로 초당 100픽셀 이동한다는 개념이 틀어지면 안된다.

그래서

지금 한 프레임 실행될 때 이 '움직이는 양'이

'고정값'이여서는 안된다.

컴퓨터 성능 속도에 따라서 가변적으로 움직여야, 그렇게 했을 때, 누적된 양이
초당 100정도를 움직일 것이다! 라는 양만큼 움직여야 한다.

그래서 빠른 컴퓨터는 훨씬 적게

느린 컴퓨터는 움직이는 단위가 큼직큼직하게 해서 결과적으로 같은 이동시간동안

같은 이동량이 나와야한다.

(잔상은 남겨두겠다)

시간

100이라는 거리를 1초안에 갈 것이다.

근데 우리 프로그램은 계소해서 여러번 나누어서 실행하고있다.

컴퓨타가 만약에 100프레임이라고 가정을 하자.


frame

https://velog.io/@starkshn/WinAPI32-PeekMessage-1

초당 렌더링 횟수를 '프레임'이라 한다.


그러면 컴퓨터 프레임이 100이라 하면 100프레임 이라는 것은 1초에 100번 수행된다는 것이다.

매순간마다 얼만큼 이동시켜야 1초에 100을 이동시킬 수 있을 까?

=> 1씩 이동한다.

만약 성능이 더 좋은 컴퓨터는 프레임이 1초에 200씩 나온다고 가정하자.

한번에 얼마씩 이동 시켜야 1초에 100을 움직일 수 있나?

어떻게 계산했나??

내가 가고싶은 '이동량'을 '프레임'으로 나눔.

바꿔말하면 내가 초당 가고싶은 이동량을 프레임수로 쪼개서 분할해서 이동을 시키면
이번 프레임에 이동한 '양'이 나온다.

100프레임일때는 1번 프레임이 1씩 움직이고

200프레임일 경우는 1번 프레임이 0.5씩 움직여야 200번프레임 까지 실행되면

100을 이동함.

( 이동거리를 프레임수로 나눔. )

이게 누적이 되어야 1초 뒤에 100이라는 이동량이 나온다.

프레임을 역수치? 한 것이다.

이것의

의미는?

1초에 두번 수행되는 컴퓨터

0.5는 무슨말? => 1프레임당 걸리는 실제 '시간'

1초에 10프레임 도는 컴퓨터 => 1/10 => 0.1초는 한 프레임 수행하는데 걸리는 시간이다.

그러면 1초당 200프레임은 => 한프레임에 실행되는 시간이 0.005초이다.

1/200초 => 5/1000초 => 0.005초

[ 질 문 ]
100을 1초에 움직이고 싶다.

컴퓨터는 200프레임이다.(1초당)

100 * 1/200 은 무슨말이냐?

컴퓨터가 한 프레임에 걸리는 시간값을 곱하겠다.

"니가 100을 이동하고싶어? 그러면 100 * 1/200초만큼 이동을 하겠다. 한프레임에"

이게 200번 누적되서 100이 된다.

CTimeManager

여기서 그래서 한 프레임당의 시간을 구할 수만 있다면

(프레임도 구하고)

내가 이동하고 싶은 양은

100을 이동하고싶다면 => 초당 100의 속도를 가지고 싶어, (시간 동기화)

초당 100의 속도에다가 DeltaTime(한프레임당 걸리는 시간) 곱하면 된다.

그러면 이게 결과적으로 값이 누적이 되서 1초뒤에 100을 이동했을 것이다.

pos.x += 100 * DeltaTime 하니까

100 * 1/10을 계속 += 더하니까

10 + 10 + 10 ... + 10 => 100될 것이다.

그러면 짧게 눌렀다가 때면은?

프로그램은 초당으로 돌아가니까 10 + 10 => 20만큼 이동하겠지..??

컴퓨터 속도가 들쭉날쭉해서 이동량이 달라질 수 있다.

운도우 백그라운드 프로그램 돌아거서 느려진다거나 그럴때

그래서 DeltaTime은 TimeManager에 의해서 계속 계산되어야한다.

GetTickCount

말고 훨씬더 미세한 카운트를 셀 수 있는 함수가 필요하다.

QueryPerformanceCount();

초당 세는 단위가 100만이다.

대충 이따위로 설계

getTickCount는 1초에 고정값이 있다. 1초가 벌어지면 카운트가 1000이 차이가 난다.

QueryPerformanceCount애는 1초가 벌어졌을 때 카운트 차이가 얼마가 나는지도 구해와야한다.

이 함수로 구한다.

'빈번도' 얼마나 자주인지 즉, 1초당 카운트가 얼마나 발생하는지에 대한 frequency값을 얻겠다.

그래서 초당 카운트도 직접 넣어주어야 한다.

이렇게 하고 실행하면 초기화 되었을 때 초당 카운트 나올 것이다.

나의 실수

#define SINGLE(type) public : static type* GetInstance() { static type mgr; return &mgr; } private : type(); ~type();

이렇게 매크로로 생성자랑 소멸자 선언해놓고

CCore 생성자, 소멸자 안 만들고 있었다.

그러니까 링크 오류뜨지...

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글