I've been making my game's core for the past week and I hit a wall because rendering was simply not good enough. Movement was jerky, I was getting tearing and there was a lot of lag in general. I thought that it may not be my game engine's fault so I tested rendering with a very simple gameloop:
sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");
window.setVerticalSyncEnabled(true);
sf::Clock clock;
sf::Event event;
float elapsed;
while(window.isOpen())
{
elapsed += clock.restart().asSeconds();
std::cout << 1.f/elapsed << std::endl;
while(elapsed > 1.f/60.f)
{
while(window.pollEvent(event))
{
if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape)
{
window.close();
}
}
elapsed -= 1.f/60.f;
}
window.clear();
window.display();
}
The fps starts at 40 , goes up to 60 and then falls back to 30, it increments again and repeats. If I set VSynct to false, I get anywhere between 30-500 fps. Either I am not testing the frame rate correctly or there is something wrong with my nvidia drivers (I did reinstall them 2 times with no changes). Any help is appreciated!
You pointed me to a material which has similar code to yours, but you wrote it differently.
From: gameprogrammingpatterns.com/game-loop.html
double previous = getCurrentTime();
double lag = 0.0;
while (true)
{
double current = getCurrentTime();
double elapsed = current - previous;
previous = current;
lag += elapsed;
processInput();
while (lag >= MS_PER_UPDATE)
{
update();
lag -= MS_PER_UPDATE;
}
render();
}
You seem to be using one variable elapsed
for both, elapsed
and lag
. That is what was baffling me. Your mangling with elapsed
makes it unusable for the purpose measuring time. I think your code should look more like:
sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");
window.setVerticalSyncEnabled(true);
sf::Clock clock;
sf::Event event;
float lag;
float elapsed;
while(window.isOpen())
{
lag = elapsed = clock.restart().asSeconds();
std::cout << 1.f/elapsed << std::endl;
while(lag > 1.f/60.f)
{
while(window.pollEvent(event))
{
if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape)
{
window.close();
}
}
lag -= 1.f/60.f;
}
window.clear();
window.display();
}
I am still not sure if this will be correct. I don't know what clock.restart().asSeconds()
does exactly. Personally, I would implement it line by line like the example. Why redesign working code?
Edit: OP confirmed that, using elapsed
for "throttling" was breaking its purpose as time a measurement variable.