We’re rewarding the question askers & reputations are being recalculated! Read more.
23 added 186 characters in body
source | link

Therein lies your problem. When the system is running your code on true fixed-rate vsync, you expect the same number of logic updates per display update. 1 or 10, but it should always be same - if it is, no stuttering. Android frame rate is quite steady, on my devices it's just under 60fps for a light NDK/OpenGL app, but it does fluctuate. Let's call this issue (A). Read on.

I haven'tHowever... I've not used Android's standard Java interface for game dev (only NDK), but what I would suggest (if possible - I don't think so?) is to run a while loop that has nothing to do with onDrawFrame() but rather just sits in main doing its game / physics logic things, while onDrawFrame() purely handles rendering at the appropriate time. I don't know exactly how that will sync up or even if it will work at all.

For Android NDK? as with most native development, you have direct control over the while loop off which everything runs :)- game logic and render calls - so the problem there is already solved.

Therein lies your problem. When the system is running your code on true fixed-rate vsync, you expect the same number of logic updates per display update. 1 or 10, but it should always be same - if it is, no stuttering. Android frame rate is quite steady, on my devices it's just under 60fps for a light NDK/OpenGL app, but it does fluctuate. Let's call this issue (A). Read on.

I haven't used Android's standard Java interface for game dev, but what I would suggest (if possible - I don't think so?) is to run a while loop that has nothing to do with onDrawFrame() but rather just sits in main doing its game / physics logic things, while onDrawFrame() purely handles rendering at the appropriate time. I don't know exactly how that will sync up or even if it will work at all. NDK? :)

Therein lies your problem. When the system is running your code on true fixed-rate vsync, you expect the same number of logic updates per display update. 1 or 10, but it should always be same - if it is, no stuttering. Android frame rate is quite steady, on my devices it's just under 60fps for a light NDK/OpenGL app, but it does fluctuate. Read on.

However... I've not used Android's Java interface for game dev (only NDK), but what I would suggest (if possible?) is to run a while loop that has nothing to do with onDrawFrame() but rather just sits in main doing its game / physics logic things, while onDrawFrame() purely handles rendering at the appropriate time. I don't know how that will sync up or even if it will work at all.

For Android NDK as with most native development, you have direct control over the while loop off which everything runs - game logic and render calls - so the problem there is already solved.

22 deleted 4 characters in body
source | link

Moral of the storyIn conclusion - 

You need interpolation if you want to accurately reflect your maximum frame rate as against your slower logic update rate, and with naive interpolation you may still perceive unwanted variances in frame rate due to occasional double-runs of physics and game logic. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look, though too many frames has drawbacks. 

When there is a mechanism in place dictating your timing, it's best to just stick with that and not try to work around it - such loops (as opposed to what Gaffer describes) are intended for one update per frame. If there are good solutions for this type of scenario, I'd love to hear them.

I haven't used Android's standard Java interface for game dev, but what I would suggest (if possible - I don't think so?) is to run a while loop that has nothing to do with onDrawFrame() but rather just sits in main doing its game / physics logic things, while onDrawFrame() purely handles rendering at the appropriate time. I don't know exactly how that will sync up or even if it will work at all. NDK? :)

Moral of the story - You need interpolation if you want to accurately reflect your maximum frame rate as against your slower logic update rate, and with naive interpolation you may still perceive unwanted variances in frame rate due to occasional double-runs of physics and game logic. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look. When there is a mechanism in place dictating your timing, it's best to just stick with that and not try to work around it - such loops (as opposed to what Gaffer describes) are intended for one update per frame.

In conclusion 

You need interpolation if you want to accurately reflect your maximum frame rate as against your slower logic update rate, and with naive interpolation you may still perceive unwanted variances in frame rate due to occasional double-runs of physics and game logic. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look, though too many frames has drawbacks. 

When there is a mechanism in place dictating your timing, it's best to just stick with that and not try to work around it - such loops (as opposed to what Gaffer describes) are intended for one update per frame. If there are good solutions for this type of scenario, I'd love to hear them.

I haven't used Android's standard Java interface for game dev, but what I would suggest (if possible - I don't think so?) is to run a while loop that has nothing to do with onDrawFrame() but rather just sits in main doing its game / physics logic things, while onDrawFrame() purely handles rendering at the appropriate time. I don't know exactly how that will sync up or even if it will work at all. NDK? :)

21 deleted 4 characters in body
source | link
  • have direct control over the core (while) loop, which you can run at the highest rate possible given the ops coded there in C/C++ code, and where equally if you take too long to process and/ render, that is entirely your own concern - but typically you have many render frames per logic frame;
  • have a (relatively) fixed frame rate dictated to you by the system, which calls your update (onDrawFrame() in this case) as a callback e.g. browser JS, Flash, or in this case, Android - here you have one or more logic frames per render frame (see the inversion from the above case?), and you absolutely must complete at least one logic update per frame period (dictated by the system) for things to proceed sanely - this which is fundamentally different.

Example A - the display frequency is relatively steady, around 16.7ms period, give or take a millsecond or 2, and for maybe 90% of frames, it is spot on at 16.7. Let's say your logic takes 9ms. Most frames, then, you'll manage just one update. But due to unforeseen delays in the Android operating system, the period on which onDrawFrame() fluctuates and sometimes jumps up to 18+ ms every so often, say 5% of the time, and then you are going to end up doing 2 logic updates because you have enough time do so instead of just 1...but the actual display frequency hasn't changed so much that it would have been apparent using a one-logic-update-per-display-update approach anyway, so what do you see? Stuttering, of course.Stuttering, of course.

Moral of the story - You need interpolation if you want to accurately reflect your maximum frame rate as against your slower logic update rate, and with naive interpolation you may still perceive unwanted variances in frame rate due to occasional double-runs of physics and game logic. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look. When there is a mechanism in place which dictatesdictating your timing, it's best to just stick with that and not try to work around it - such loops (as opposed to what Gaffer describes) are intended for one update per frame. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look.

  • have direct control over the core loop, which you can run at the highest rate possible given the ops coded there in C/C++ code, and where equally if you take too long to process and render, that is entirely your own concern - but typically you have many render frames per logic frame;
  • have a (relatively) fixed frame rate dictated to you by the system, which calls your update (onDrawFrame() in this case) as a callback e.g. browser JS, Flash, or in this case, Android - here you have one or more logic frames per render frame (see the inversion from the above case?), and you absolutely must complete at least one logic update per frame period (dictated by the system) for things to proceed sanely - this which is fundamentally different.

Example A - the display frequency is relatively steady, around 16.7ms period, give or take a millsecond or 2, and for maybe 90% of frames, it is spot on at 16.7. Let's say your logic takes 9ms. Most frames, then, you'll manage just one update. But due to unforeseen delays in the Android operating system, the period on which onDrawFrame() fluctuates and sometimes jumps up to 18+ ms every so often, say 5% of the time, and then you are going to end up doing 2 logic updates because you have enough time do so instead of just 1...but the actual display frequency hasn't changed so much that it would have been apparent using a one-logic-update-per-display-update approach anyway, so what do you see? Stuttering, of course.

Moral of the story - You need interpolation if you want to accurately reflect your maximum frame rate as against your slower logic update rate, and with naive interpolation you may still perceive unwanted variances in frame rate due to occasional double-runs of physics and game logic. When there is a mechanism in place which dictates your timing, it's best to just stick with that and not try to work around it - such loops (as opposed to what Gaffer describes) are intended for one update per frame. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look.

  • have direct control over the core (while) loop, which you can run at the highest rate possible given the ops coded there in C/C++ code, and where if you take too long to process / render, that is entirely your own concern - but typically you have many render frames per logic frame;
  • have a (relatively) fixed frame rate dictated to you by the system, which calls your update (onDrawFrame() in this case) as a callback e.g. browser JS, Flash, or in this case, Android - here you have one or more logic frames per render frame (see the inversion from the above case?), and you absolutely must complete at least one logic update per frame period (dictated by the system) for things to proceed sanely - this which is fundamentally different.

Example A - the display frequency is relatively steady, around 16.7ms period, give or take a millsecond or 2, and for maybe 90% of frames, it is spot on at 16.7. Let's say your logic takes 9ms. Most frames, then, you'll manage just one update. But due to unforeseen delays in the Android operating system, the period on which onDrawFrame() fluctuates and sometimes jumps up to 18+ ms every so often, say 5% of the time, and then you are going to end up doing 2 logic updates because you have enough time do so instead of just 1...but the actual display frequency hasn't changed so much that it would have been apparent using a one-logic-update-per-display-update approach anyway, so what do you see? Stuttering, of course.

Moral of the story - You need interpolation if you want to accurately reflect your maximum frame rate as against your slower logic update rate, and with naive interpolation you may still perceive unwanted variances in frame rate due to occasional double-runs of physics and game logic. Admittedly I'm not an expert on interpolation / extrapolation algorithms but it stands to reason that the more frames you use to calculate averages over, the smoother it's going to look. When there is a mechanism in place dictating your timing, it's best to just stick with that and not try to work around it - such loops (as opposed to what Gaffer describes) are intended for one update per frame.

20 deleted 375 characters in body
source | link
19 added 47 characters in body
source | link
18 added 47 characters in body
source | link
17 added 47 characters in body
source | link
16 added 57 characters in body
source | link
15 added 1 character in body
source | link
14 added 1 character in body
source | link
13 added 26 characters in body
source | link
12 added 26 characters in body
source | link
11 added 26 characters in body
source | link
10 added 44 characters in body
source | link
9 deleted 26 characters in body
source | link
8 added 18 characters in body
source | link
7 added 232 characters in body
source | link
6 deleted 76 characters in body
source | link
5 deleted 76 characters in body
source | link
4 deleted 76 characters in body
source | link
3 deleted 76 characters in body
source | link
2 deleted 76 characters in body
source | link
1
source | link