i don't know where else to go with this question, but this following code successfully locked the frame rate in sdl.
when i ported it to glfw it no longer works. the frame rate it locks too is seemingly random. could someone pretty please take a look at this snippet and help me out?
Where are you calling glfwSwapBuffers()? You should do this before you measure the frame_start time, otherwise you're not taking into account the actual rendering time.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@iamwhosiam: At brief glance the code seems reasonable, but this is hard to tell without all the code. I'd advise trying to create a small test app, and if that has problems you could share it with me and I could help debug it.
I would try a few changes.
Make sure you time the entire loop, so the start time should be measured after the tw_time_update(). This way if you have any time being taken up inside tw_input_update this is being accounted for.
Write your code for easy debugging, and make sure you don't pass 0 to Sleep. Example below:
double wait_time = 1.0 / (targetFrameRate);
double curr_frame_time = glfwGetTime() - frame_start;
double dur = 1000.0 * ( wait_time - curr_frame_time ) + 0.5;
DWORD durDW = (DWORD)dur;
if( durDW > 0 ) // ensures that we don't have a dur > 0.0 which converts to a durDW of 0.
{
Sleep( durDW );
}
double frame_end = glfwGetTime();
// here you could print to file or OutputDebugStream curr_frame_time, frame_end - frame_start and dur.
frame_start = frame_end;
Note that there is no guarantee that Sleep will return exactly on the time you require. It's possible your odd frame times were due to passing in a 0 value to Sleep, which causes the thread to give up it's time slice.
~~~~~~
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Oops - forgot DWORD is unsigned. Make sure to use a signed integer type when converting from double as it's undefined as to what happens for negative values on cast to unsigned int.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
one question i have, is should i be setting the swap interval to zero or maybe one? or just leave it default? having vsync on would be cool but im not sure if it would mess with the frame rate. also some peoples computers might just force it off anyway so, just leave it default and make em both work?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This code works for - I can change the target_frame_rate and never get more, though can get less obviously.
Note that glfwSetWindowTitle can be expensive, so I moved this into calc_frame_rate inside the if(elapsed>1) so as to change the title only once per second.
Preferably you should use something like FRAPS or gDEBugger to check frame rate, and this shows a nice solid flat FPS graph for me.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
On the question of vsync, I would make that user configurable. I prefer having it on, but some don't. Also note the documentation on glfwSwapInterval and negative swap intervals which can work well.
Note on Windows the _GLFW_USE_DWM_SWAP_INTERVAL definition (requires a recompile of glfw) controls whether to ignore swap interval settings when the DWM compositing is on, and as you say many drivers can override the application settings.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i don't know where else to go with this question, but this following code successfully locked the frame rate in sdl.
when i ported it to glfw it no longer works. the frame rate it locks too is seemingly random. could someone pretty please take a look at this snippet and help me out?
any help is much appreciated :)
Where are you calling glfwSwapBuffers()? You should do this before you measure the frame_start time, otherwise you're not taking into account the actual rendering time.
i'm not using sleep function:
currentTime, lastTime - doubles
render() is my rendering function with glfwSwapBuffers()
renderfps(60) - 60 fps, called in the main loop
arampl: i tried this technique and it worked but since the process never sleeps it takes up too much cpu and i dont want my game to be a hog ;)
doug binks: here's my main loop, i took out the non-relevant bits and i think the functions are pretty self explanatory.
while( !glfwWindowShouldClose(window) )
{
tw_time_frame_start(); // get the start time
handle_events();
update_func();
}
@iamwhosiam: At brief glance the code seems reasonable, but this is hard to tell without all the code. I'd advise trying to create a small test app, and if that has problems you could share it with me and I could help debug it.
I would try a few changes.
Make sure you time the entire loop, so the start time should be measured after the tw_time_update(). This way if you have any time being taken up inside tw_input_update this is being accounted for.
Write your code for easy debugging, and make sure you don't pass 0 to Sleep. Example below:
Note that there is no guarantee that Sleep will return exactly on the time you require. It's possible your odd frame times were due to passing in a 0 value to Sleep, which causes the thread to give up it's time slice.
~~~~~~
Oops - forgot DWORD is unsigned. Make sure to use a signed integer type when converting from double as it's undefined as to what happens for negative values on cast to unsigned int.
ok i made a test app that just creates a window then just calculates frame rate and sleeps and it's still doing it.
ive uploaded it to http://pastebin.com/E1kGThRn
one question i have, is should i be setting the swap interval to zero or maybe one? or just leave it default? having vsync on would be cool but im not sure if it would mess with the frame rate. also some peoples computers might just force it off anyway so, just leave it default and make em both work?
This code works for - I can change the target_frame_rate and never get more, though can get less obviously.
Note that glfwSetWindowTitle can be expensive, so I moved this into calc_frame_rate inside the if(elapsed>1) so as to change the title only once per second.
Preferably you should use something like FRAPS or gDEBugger to check frame rate, and this shows a nice solid flat FPS graph for me.
ok, thank u very much for your time :)
On the question of vsync, I would make that user configurable. I prefer having it on, but some don't. Also note the documentation on glfwSwapInterval and negative swap intervals which can work well.
Note on Windows the _GLFW_USE_DWM_SWAP_INTERVAL definition (requires a recompile of glfw) controls whether to ignore swap interval settings when the DWM compositing is on, and as you say many drivers can override the application settings.