C++ 게임 루프 구현: QueryPerformanceCounter로 고정 프레임 엔진 루프 만들기

🚀 들어가며

이전 글에서는 게임 루프의 기본 개념과
deltaTime이 왜 필요한지 살펴봤습니다.

👉 게임은 반복되는 루프를 통해 계속 실행된다

이번 글에서는 한 단계 더 나아가
👉 C++로 실제 동작하는 게임 루프를 구현해보겠습니다.


🎯 이번 글의 목표

이번 글에서는 다음을 구현합니다:

  • 고정 프레임(Fixed Timestep)
  • deltaTime 계산
  • FPS 제어
  • Busy wait 방식

🔥 단순한 게임 루프의 문제

가장 기본적인 게임 루프는 다음과 같습니다.

while (true)
{
    Tick();
    Draw();
}

하지만 이 구조는 문제가 있습니다.

  • CPU를 최대 속도로 사용
  • 프레임 속도 제어 불가능
  • 실행 환경마다 결과가 달라짐

👉 해결 방법은 하나입니다.

프레임 시간을 일정하게 유지한다


🎯 고정 프레임 개념

예를 들어 60FPS를 목표로 한다면:

1 프레임 ≒ 0.01666초 (약 16.6ms)

👉 즉, 한 프레임은 최소 16ms 이상 걸려야 합니다.


🧠 구현 아이디어

게임 루프는 다음 흐름으로 구성됩니다.

현재 시간 측정
→ deltaTime 계산
→ 일정 시간 이상 경과했는지 확인
→ Tick / Draw 수행

🔧 C++ 게임 루프 구현 (QueryPerformanceCounter)

#include <windows.h>

void GameLoop()
{
    LARGE_INTEGER frequency;
    QueryPerformanceFrequency(&frequency);

    LARGE_INTEGER counter;
    QueryPerformanceCounter(&counter);

    int64_t previousTime = counter.QuadPart;

    const float targetFrameTime = 1.0f / 60.0f;

    while (true)
    {
        QueryPerformanceCounter(&counter);
        int64_t currentTime = counter.QuadPart;

        float deltaTime = static_cast<float>(currentTime - previousTime)
            / static_cast<float>(frequency.QuadPart);

        if (deltaTime >= targetFrameTime)
        {
            Tick(deltaTime);
            Draw();

            previousTime = currentTime;
        }
    }
}

🔍 코드 핵심 설명

✔ QueryPerformanceCounter

QueryPerformanceCounter(&counter);

👉 현재 시간을 고해상도로 측정합니다.


✔ deltaTime 계산

(currentTime - previousTime) / frequency

👉 이전 프레임과 현재 프레임 사이의 시간


✔ 고정 프레임 조건

if (deltaTime >= targetFrameTime)

👉 목표 프레임 시간이 지났을 때만 Update 실행


🧭 deltaTime 흐름 다시 보기

previousTime ───────────── currentTime
     │                          │
     └──── 시간 차이 계산 ───────┘

deltaTime = (currentTime - previousTime) / frequency

⚠️ 이 방식은 Busy wait인가?

이 루프는 계속 반복하면서 시간을 체크합니다.

while (true)
{
    QueryPerformanceCounter(...)
}

👉 즉:

CPU가 계속 시간을 확인하면서 기다리는 방식


🎯 장점

  • 구현이 매우 단순
  • 흐름 이해가 쉬움
  • 타이밍 정확도 높음

⚠️ 단점

  • CPU 사용률 높음
  • 대기 중에도 루프 계속 실행

👉 그래서 실제 엔진에서는 더 다양한 방식이 사용됩니다


🧩 실제 엔진에서는?

실제 게임 엔진에서는 다음과 같은 요소가 추가됩니다.

  • 입력 처리
  • 물리 업데이트
  • 충돌 처리
  • 렌더링 파이프라인
  • 오브젝트 관리

👉 즉, 지금 구조는 다음 단계의 기반입니다.


🔥 핵심 정리

  • QueryPerformanceCounter로 시간을 측정한다
  • deltaTime으로 시간 차이를 계산한다
  • 고정 프레임으로 FPS를 제어한다
  • Busy wait 방식으로 간단하게 구현할 수 있다

🎯 다음 글 예고

다음 글에서는:

👉 게임 루프 방식 비교

  • Fixed timestep
  • Variable timestep
  • Sleep vs Busy wait
  • Hybrid 구조

👉 실제 엔진에서 어떤 방식이 사용되는지 살펴보겠습니다.


🎮 마무리

이번 글에서 구현한 구조는 단순한 예제가 아니라
👉 게임 엔진의 가장 기본적인 실행 흐름입니다.


👍 한 줄 정리

👉 “이 글은 게임 루프를 직접 구현해보는 첫 번째 실전 단계입니다”


🚀 한 단계 더 나아가고 싶다면

게임 루프를 이해하는 것은 엔진 구조를 이해하는 출발점입니다.
이 구조를 단순히 개념으로 아는 것과 직접 구현해보는 것은 큰 차이가 있습니다.
엔진을 직접 만들어보는 과정에서 이 개념들이 어떻게 연결되는지 확인하고 싶으시다면
아래 강의도 참고해보셔도 좋습니다.

👉 강의 링크: C++로 만드는 게임 엔진 프레임워크 (소코반과 슈팅 게임으로 배우는 엔진 구조)

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Please turn AdBlock off

Notice for AdBlock users

Please turn AdBlock off