我想计算帧率,并将其限制为60,但是我通过谷歌查找了一些代码,完全看不懂。
我想计算帧率,并将其限制为60,但是我通过谷歌查找了一些代码,完全看不懂。
Delta time是最终时间减去原始时间的差值。
dt= t-t0
f(x + h) - f(x)
f'(x) = lim -----------------
h->0 h
http://mathworld.wolfram.com/Derivative.html
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"winmm.lib")
void gotoxy(int x, int y);
void StepSimulation(float dt);
int main(){
int NewTime = 0;
int OldTime = 0;
float dt = 0;
float TotalTime = 0;
int FrameCounter = 0;
int RENDER_FRAME_COUNT = 60;
while(true){
NewTime = timeGetTime();
dt = (float) (NewTime - OldTime)/1000; //delta time
OldTime = NewTime;
if (dt > (0.016f)) dt = (0.016f); //delta time
if (dt < 0.001f) dt = 0.001f;
TotalTime += dt;
if(TotalTime > 1.1f){
TotalTime=0;
StepSimulation(dt);
}
if(FrameCounter >= RENDER_FRAME_COUNT){
// draw stuff
//Render();
gotoxy(1,2);
printf(" \n");
printf("OldTime = %d \n",OldTime);
printf("NewTime = %d \n",NewTime);
printf("dt = %f \n",dt);
printf("TotalTime = %f \n",TotalTime);
printf("FrameCounter = %d fps\n",FrameCounter);
printf(" \n");
FrameCounter = 0;
}
else{
gotoxy(22,7);
printf("%d ",FrameCounter);
FrameCounter++;
}
}
return 0;
}
void gotoxy(int x, int y){
COORD coord;
coord.X = x; coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
return;
}
void StepSimulation(float dt){
// calculate stuff
//vVelocity += Ae * dt;
}
您不应该尝试限制fps。唯一的原因是,如果您没有使用delta时间并且希望每个帧具有相同的长度。即使是最简单的游戏也无法保证这一点。
但是,您可以将delta时间切成固定大小,然后保留剩余部分。
这是我最近编写的一些代码。它没有经过彻底测试。
void GameLoop::Run()
{
m_Timer.Reset();
while(!m_Finished())
{
Time delta = m_Timer.GetDelta();
Time frameTime(0);
unsigned int loopCount = 0;
while (delta > m_TickTime && loopCount < m_MaxLoops)
{
m_SingTick();
delta -= m_TickTime;
frameTime += m_TickTime;
++loopCount;
}
m_Independent(frameTime);
// add an exception flag later.
// This is if the game hangs
if(loopCount >= m_MaxLoops)
{
delta %= m_TickTime;
}
m_Render(delta);
m_Timer.Unused(delta);
}
}
有很多好的理由,为什么你不应该以这种方式限制你的帧率。其中一个原因是,正如Stijn所指出的那样,不是每个显示器都能以恰好60fps运行,另一个原因是计时器的分辨率不足,还有一个原因是即使给定足够的分辨率,两个独立的计时器(监视器刷新和你的)并行运行将始终因随机不准确性而失去同步时间(它们必须!),最重要的原因是根本没有必要。
请注意,在Windows下,默认计时器分辨率为15ms,您可以通过使用timeBeginPeriod获得的最佳分辨率为1ms。因此,您最多可以等待16ms或17ms。在60fps下的一个帧是16.6666ms,你怎么等待16.6666ms呢?
如果你想将游戏速度限制在显示器的刷新率上,请启用垂直同步。这将精确地做到你想要的,而且没有同步问题。垂直同步也有其特殊性(例如当一帧需要16.67ms时,你会得到有趣的惊喜),但它是目前最好的解决方案。
如果你想这么做的原因是为了将你的模拟适应渲染循环,那么this对你来说是必读的。看看这个:
//Creating Digital Watch in C++
#include<iostream>
#include<Windows.h>
using namespace std;
struct time{
int hr,min,sec;
};
int main()
{
time a;
a.hr = 0;
a.min = 0;
a.sec = 0;
for(int i = 0; i<24; i++)
{
if(a.hr == 23)
{
a.hr = 0;
}
for(int j = 0; j<60; j++)
{
if(a.min == 59)
{
a.min = 0;
}
for(int k = 0; k<60; k++)
{
if(a.sec == 59)
{
a.sec = 0;
}
cout<<a.hr<<" : "<<a.min<<" : "<<a.sec<<endl;
a.sec++;
Sleep(1000);
system("Cls");
}
a.min++;
}
a.hr++;
}
}