Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

supagu

indpedendent update / render

This topic is 5315 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

hi, i have an engine, it was signelthreaded, and 40 times per second i would update my world, and 100 times per second, update my physics, now i run into problems when i get less that 100 fps, physics slows down... i tired opening another thread for my render'' but this drops about 30 - 40 fps off is there another solution?

Share this post


Link to post
Share on other sites
Advertisement
Multiple threads seem really good in a theoretical, aesthetic sense but they are inefficient. There are two options I see for you ina single thread:
1)Change your physics code to update once per graphics frame with a variable timestep so it actually updates the world by the amount of time that has passed since last frame. This is the most theoretically nice option but probably means changing your physics code quite a bit to something more complicated.
2)Something like this:
function GameRender()
{
float updateTimeStep=0.01f; //how much the physics updates by
float timeStep=timeNow-timeLastCall; //in seconds
int steps = timestep/updateTimeStep; //0 if fps>100
for(int i=0;i< steps;++i)
{
PhysicsUpdate()
}
}

This was done in the game I worked on at a real game developer.
Basically it does how every many steps are needed to bring the physics up to date. If the renderer is faster than the physics update rate, some frames no physics will be done. This works well.

[edited by - d000hg on February 28, 2004 12:31:24 PM]

Share this post


Link to post
Share on other sites
hrmm i like the second idea,

ive implemented it, but running at 150 fps and then at 60fps does feel different :-/


time = SDL_GetTicks();

physDeltaTime = time - lastPhysTime;
gameDeltaTime = time - lastGameTime;

physStep = physDeltaTime / PHYSICS_UPDATE;
gameStep = gameDeltaTime / GAME_UPDATE;


//then inside my phsics loop:

lastPhysTime = time;

//and in my game loop:

lastGameTime = time;


:-/ makes sence on how it works, but it doesnt seem to be perfect :-/


edit: does seem to be working, at 150fps, every second frame its updated once,

at 60 fps, its updated at least once every fps, sometimes 2 times.

hrmm :-/
any way to make it more accurate? maybe determine the remainder after the division?
[edited by - supagu on February 28, 2004 9:07:51 PM]

[edited by - supagu on February 28, 2004 9:14:00 PM]

Share this post


Link to post
Share on other sites
The typical game main loop is:


lastTime = clock();
while( running ) {
while( UIEventsAvailable() ) {
ReadAndProcessUIEvents();
}
now = clock();
if( lastTime < now-MAX_TIME_JUMP ) {
lastTime = now-MAX_TIME_JUMP;
}
while( lastTime < now ) {
StepPhysicsByOneTimestep();
lastTime += TIME_STEP_SIZE;
}
RenderOneFrame();
}


This will make sure that the time step is always the same, and you render when you have CPU left over. If you have more CPU than needed to render once per physics step, you''ll render multiple frames based on the same physics state; you can improve that by reducing the step size (thus giving the CPU more to do) or by rendering a frame that''s interpolated between the last two physics frames, based on (real) time.

If you want to write a program that runs the same speed in debug and release builds, and on a 600 MHz CPU as well as a 3.2 GHz CPU, you''ll need to realize that physics must be very cheap; specifically, it''ll have to be cheap enough to run at full rate in debug mode on a 600 MHz CPU while still leaving some time left for rendering.

Share this post


Link to post
Share on other sites
The remaining time will make an effect, come to think of it. If you should be doing 1.8 physics updates every frame but always do 1 it'll be wrong. If you get the floating point value for number of physics updates before truncating it and store the fractional part as remainder then each frame, using last frame's remainder:
physStep = (int)(physDeltaTime / PHYSICS_UPDATE + remainder)  
Which'll catch up the updates you're missing.

[edited by - d000hg on February 29, 2004 12:38:05 PM]

Share this post


Link to post
Share on other sites
nope thats cant be right,

should be something like this:


physReminder += (physDeltaTime % PHYSICS_UPDATE);

if( physReminder > 10 ) //10 means 1 step

{
// printf("adding step!\n");

++physStep;
physReminder -= 10;
}


i tired this, but it still isnt the same speed at differeing frame rates :-/

Share this post


Link to post
Share on other sites
Ah, you''re dealing in milliseconds right, not actual seconds? I''d certainly find using real seconds and floating point values simpler because then:
timeSinceLastFrame/physicsUpdateInterval gives you a floating point number. The integer part + the fractional part from last frame is then how you work out the number of updates to do each frame.

Share this post


Link to post
Share on other sites
i put in a 10 second timer that counts the number of physics steps in 10 seconds, and it still like 100 more steps with higher fps :-/

the reminder doesnt add up either!

the one with more physics steps in 10 seconds ahppened to have a greater additive time at the end :-/


[edited by - supagu on March 1, 2004 4:30:48 AM]

Share this post


Link to post
Share on other sites
I GOT IT!!!!


time = SDL_GetTicks();

deltaTime = time - startTime;
curPhysSteps = deltaTime / PHYSICS_UPDATE;

for( int p = 0; p < curPhysSteps - completePhysSteps; ++p )
{
//do physics update

}
completePhysSteps = curPhysSteps;


i also do the same for my game loop,
this usually is with an accuracy of 1 loop in seconds

Share this post


Link to post
Share on other sites
That was gong to be my last suggestion! It would be nicer to have
while(completePhysSteps++<=curPhysSteps){//do physics update}  
instead of
for( int p = 0; p < curPhysSteps - completePhysSteps; ++p ){//do physics update}  
IMO only this is better but it's just a sytlistic thing. Plus the ++ probably isn't quite right...

[edited by - d000hg on March 1, 2004 10:36:14 AM]

Share this post


Link to post
Share on other sites

  • 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!