Skip to main content
gamedev.net
🔒 Locked

Getting a consistent framerate...

Started by AndrewSmart 12 replies 550+ views
Original Post
AndrewSmart
AndrewSmart
Hi all, I''m fed up with having jerky movement in my 3D engine, which is a terrain based game. It uses a cellular approach to rendering only a sub-set of the total terrain. As you move forward in the terrain, cells of terrain have to be destroyed, and new ones created in the distance. Cells can contain many different types of objects, some simple meshes, some complex, and some with none at all. So depending on where you are in the terrain, the rendering time can vary depending on object complexities etc. Movement is based on velocities and time since the last frame, in order to try and even out the jerkiness, but I still get a jerky movement when moving in the terrain. Can anyone offer any suggestions as to how to improve frame rate consistency... I''ve tried to monitor the frame rate, and put in small time delays to get each frame to be the same length of time, but it doesn''t seem to improve anything really. I would really appreciate any comments... Andrew
thona
thona
Could have been that the loop better fitted the complex instruction pipelines you have today. Less writes to the stack, too... Modern processors are complex and sometimes hard to predict.
RegardsThomas TomiczekTHONA Consulting Ltd.(Microsoft MVP C#/.NET)
AndrewSmart
AndrewSmart
I can achieve an average framerate of around 50fps +/- a bit of variation. It would therefore seem reasonable to be able to maintain a steady framerate of say 30fps, with delays to compensate for the "quicker" frames. You can slow the quick frames down to match the time of the slowest frames, if you catch my drift. I thought this was how to approach it...

Seems a bit ironic I''m trying to slow the thing down ?? Am I doing something wrong ???????????

Andrew
juhaszt
juhaszt
The best solution is:
at every frame you have to calculate the time passed since the last frame:

for(newTime=GetTickCount();newTime==lastTime;newTime=GetTickCount());
elapsedTime=newTime-lastTime;
lastTime=newTime;


Using this time (elapsedTime) you have to calculate every movements so, that you know the speed of every objects, and the calculated movement comes from multiplying the calculated elapsedTime with the speed of the object.
That is all and works on computers with different speed!!

I would not slow down the programm with delay!!!
programmer
AndrewSmart
AndrewSmart
This is exactly what I am doing at present, but I still get jerky movement for some reason...
juhaszt
juhaszt
You may flip the back buffer to the front buffer only on VSYNC!!
Is that fulfilled in the programm??
programmer
IFooBar
IFooBar
Hello

There are basically two ways (that i know of) to make animations run the same on systems. if you have a faster computer then you''re animations will be smoother (more frames per second) and a slower computer the animation should happen in the same amount of time but with less frames, so it will not be as smooth as a faster computer.

anyway. the 2 ways are by frame time, and by speed factor. There is an article on gamedev on speed factor. And ive written a tutorial and class on both techniques at my site (Triple Buffer)

The best way in my opinion is to base all your animatioons in pixels per second, but since your using directX youd be better off using your own predefined fixed set of units, ie: you can use cm/s and define 10 units as 1 cm.

now instead of specifying how many units u want something to move per frame, you should specify how many units you want an object to move per second. that way you''ll get more consistent movement (but it could still be jerky on slower computers)

The speed factor technique is this: you set a target fps. say 30 fps, and if ur computer is running at 60 fps then you multiply all animations by a speed factor which is targetFPS/actualFPS in this case teh speed factor is 0.5, so all you animations will move at 30fps, only they''ll have double the amount of rendering frames making it smoother

I have a feeling i was somehow off topic but anyways, thats it



Al
"May Trixus (the goddess of programming) guide you "
[Triple Buffer]|[SCRIPTaGAME]|[My Old Site]
[size=2]aliak.net
AndrewSmart
AndrewSmart
Hmmm, not sure if I am doing a Blt on VSync or not, how do I check this...

The code snippet is as follows:-

//-----------------------------------------------------------------------------
// Name: ShowFrame()
// Desc: Show the frame on the primary surface, via a blt or a flip.
//-----------------------------------------------------------------------------
HRESULT CD3DFramework7::ShowFrame()
{
if( NULL == m_pddsFrontBuffer )
return D3DFWERR_NOTINITIALIZED;

if( m_bIsFullscreen )
{
// We are in fullscreen mode, so perform a flip.
if( m_bIsStereo )
return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT | DDFLIP_STEREO );
else
return m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT );
}
else
{
// We are in windowed mode, so perform a blit.
return m_pddsFrontBuffer->Blt( &m_rcScreenRect, m_pddsBackBuffer,
NULL, DDBLT_WAIT, NULL );
}
}

AndrewSmart
AndrewSmart
Is there a function to wait for the VSYNC signal, and then proceed to do the Flip / Blt ??
juhaszt
juhaszt
I think there is no function for that, that will be decided when you create the device.
Anyway you have to run your programm in fullscreen mode to be able to do the flip on VSYNC.
If the flip will be executed on VSYNC your framerate can be ''refresh rate'' or ''refresh rate/2'' or ''refresh rate/3'' and so on. So you can see at once if your flip will be executed on VSYNC!
programmer
Shannon Barber
Shannon Barber
I thought there was a flag on the flip method to tell it to wait for vsync? (I don''t have the Dx7 documentation anymore, so I can''t check it)

The Dx8 docs say you have to decide when you create the swapping chain (it''s buried in one of the flag structures).

Out-of-the box Window''s time slice is anywhere from 10ms to 16ms. You need to call... eh... timeBeginTime (found in mmsystem.h) and (try to) set it to 1ms - that way you can sleep for only a couple of milliseconds.

I''ve heard that Quake runs it''s physics at 10Hz, and (linearly) interpolates animation frames in-between. There are some very good reasons to run the physics at a fixed rate. Now, that doesn''t mean that they must be calculated every 100ms - let''s say for some reason it takes 200ms to render a frame. Then you need to perform 2 physics updates before rendering the next frame. Normall frames will be rendering in <30ms, so you will only do a physics update every 3 or 4 frame. (You need a anti-aliased decimating filter)
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
CWizard
CWizard
I don''t know if this approach it as all possible today, with games and with APIs like DirectX. But, when I coded demos long time ago, I had a system to even out calculations over time. It was very messy and tweaked beyond theoretical description. It was based on that I had a "queue" with calculations to do. It would draw the screen and then did as many calculations as there was time to untill the next screen update. The thing one didn''t notice here was that there were a "lag" between the calculation and the drawing, and that would probably be problematic to have in a game.

As stated, I have no idea if one could implement such a system while using an API on "non-standard systems" (that is, can''t know how many cycles you are given every second). But, with skilled fingers, one could probably do something like this with a selected type of calculations.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.