-
Hello,
so I seem to be experiencing a rather dramatic FPS drop based on the period of time my game has been running for.
(Useful Info):
Using: SFML 2.4.2 with C++ in Visual Studio 2015.
Graphics Card: nVidia 960M
I've stripped my game loop down to just doing a basic
while (m_rWindow.isOpen())
{
Event evnt; //Make an sfml event
while (m_rWindow.pollEvent(evnt))//Get all the events that have occurred
{
if (evnt.type == Event::Closed)
{
m_rWindow.close();
}
if (evnt.type == Event::LostFocus)
{
hasFocus = false;
}
if (evnt.type == Event::GainedFocus)
{
hasFocus = true;
}
if (evnt.type == Event::KeyReleased)
{
if (evnt.key.code == Keyboard::Escape)
{
m_rWindow.close();
}
}
}
++frames;
thisTime = elapsed.getElapsedTime();
setFPSText(lastTime, thisTime, frames);
m_rWindow.clear();
m_rWindow.draw(m_fpsText);
m_rWindow.display();
}
All the loop does now is draw the fps to the screen and display this value. I disabled all rendering and updating of the game to find the cause of my present problem. Through some testing I managed to find:
When the game is initially run on my PC with just this loop (no VSync enabled, and no frame rate limit function call) I achieve 1.7 ms/frame (568 fps). But after a period of maybe 2-3 minutes I can end up at a value of 10 ms/frame (97 fps). This drastic change when I do have the fps capped to 60 and my game running takes me from an average of 16 ms/frame to 32 ms/frame.
There only a black screen with an FPS counter at the top right of the game window. I've profiled the executable a few times and timed the m_renderWindow.clear() to .display() and had variations from 11ms to 110ms when rendering my own game, but then had 6ms - 90ms when only rendering text (with a 60 fps cap on).
(Sorry for the information overload!)
-
Sounds more like an accumulation of calculating the FPS wrong. Can you show your FPS calculation?
-
Yeah sure, here's my fps calculation:
void Game::setFPSText(Time& lastTime, const Time& currentTime, Int32& frames)
{
const float TIME_GAP = 0.1f;
if ((currentTime - lastTime).asSeconds() >= TIME_GAP)
{
float msPerFrame = 1000.0f / float(frames);
m_fpsText.setString(std::to_string(msPerFrame) + " ms/frame\n " + "FPS: " +
std::to_string((Int32)(1.0f / (msPerFrame / 1000.0f))));
frames = 0;
lastTime += Time(seconds(1.0));
}
}
The thing is the game does begin to run slower, I can see things jittering on the screen
-
lastTime += Time(seconds(1.0));
Should be
lastTime = currentTime;
Because the difference will never be exactly 1.0.
-
Using that I still get the same FPS drop during runtime. I'm going to try just running a window not initialising my own game and just run a renderwindow with some text displaying ms/frame and FPS
-
Btw, you can always just determine a simple FPS by restarting a clock and taking the inverse.
auto dt = clock.restart();
auto fps = 1.f / dt.asSeconds();
So you can at least use this to verify your implementation.
-
Btw, you can always just determine a simple FPS by restarting a clock and taking the inverse.
auto dt = clock.restart();
auto fps = 1.f / dt.asSeconds();
So you can at least use this to verify your implementation.
Thanks for the help, I'll put that in
Sent from my SM-G920F using Tapatalk
-
So I'm still not sure, but I verified the issue only occurs when I initialise my game
I used VS' profiler to profile the game in release mode, and that erratic CPU usage section (that's highlighted in yellow) is what is the filter for the results. I do see huge spikes when I time around my clear() & display () blocks. I find spikes of 90ms+, but it's only rendering around 20 sprites, most of which share a texture. There's nothing new being added. Below is the data from the profiler:
(https://image.ibb.co/gHyhyQ/Profiler.png)
(https://image.ibb.co/f642Xk/Profiler2.png)
(https://image.ibb.co/cRVRsk/Profiler3.png)
-- Update --
So I've profiled down and during the games execution inside a loop which draws all game objects (shown below) seems to spike. The object count remains constant through execution (I checked for this initially).
for (const auto& gameObj : m_allGameObjects)
{
if (!gameObj->isEnabled())
{
continue;
}
m_rWindow->draw(*gameObj);
}
When getting the game to output a value every time this loops execution is above 20ms I get log outputs such as:
DRAWING OBJECTS > 20ms with value of 84
DRAWING OBJECTS > 20ms with value of 72
DRAWING OBJECTS > 20ms with value of 80
DRAWING OBJECTS > 20ms with value of 77
DRAWING OBJECTS > 20ms with value of 67
DRAWING OBJECTS > 20ms with value of 79
DRAWING OBJECTS > 20ms with value of 76
DRAWING OBJECTS > 20ms with value of 77
DRAWING OBJECTS > 20ms with value of 109
DRAWING OBJECTS > 20ms with value of 84
DRAWING OBJECTS > 20ms with value of 59
DRAWING OBJECTS > 20ms with value of 52
DRAWING OBJECTS > 20ms with value of 84
DRAWING OBJECTS > 20ms with value of 99
DRAWING OBJECTS > 20ms with value of 54
DRAWING OBJECTS > 20ms with value of 58
DRAWING OBJECTS > 20ms with value of 73
DRAWING OBJECTS > 20ms with value of 70
-
Not sure how went from wrongful FPS calculation to FPS spikes, but there has been an issue with the joystick bit, which was fixed in SFML master (https://github.com/SFML/SFML/commit/f053871a6c041292ecc059a8a2a435416f176390).
-
Not sure how went from wrongful FPS calculation to FPS spikes, but there has been an issue with the joystick bit, which was fixed in SFML master (https://github.com/SFML/SFML/commit/f053871a6c041292ecc059a8a2a435416f176390).
My initial post was about this FPS drop, and it is still the main issue that I'm experiencing. Would I need to compile the master branch myself to see if this fixes my issue?
-
So whilst debugging I found the element that seems to hit the performance of the game, and it points to renderwindow's .clear(), but only after a period of time has elapsed do I get this issue.