My apologies for the late replies, folks.
Java does garbage collecting on background - maybe that's one of the reasons?
I think someone somewhere mentioned that they used some program or other to check the garbage collector, and didn't find much wrong?
I'm also working on a slick2d project but in a very very early stage so I can't say a thing about stuttering.
Tell us what happens!
Well, the stuttering in cas, delventhal and gafferongames was big like 5-10px which means that the framerate dropped dramatically (high frametime) so something processor-heavy must have happened - just like if GC has kicked in or something. But when nothing like this is happening, then all the examples behave quite equally IMO (at least 90% equally) so really the different timesteps aren't behaving much differently.
When you say "all the examples behave quite equally," does that include the Game Maker example...?? ...Maybe?
---
I updated the
box.com download with a new example. If I understand correctly, it's a sort of hybrid between Cas's example and Eli Delventhal's. I'm not sure if it's any smoother than any of the other Java examples, but there's at least one new thing being done here.
I noticed that Cas's example can loop many times without CPU problems. I think this means that, even if one of these example programs loops many times, the CPU only starts groaning if it also renders very fast (although it seems that the CPU still starts groaning if the looping is
too fast). I tried looping like this in the hybrid example because it seems to me that, since the program checks the time more often, the timing would be more precise.
Also, I incorporated Eli Delventhal's timing method but applied it not only to logic updates but also to the rendering, which amounts, if I understand correctly and if I'm using the right terms, to making logic and rendering almost completely independent of each other in a sense. Put another way, they're each sort of on their own schedule.
Again, I can't really tell if all this allows the program to run any better than any of the other examples, but there it is anyway.
Here's some of the relevant code:
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
initGL(); // init OpenGL
vsync = false;
dsync = false;
wait = true;
drawInterpolated = true;
timerResolution = 1000000000;
updateRate = 60;
renderRate = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDisplayMode().getRefreshRate();
if (renderRate == java.awt.DisplayMode.REFRESH_RATE_UNKNOWN) renderRate = 60;
double updateInterval = timerResolution / (double) updateRate;
double renderInterval = timerResolution / (double) renderRate;
double lastFPSTime = System.nanoTime();
double lastUpdateTime = lastFPSTime;
double lastRenderTime = lastFPSTime;
int updateCount = 0;
int renderCount = 0;
int loopCount = 0;
updatesPerSecond = 0;
rendersPerSecond = 0;
loopsPerSecond = 0;
maxUpdates = 5;
Display.setVSyncEnabled(vsync);
while (!Display.isCloseRequested()) {
double now = System.nanoTime();
int localUpdateCount = 0;
while (now - lastUpdateTime > updateInterval && localUpdateCount < maxUpdates) {
update();
lastUpdateTime += updateInterval;
localUpdateCount++;
updateCount++;
}
if (now - lastUpdateTime > updateInterval) {
lastUpdateTime = now - updateInterval;
}
now = System.nanoTime();
if (now - lastFPSTime > timerResolution) {
lastFPSTime = now;
//lastFPSTime += timerResolution;
updatesPerSecond = updateCount;
rendersPerSecond = renderCount;
loopsPerSecond = loopCount;
updateCount = 0;
renderCount = 0;
loopCount = 0;
Display.setTitle(updatesPerSecond
+ ", " + rendersPerSecond
+ ", " + loopsPerSecond
+ "; VSync: "+ vsync
+ "; Display.sync(): " + dsync
+ "; Interpolated drawing: " + drawInterpolated
+ "; Yield and sleep: " + wait);
}
interpolation = (float) ((now - lastUpdateTime) / updateInterval);
now = System.nanoTime();
if (now - lastRenderTime > renderInterval) {
renderGL();
Display.update();
//lastRenderTime = now;
lastRenderTime += renderInterval;
renderCount++;
}
while (now - lastRenderTime > renderInterval) {
lastRenderTime += renderInterval;
}
loopCount++;
if (dsync) {
Display.sync(60); // cap fps to 60fps
} else if (wait) {
Thread.yield();
try {
Thread.sleep(1);
} catch (Exception e) {}
}
}
Display.destroy();
}