Jump to content
  • Advertisement
Sign in to follow this  
DragonicZero

Unity SDL Framerate Capping Issue [Solved]

This topic is 2992 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,
This should be my first post on the forums but as many of you may have noticed, there were like 8 threads with this same subject. I'm sorry about that, what happened was that when I pressed the button to submit my post nothing happened, I tried again a few times and still, but I tried again now a few times and finally my post was submitted, only to found out that I had accidentally submitted the post a few times, but I've deleted the others. I apologize for that. It was the source tags that caused it, I'm now using code tags instead.

I hope someone can help me with this. I'm having some trouble making my animations look smooth while capping the frame rate, my weapon of choice is Cplusplus with the SDL API. I'm following Lazy Foo's tutorial about Regulating Frame rate.

The logic is this:



#include "SDL.h"

const int FRAMES_PER_SECOND = 60;


int main(int argc, char* args[])
{
//Here I initialize everything

bool running = true;

int startTime;

while(running)
{
startTime = SDL_GetTicks();

//Here I handle events
//*Events*

//Here's the game logic for my character movement on the screen
//*Logic stuff*

//Here I handle the rendering
//*Blits*, *Flip the screen*...

//============== Here I cap the frame rate ======================

static int elapsedTime = 0;

elapsedTime = (SDL_GetTicks() - startTime);

if( elapsedTime < (1000 / FRAMES_PER_SECOND) )
{
SDL_Delay( (1000 / FRAMES_PER_SECOND) - elapsedTime);
}

//===============================================================

}//End of game loop

//Free resources
//*Free SDL surfaces and close SDL stuff*

return 0;
}//End main



This is only the logic, I didn't do exactly this on my program.

OK, in details the problems are:

1. On my PC when capping the frame rate at 60FPS I get frame rates around 62.5 and 62.486 and my game animation (the character movement is not smooth, it's kind of jumpy, with or without using frame independent movement together with this approach of frame capping. However when using frame independent movement explained here without frame capping the animation runs super smooth (at around 303 fps), but I want to cap the frame rate to keep the CPU more relaxed and to avoid rendering unnecessary frames to the screen. Maybe the problem is because my FPS are not exactly 60 all of the time, but I've seen games run on this PC at exactly 60 FPS, how do I achieve this?

This problem occurs on a Intel Core i7 CPU @ 2.80GHz, 4 GB of RAM, Using Windows 7 Professional (64 bit).

2. On my bro's PC the same frame rate capping approach works smoothly but it runs around 58 and 59 FPS and I noticed some tearing on the character sprites while moving around the screen.

That's on a AMD Athlon 64 X2 Dual Core CPU @ 2.71GHx, 3 GB of RAM, Using Win XP SP3.

Before posting, I searched everywhere and the closest thing I found about my problem was this unresolved post.
The poster of that thread seems to have the exact same problem I'm having.

[disturbed] Am I just doing something wrong?

[looksaround] Is frame rate capping really needed, or should I let the game be selfish and run the loop as fast as possible unnecessarily without taking into account that the CPU could be doing something else in the background?

[wow] What is the standard way of handling frames?

Any pointers would be greatly appreciated as I've been searching info about the subject for two days without success;

[Edited by - DragonicZero on July 14, 2010 3:06:55 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by DragonicZero
[disturbed] Am I just doing something wrong?


I would guess that relying on SDL_Delay to regulate framerate is not a good idea, since suspending a thread is not guaranteed to return exactly at the requested duration. From SDL documentation: This function [SDL_Delay] waits a specified number of milliseconds before returning. It waits at least the specified time, but possible longer due to OS scheduling. The delay granularity is at least 10 ms. Some platforms have shorter clock ticks but this is the most common.

Quote:

[looksaround] Is frame rate capping really needed, or should I let the game be selfish and run the loop as fast as possible unnecessarily without taking into account that the CPU could be doing something else in the background?


Frame rate capping is not really needed, but letting the OS know that your game doesn't need all of the cpu (aka SDL_Delay(0) or SDL_Delay(1)) is all you need at the end of rendering a frame.

Quote:

[wow] What is the standard way of handling frames?

Any pointers would be greatly appreciated as I've been searching info about the subject for two days without success;


See the Fix Your Timestep article for ideas:

// Although this code renders as fast as possible, it helps
// keep the logic regulated at a constant rate

unsigned currentTicks = SDL_GetTicks(); // Current time
unsigned previousTicks = currentTicks; // Time at last frame
unsigned elapsedTime = 0; // Elapsed ticks between the current and previous frame
unsigned bukkit = 0;

unsigned fps = 60;
unsigned ticksPerSecond = 1000;
unsigned ticksPerFrame = ticksPerSecond / fps;
unsigned updateThreshold = ticksPerFrame * 5;
float deltaTime = static_cast<float>(ticksPerFrame) / ticksPerSecond;

while ( running ) {
previousTicks = currentTicks;
currentTicks = SDL_GetTicks();
elapsedTicks = currentTicks - previousTicks;

if ( elapsedTicks >= updateThreshold )
elapsedTicks %= ticksPerFrame;

for ( bukkit += elapsedTicks; bukkit >= ticksPerFrame; bukkit -= ticksPerFrame ) {
// Event Handling

// Logic
theGame.update( deltaTime );
}

// Rendering
// Additionally, you can use interpolation here
// float interp = static_cast<float>( bukkit ) / ticksPerFrame;
// theGame.render( interp ); // A value between [0, 1), 0 being the previous state, 1 being the current state
theGame.render();

SDL_Sleep( 0 );
}




Share this post


Link to post
Share on other sites
Quote:
Original post by _fastcall
Quote:
Original post by DragonicZero
[disturbed] Am I just doing something wrong?


I would guess that relying on SDL_Delay to regulate framerate is not a good idea, since suspending a thread is not guaranteed to return exactly at the requested duration. From SDL documentation: This function [SDL_Delay] waits a specified number of milliseconds before returning. It waits at least the specified time, but possible longer due to OS scheduling. The delay granularity is at least 10 ms. Some platforms have shorter clock ticks but this is the most common.

Quote:

[looksaround] Is frame rate capping really needed, or should I let the game be selfish and run the loop as fast as possible unnecessarily without taking into account that the CPU could be doing something else in the background?


Frame rate capping is not really needed, but letting the OS know that your game doesn't need all of the cpu (aka SDL_Delay(0) or SDL_Delay(1)) is all you need at the end of rendering a frame.

Quote:

[wow] What is the standard way of handling frames?

Any pointers would be greatly appreciated as I've been searching info about the subject for two days without success;


See the Fix Your Timestep article for ideas:
*** Source Snippet Removed ***


Well, it seems like I wont be capping the framerate then. However I found out a way to make the Delay more consistent, instead of skipping the remaining frames, it is better to check if a frame took the time it should, if it was faster, wait for the difference between the time it should have taken and the time it took.

About the SDL_Delay(0) and SDL_Delay(1), I read on this thread:
Quote:
Original post by rip-off
Quote:
Original post by TheBuzzSaw
I use SDL_Delay(1) in my program. What is the fundamental difference between that at SDL_Delay(0)?


I believe that on some implementations of SDL, SDL_Delay(0) may return immediately, whereas SDL_Delay(1) will always sleep for some period (generally a timeslice, which could have a granularity of 10 milliseconds for example on Windows).


Can someone confirm this?
Which one is preffered?


By the way, very nice article and thanks for the response.
I'm trying to get better at this so that I can help others too.

Share this post


Link to post
Share on other sites
Hi, I don't want to hijack the thread but I tried this too and was also wondering whether I had implemented the code correctly too. It is exactly the same code that DragonicZero has posted up.

DragonicZero - When you start the game does the framerate start at zero and then gradually builds up to the framerate you set?

I've set the framerate to 30fps and the framerate builds up slowly from zero to about 28- 29 fps I think.

Download the game and have a look, is it the same behaviour as your game?

Game here

Mines is an AMD opteron 180 @ 2.4Ghz, 2GB of RAM with a Geforce 6800GT GPU, WinXP SP3.

Share this post


Link to post
Share on other sites
Quote:
Original post by popcorn
Hi, I don't want to hijack the thread but I tried this too and was also wondering whether I had implemented the code correctly too. It is exactly the same code that DragonicZero has posted up.

DragonicZero - When you start the game does the framerate start at zero and then gradually builds up to the framerate you set?

I've set the framerate to 30fps and the framerate builds up slowly from zero to about 28- 29 fps I think.

Download the game and have a look, is it the same behaviour as your game?

Game here

Mines is an AMD opteron 180 @ 2.4Ghz, 2GB of RAM with a Geforce 6800GT GPU, WinXP SP3.


I usually don't open programs without trusting the source, but I made an exception this time.
Next time please try to post a bit of code instead.

Now, I checked your game and it seems to be working nicely around the 29 - 30 fps from the beginning. The title of your game when running says Average Frames per Second, so I'm guessing you're using Lazy Foo's method for calculating framerate.
Well, what happens is this, you're calculating the average frames per second since the beginning of the program, before the actual game there's the title screen that seems to be running at a very low framerate, the way you implemented your code that framerate is taken into account together with the framerate of the actual game which is 30 fps. Check it out yourself, when you run your game hit s immediately to start, and look at the framerate, it will say 30 because it didn't got to store the framerate of the title screen. To calculate the average frames per second of your game you have to start counting frames after the title screen.

Edit: it could be either what I said about the title screen having low framerate or maybe you start counting frames before the title screen and start the timer for calculating framerate after the title screen or the other way around.

Share this post


Link to post
Share on other sites
Thanks DragonicZero, it was your second option that was correct, I started the timer before entering the game loop, I've changed the code so that the timer starts when 's' is pressed and it calculates at 29 - 30fps straight away.

I can understand about not wanting to open programs from unknown sources so thanks for explaining and for checking the program.

About your problem, not that I'm much help but maybe you could try running at a lower fps like 30/40fps instead of 60fps and see if it runs better?

Share this post


Link to post
Share on other sites
I'm glad I could help.

Thanks for the suggestion, actually I am now using the technique I talked about on my earlier post for regulating my framerate (the one where I check if a frame took the time it should, if it was faster, wait for the difference between the time it should have taken and the time it took, instead of skipping the remaining frames, which is what was causing the jumpiness on my animation in the first place, so now I get a smooth animation while at 30 or 60 fps. I noticed your game a little jumpy too, you could get your fps more constant by doing what I did.

It was basically:


const float FRAMERATE = 30;
const float FPS = 1000.f / FRAMERATE;

int main(int argc, char* args[])
{
int frameNumber = 0

Uint32 startTime = SDL_GetTicks();
//Game loop
while(static bool running = true)
{
frameNumber++

//Events, Logic, Rendering...

//=================== Framerate capping =========================

Uint32 timeTheFrameShouldHaveTaken = startTime + frameNumber * FPS;
Uint32 timeItTookToRenderAllPreviousFrames = SDL_GetTicks();

if(timeItTookToRenderAllPreviousFrames <= timeTheFrameShouldHaveTaken)
{
SDL_Delay(timeItShoulHaveTaken - timeItTook);
}
else
{
//if it took longer than it should
//reset the frames and the startTime

frame = 0;
startTime = SDL_GetTicks;

//if you dont do this the frames will try
//to catch up with a higher framerate

//that happens for example if you move
//your window while ingame for some time
}
//===============================================================
}//end game loop

//free resources

return 0;
}//end main


But I finally decided not to cap my framerate and just use "SDL_Delay(1);" because with that the program uses around 7% CPU, I tried "SDL_Delay(0); but it used around 13% CPU, that's why I stayed with 1.


EDIT: I fixed something on the code above because it gave almost the same effect as the one on the first code because there wasn't enough precision, so I changed the const int on the first lines to const float, sorry if that caused any confusion.

[Edited by - DragonicZero on July 13, 2010 12:14:07 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by DragonicZero
I'm glad I could help.

Thanks for the suggestion, actually I am now using the technique I talked about on my earlier post for regulating my framerate (the one where I check if a frame took the time it should, if it was faster, wait for the difference between the time it should have taken and the time it took, instead of skipping the remaining frames, which is what was causing the jumpiness on my animation in the first place, so now I get a smooth animation while at 30 or 60 fps. I noticed your game a little jumpy too, you could get your fps more constant by doing what I did.


But I finally decided not to cap my framerate and just use "SDL_Delay(1);" because with that the program uses around 7% CPU, I tried "SDL_Delay(0); but it used around 13% CPU, that's why I stayed with 1.


EDIT: I fixed something on the code above because it gave almost the same effect as the one on the first code because there wasn't enough precision, so I changed the const int on the first lines to const float, sorry if that caused any confusion.


OK DragonicZero I'll bear your advice in mind but at the moment I feel the way the fps are calculated is fine, I personally don't feel the game is a little jumpy. The method in lazy foos tutorials does seem to take more CPU time than your suggestion though since I notice that it takes about 24 - 26% of CPU time.

Share this post


Link to post
Share on other sites
Your game is fine Popcorn, the jumpiness is barely noticeable, just giving a different approach to framerate capping. As for me, I think my problem is solved. For simple games that don't use physics for now I'll do them framerate based until I get better at this. Then I'll try to implement a timestep based games with physics, I hope my brain survives.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!