Unlimited Rendering vs 25 Updates a second

Started by
5 comments, last by danqua 9 years, 2 months ago

Hi Gamdev-Community,

this is my first post on this board, so i'm gonna introduce myself shortly:

My name is Daniel and I'm a Computerscience-Student from Germany.

I stumbled upon a problem I couldn't find a solution for.

I'm using the SDL2-Library and I try to accomplish a game loop that updates 25 times a second and renders as fast as the machine allows it to.

I want the movements for my game objects as smooth as possible but I don't know how.

I made a graphic to show my problem.

[attachment=26011:smooth_render.jpg]

The upper graph shows the type of rendering I'm trying to achieve.

The lower graph shows the actual result I get.

The idea is, when I set for example the speed of a game object to 5, it shouldn't jump from 0 to 5, but from {(0,1), (1, 2), ..., (4, 5)}.

25 times a second the object gets updated so every 25th of a second the object moves from its current position to (current position) + 5.

But between every update it gets rendered as ofthen as the computer allows it to. And in this (rendering)time, it should move smoothly to the new position.

There must be an interpolation or something to achieve this. The problem is that SDL only allows natural numbers (integer) for its x and y values on the screen.

(No OpenGL suggestions please!)

I hope I made my point clear.

Greetings,

Daniel

Advertisement

Just remember the next older position and interpolate between it and the new position, using the fraction of time passed inbetween as interpolation factor.

If you insist on using that integer only API, you can just round your floats to the nearest int when calling it.

You also should read http://gafferongames.com/game-physics/fix-your-timestep/ .

Seconding the "Fix your Timestep" article. In summary (he doesn't spell out the final product in anything but pseudo-code in the article)...

1. Each display frame, add the time since the start of the last display frame to an accumulator.

2. If the time accumulator has a value greater than your physics timestep (1/25th of a second, for you), then...

2.1. Save the current world state as the "previous" state.

2.2. Iterate a new world state (apply forces, movement rates, input).

2.3. Subtract one physics timestep from the accumulator.

3. Determine fraction of time between world states: the current accumulator value divided by the timestep width.

4. That results in a value Tf=[0..1). Calculate a virtual world state that is Tf of the way from "previous" to "current" world states (usually linear interpolation, but watch for cases where spherical interpolation is needed)

5. Render using that virtual world state.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

For the integer restriction, you should do movement in floats and round them to whole numbers at the rendering stage.

Since SDL is not hardware accelerated you are not going to get the benefits of texture image filtering and interpolation with fine movements, so everything that's drawn will have to be positioned to whole numbers. You'll have to make do with the slight jerky movement artifacts for the very slow movements.

New game in progress: Project SeedWorld

My development blog: Electronic Meteor

Okay thank you guys! I will try your approaches und post my progress.

@CC Ricers:

SDL2 is hardware accelerated ;-) You can choose between software and hardware acceleration in your renderer.

The problem is that SDL only allows natural numbers (integer) for its x and y values on the screen.

It wouldn’t matter anyway.
You can always keep track of your objects with float’s and cast to integer only when performing the draw.

As for the rest, fixed-step updates (as mentioned before) is a solution which I have outlined for clarity here.

His method uses forward-interpolation (predicting the future image) whereas mine uses backwards interpolation (showing the past image), which is easier to implement and avoids graphical anomalies at the expense of a slight delay in the graphics shown to the user.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

I got it working!

Thanks a lot to all of you.

My objects render method looks something like this:


void Player::draw(float interpolation) {
  
  m_renderPosition.x = (m_currPosition.x - m_oldPosition.x) * interpolation + m_oldPosition.x;
  m_renderPosition.y = (m_currPosition.y - m_oldPosition.y) * interpolation + m_oldPosition.y;

  p_texture->draw(m_renderPosition.x, m_renderPosition.y, m_width, m_height);
}

The game loop and interpolation calculation I used is from deWiTTERS.

This topic is closed to new replies.

Advertisement