Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Using sf::Clock and std::this_thread::sleep_for to achieve X fps bad results  (Read 3885 times)

0 Members and 1 Guest are viewing this topic.

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Hello.
I am trying to achieve a system that will handle events at 100 fps while game will run on 1-60 fps.
The issues is that the outer loop is not accurate and i will post my math, pretty sure it sould be working any tips/help?

The logic i am using goes something like this
if DesiredLoopLastTime - LastLoopTime > 0
then pause for DesiredLoopLastTime - LastLoopTime
This produces 67 fps instead of 100  :(

Code: [Select]
//Time.cpp
void Time::LoopTime()
{
//Pause here to make last loop last 10ms or desired amount
int tmpTime = threadClock.getElapsedTime().asMilliseconds();
if(10 - tmpTime > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(10 - tmpTime));

dt = threadClock.restart().asMilliseconds();

if(isPaused)//Dont loop logic if paused
return;

//Thread
threadCounter++;
//Logic
logicAccumulated += dt;
if(logicAccumulated > logicRequired * 2)
logicAccumulated = logicRequired*2;
//Fps
fpsAccumulated += dt;
if(fpsAccumulated > fpsRequired)
{
fpsAccumulated -= fpsRequired;
//Update fps data
txtThread.setString("FPST:"+std::to_string(threadCounter));
threadCounter = 0;
txtLogic.setString("FPSL:"+std::to_string(logicCounter));
logicCounter = 0;
}
}

//Main.cpp
//The main while loop

while(objState.GetAppState() != en::AppState::APExit)
{
objTime.LoopTime();//Once per loop
if(objState.GetAppState() != en::AppState::APPause)
{
//objEvent.HandleEvents(objWin.Win, objState, objTime, en::EventHandleTypes::EHAll);//Once per loop //Of this type

while(objTime.logicAccumulated > objTime.logicRequired)//If logic update
{
objTime.logicAccumulated -= objTime.logicRequired;
objTime.LoopLogicTime();

objEvent.HandleEvents(objWin.Win, objState, objTime, en::EventHandleTypes::EHAll);//Once per loop //Of this type
objWin.Win.clear(sf::Color(0,0,0,255));

if(objState.GetGameState() == en::GameState::GSMainMenu)
{
objMenu.LoopMenu(objEvent, objState);
objMenu.DrawMenu(objWin.Win);
}
else if(objState.GetGameState() == en::GameState::GSGame)
{
objPlayer.LoopPlayer(objEntity, objEvent, objTime.logicRequired);
objMap.LoopMap(objEvent, objState);

objMap.DrawMap(objWin.Win);
objEntity.DrawEntity(objWin.Win);
objInventory.DrawInventory(objWin.Win);
}
else if(objState.GetGameState() == en::GameState::GSEditor)
{
objMap.LoopEditor(objEvent, objState);

objMap.DrawEditor(objWin.Win);
}
objTime.DrawTime(objWin.Win);
objEvent.ClearDataPerLoop();
}
}
else//App state == pause
{
objEvent.HandleEvents(objWin.Win, objState, objTime, en::EventHandleTypes::EHApp);//Once per loop //Of this type
}
objWin.Win.display();//Once per loop
}
This is Time and main while loop.
The inner FPS other called Logic fps is 60-61 but the Thread fps is not stable at all and varies from 60-100 and after 10-15 sec or app running it stops at ~67-70 and does not change.


EDIT::
Minimal example coming soon.
« Last Edit: December 25, 2013, 07:36:05 pm by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
First of all, the time per frame *will* vary depending on lots of things like; the work you do per frame, the resolution of your operating systems timers/scheduling frequency, other processes running on the machine, power-saving features of the hardware (like frequency scaling etc) and many other things. Never depend on timers or fps being stable or predictable.

Second; you may *want* 100fps, but is your hardware able to achieve that? What about other peoples machines? You simply can't make that kind of assumptions.

Third; read this: http://gafferongames.com/game-physics/fix-your-timestep/

EDIT: also take a look at the documentation for setVerticalSyncEnabled() and setFramerateLimit() .
« Last Edit: February 28, 2014, 08:02:24 pm by Jesper Juhl »