게임에서 TIme은 정말 중요한 요소중 하나인데 우리가 알고 있는 FPS가 1초당 그림을 몇번 그려지는 냐에 따라 움직임이 버벅리거나 부드럽게 움직여지는데 중요한건 각 컴퓨터의 성능 마다 프레임 처리 속도 즉 시간 측정이 달라지기 때문에 공통으로 사용 하는 시간 클래스를 하나 만들어서 사용 할 예정
좀더 간략 하게 애기하면 A라는 컴퓨터는 1초당 3000 FPS 그려지는 속도를 가지는 성능 B라는 컴퓨터는 1초당 1000 FPS 가진다면 A와 B의 시간차이가 나기 때문에 같은 속도를 가진 캐릭터를 움직이여도 A라는 컴퓨터가 더 빠르게 움직이기 때문에 사용 하는 클래스
Time 클래스를 보면 QueryPerformanceCounter() 함수가 있는데 주파수 통해서 시간을 구해오는 기능 이라는것만 알아두면 된다.
1. Time.h
1.중요한 부분은 ☆ 부분친 것이 주로 많이 사용하는 핵심이다.
2. Timer 클래스도 있는데 아직은 사용 안하는 클래스
#pragma once
class Time
{
public:
static Time* Get();
static void Create();
static void Delete();
static bool Stopped() { return isTimerStopped; }
static float Delta() { return isTimerStopped ? 0.0f : timeElapsed; } //공통(공용) 시간 ☆
void Update();
void Print();
void Start();
void Stop();
float FPS() const { return framePerSecond; }
float Running() const { return runningTime; }
private:
Time(void);
~Time(void);
static Time* instance; //< 싱글톤 객체
static bool isTimerStopped; //< 타이머 중지
static float timeElapsed; //< 이전 프레임으로부터 경과시간 (현재 시간과 이전 시간의 차이) ☆
INT64 ticksPerSecond; //< 초당 틱카운트
INT64 currentTime; //< 현재 시간 ☆
INT64 lastTime; //< 이전시간 ☆
INT64 lastFPSUpdate; //< 마지막 FPS 업데이트 시간
INT64 fpsUpdateInterval; //< fps 업데이트 간격
UINT frameCount; //< 프레임 수
float runningTime; //< 진행 시간
float framePerSecond; //< FPS
};
// Time 클래스에 같이 선언한 클래스
class Timer
{
public:
Timer();
~Timer();
void Start(function<void()> func, int milliSec, UINT repeat = 0);
void Stop();
private:
mutex m;
bool bComplete;
UINT count;
};
2. Time.cpp
1. QueryPerformanceCounter() 기능을 통해서 시간값을 계산
2. Update()문 에서 진행시간 & FPS 시간값 구하고 있다.
#include "stdafx.h"
#include "Time.h"
Time* Time::instance = NULL;
bool Time::isTimerStopped = true;
float Time::timeElapsed = 0.0f;
Time::Time(void) :
ticksPerSecond(0), currentTime(0), lastTime(0), lastFPSUpdate(0), fpsUpdateInterval(0),
frameCount(0), runningTime(0), framePerSecond(0)
{
//QueryPerformanceFrequency cpu의 주파수 통해서 시간을 계산
QueryPerformanceFrequency((LARGE_INTEGER *)&ticksPerSecond);
fpsUpdateInterval = ticksPerSecond >> 1;
/*TwBar* bar = TweakBar::Get()->GetBar();
TwAddVarRO(bar, "Time", TW_TYPE_FLOAT, &framePerSecond, "");*/
}
Time::~Time(void)
{
}
Time* Time::Get()
{
assert(instance != NULL);
return instance;
}
void Time::Create()
{
assert(instance == NULL);
instance = new Time();
}
void Time::Delete()
{
SAFE_DELETE(instance);
}
//☆ 핵심 ☆
void Time::Update()
{
if (isTimerStopped) return;
//1. 현재시간을 가져와 시간 간격 및 진행 시간을 계산한다.
QueryPerformanceCounter((LARGE_INTEGER *)¤tTime);
timeElapsed = (float)(currentTime - lastTime) / (float)ticksPerSecond;
runningTime += timeElapsed;
//2. FPS Update
frameCount++;
if (currentTime - lastFPSUpdate >= fpsUpdateInterval)
{
float tempCurrentTime = (float)currentTime / (float)ticksPerSecond;
float tempLastTime = (float)lastFPSUpdate / (float)ticksPerSecond;
framePerSecond = (float)frameCount / (tempCurrentTime - tempLastTime);
lastFPSUpdate = (INT64)currentTime;
frameCount = 0;
}
lastTime = currentTime;
}
void Time::Print(){}
void Time::Start()
{
if (!isTimerStopped)
assert(false);
QueryPerformanceCounter((LARGE_INTEGER *)&lastTime);
isTimerStopped = false;
}
void Time::Stop()
{
if (isTimerStopped)
assert(false);
INT64 stopTime = 0;
QueryPerformanceCounter((LARGE_INTEGER *)&stopTime);
runningTime += (float)(stopTime - lastTime) / (float)ticksPerSecond;
isTimerStopped = true;
}
///////////////////////////////////////////////////////////////////////////////
Timer::Timer()
{
bComplete = false;
count = 0;
}
Timer::~Timer(){}
void Timer::Start(function<void()> func, int milliSec, UINT repeat)
{
assert(bComplete == false);
bComplete = false;
thread t([=]()
{
while (true)
{
if (repeat > 0 && count == repeat)
break;
if (bComplete == true)
break;
count++;
Sleep(milliSec);
if (bComplete == true)
break;
func();
}
Stop();
});
t.detach();
}
void Timer::Stop()
{
count = 0;
bComplete = true;
}
3. 수정
stdafx.h
Time 클래스를 사용 할 수있게 미리 컴파일러 헤더에 필요한 부분을 선언
#include <mutex> // thread 임계구역 구별용 (Time)
#include "System/Time.h"
#define SAFE_DELETE(p) { if(p) { delete (p); (p) = nullptr; } }
Device.cpp -> Running()
ImGui 생성및 사용 방법으로 값을 셋팅
WPARAM Running()
{
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
// 싱글톤
ImGui::Create(Hwnd, Device, DeviceContext);
ImGui::StyleColorsDark(); //테마 (안해도됨)
//System
Key = new Keyboard();
Time::Create();
Time::Get()->Start();
InitScene();
while (true)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) //종료
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Time::Get()->Update();
ImGui::Update();
Update();
Render();
}
}
DestroyScene();
Time::Delete();
SafeDelete(Key);
ImGui::Delete();
return msg.wParam;
}
4. 확인
Scene.cpp -> Update()
Update() 함수 안에 해당 코드 작성후 실행 하면 ImGui로 확인 해보면 0.1초씩 증가 및 FPS 값도 측정
//FPS
ImGui::Text("%.1f", ImGui::GetIO().Framerate);
ImGui::Text("FPS : %.1f", Time::Get()->FPS());
ImGui::Text("Running Time : %.1f", Time::Get()->Running());
https://github.com/ascher8159/DX2D
DX2D_12 Time
'DirectX > DirectX 2D' 카테고리의 다른 글
DX2D_14 Texture (Sampler state, Blend State) (0) | 2023.03.22 |
---|---|
DX2D_13 Rect_Control (1) | 2022.12.24 |
DX2D_11 Rect_Control (상속, 다형성) (0) | 2022.12.14 |
DX2D_10 Rect (0) | 2022.12.07 |
DX2D_9 WVP2 (1) | 2022.12.04 |