Now that JOGL is moving towards 1.5 Yipee! I thought I'd share my FPS animator I've been using recently. You can toggle between current implementation and this new one with the boolean at the top of the code 'useOwnAnimator'. I wrote this primarily when JOGL was having some concurrency issues adding and removing drawables from animators (since fixed). However I've still been using this implementation which I find gives a smoother frame rate, ymmv.
For me, when I zoom out to show my whole game world, and hold a rotate key down, I can really see the difference between the two implementations. With gl.setSwapInterval(1) also set it's even smoother! but then my 1st person mode seems to fail with mouse detection - work in progress :) Peter PS. tested under latest OSX with GLCanvs only package com.brickfarmer.gameclient.widgets; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import javax.media.opengl.GLAutoDrawable; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.AnimatorBase; import com.jogamp.opengl.util.FPSAnimator; public final class WHAnimator { private static final boolean useOwnAnimator = true; private static final int fpsReportingPeriodSeconds = 5; private final CopyOnWriteArraySet<GLAutoDrawable> drawables = new CopyOnWriteArraySet<GLAutoDrawable>(); private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private final ScheduledExecutorService fpsCounter = Executors.newSingleThreadScheduledExecutor(); private final int delayBetweenFramesMicroSeconds; private final AtomicBoolean animating = new AtomicBoolean(false); private final AtomicInteger frames = new AtomicInteger(0); private final AtomicInteger fps = new AtomicInteger(0); //old animator private AnimatorBase animator; private final AtomicInteger lastFrameCount = new AtomicInteger(0); Runnable displayJob = new Runnable() { public void run() { try { frames.incrementAndGet(); for (GLAutoDrawable drawable : drawables) { drawable.display(); } } catch (RuntimeException r) { r.printStackTrace(); } } }; Runnable fpsJob = new Runnable() { public void run() { int frameCount; if (useOwnAnimator) { frameCount = frames.getAndSet(0); } else { int newFrameCount = animator.getTotalFrames(); frameCount = newFrameCount - lastFrameCount.getAndSet(newFrameCount); } fps.set(frameCount/fpsReportingPeriodSeconds); System.out.println("Animator: "+drawables.size()+" scenes. "+frameCount+" frames in "+fpsReportingPeriodSeconds+"s. "+fps.get()+"fps"); } }; /** * Animate as fast as possible */ public WHAnimator() { delayBetweenFramesMicroSeconds = 1; if (!useOwnAnimator) { animator = new Animator(); } } /** * @param targetFramerate 60 means 60fps */ public WHAnimator(final int targetFramerate) { delayBetweenFramesMicroSeconds = 1000000/targetFramerate; //System.out.println("delay between frames: "+delayBetweenFrames); if (!useOwnAnimator) { animator = new FPSAnimator(targetFramerate, true); } } public void add(final GLAutoDrawable drawable) { if (useOwnAnimator) { drawables.add(drawable); } else { animator.add(drawable); } } public void remove(final GLAutoDrawable drawable) { if (useOwnAnimator) { drawables.remove(drawable); } else { animator.remove(drawable); } } public void start() { fpsCounter.scheduleAtFixedRate(fpsJob, 0, fpsReportingPeriodSeconds, TimeUnit.SECONDS); if (useOwnAnimator) { scheduler.scheduleAtFixedRate(displayJob, 0, delayBetweenFramesMicroSeconds, TimeUnit.MICROSECONDS); } else { animator.start(); } animating.set(true); } public void stop() { if (useOwnAnimator) { } else { animator.stop(); } animating.set(false); } public boolean isAnimating() { return (useOwnAnimator) ? animating.get() : animator.isAnimating(); } public int getFps() { return fps.get(); } }
Experiments: https://github.com/WhiteHexagon
|
Free forum by Nabble | Edit this page |