[WinAPI] update구현

jh Seo·2024년 1월 30일
0

winapi공부

목록 보기
5/6

SetTimer함수를 통한 구현

WinAPI에서

//  함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  용도: 주 창의 메시지를 처리합니다.
//
//  WM_COMMAND  - 애플리케이션 메뉴를 처리합니다.
//  WM_PAINT    - 주 창을 그립니다.
//  WM_DESTROY  - 종료 메시지를 게시하고 반환합니다.

WndProc을 통해 메시지를 처리한다.

여기서 SetTimer함수를 통해 특정함수를 일정 주기마다 호출하는 방법을 사용할 수 있다.
이 함수를 통해 유니티의 FixedUpdate()와 비슷하게 일정 시간 마다 호출하는 부분을 구현해보려고한다.

SetTimer함수

SetTimer(hwnd,             // handle to main window 
    IDT_TIMER1,            // timer identifier 
    10000,                 // 10-second interval 
    (TIMERPROC) NULL);     // no timer callback 
  • 첫번째 인자는 window의 handle이다.

  • 두번째 인자는 해당 타이머의 이름

  • 세번째 인자는 1ms단위로 10000ms는 10초다.

  • 네번째 인자는 콜백함수이다.
    null값을 설정하면 WndProc함수의 case WM_TIMER:에 전달 되고,
    특정함수를 설정하면 해당 함수에서 WM_TIMER을 처리한다.

식별자가 있어 여러개의 타이머를 동시에 세팅할 수 있다.

SetTimer(hwnd, 1, 10, NULL);
SetTimer(hwnd, 2, 100 ,NULL);

이렇게 1번 2번 타이머를 세팅해줬다면

 case WM_TIMER:
  switch (wParam)
  {
  case 1: //1번 타이머의 메시지
   MessageBox(hwnd, L"1실행", L"1번타이머", NULL);
   break;
  case 2: //2번 타이머의 메시지
   MessageBox(hwnd, L"2실행", L"2번타이머", NULL);
   break;
  }
  break;

이런식으로 wParam의 값을 통해 몇번 타이머인지 알아낼수 있다.

구현

case WM_CREATE:                         // 프로그램이 실행 될 때 한 번 호출된다.
	SetTimer(hWnd, 1, 10, NULL);
	break;

위와 같이 WM_CREATE에서 식별자가 1이고, 주기가 10ms인 타이머를 호출해준다.

	case WM_TIMER:                         
		if(pMainGame)
		pMainGame->Update();
		break;

콜백함수가 NULL이므로 case WM_TIMER: 에서 처리해야한다.
여기서 메인게임의 Update를 호출함으로 10ms마다 주기적으로 호출해줬다.

PeekMessage함수를 통한 구현

기본적으로 wWinMain함수에는 MSG msg 이런식으로 메시지 변수를 선언한 후,
GetMessage함수를 통해 메시지를 읽어온다.

단점은 메시지큐가 비어있다면 무한 대기에 빠진다.

따라서 PeekMessage함수를 통해 block되지않고 큐 확인만 한 후,
나머지 처리 (예: update함수나 render함수) 를 해준다.

    MSG msg;

    // 기본 메시지 루프입니다:
        while (true)
        {
            if(PeekMessage(&msg,nullptr,0,0,PM_REMOVE))
            {
                if (msg.message == WM_QUIT)
                    break;
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        	else
        	{
            	if (pMainGame) {
                	pMainGame->Update();
                	pMainGame->Render();
            	}
        	}
        }

이런식으로 if문을 통해 message큐 처리만 해준 후, else로 빠져나와 함수처리를 해준다.
이런 방식으로 짜면 위 SetTimer방식보다 훨씬 더 많이 CPU를 사용할 수 있다.
함수호출도 훨씬 많아진다.

단점은 컴퓨터마다 성능이 달라 프레임이 달라지므로 이전에 작성한
QPC(QueryPerformanceCounter)를 통한 deltatime 을 이용해야한다!

profile
코딩 창고!

0개의 댓글