From 0869880c8e0167e4a765ab05b7b1f85a455e20bd Mon Sep 17 00:00:00 2001
From: Daniel Johansson
+ *
+ *
+ *
+ *
Timer
handles the system's time related functionality. This
+ * allows the calculation of the framerate. To keep the framerate calculation
+ * accurate, a call to update each frame is required. Timer
is a
+ * singleton object and must be created via the getTimer
method.
+ *
+ * @author Mark Powell
+ * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
+ */
+public class LwjglSmoothingTimer extends LwjglTimer {
+ private static final Logger logger = Logger.getLogger(LwjglSmoothingTimer.class
+ .getName());
+
+ private long lastFrameDiff;
+
+ //frame rate parameters.
+ private long oldTime;
+
+ private float lastTPF, lastFPS;
+
+ public static int TIMER_SMOOTHNESS = 32;
+
+ private long[] tpf;
+
+ private int smoothIndex;
+
+ private final static long LWJGL_TIMER_RES = 1;
+ private final static float INV_LWJGL_TIMER_RES = ( 1f / LWJGL_TIMER_RES );
+ private static float invTimerRezSmooth;
+
+ public final static long LWJGL_TIME_TO_NANOS = (1000000000 / LWJGL_TIMER_RES);
+
+ private long startTime;
+
+ private boolean allSmooth = false;
+
+ /**
+ * Constructor builds a Timer
object. All values will be
+ * initialized to it's default values.
+ */
+ public LwjglSmoothingTimer() {
+ reset();
+
+ //print timer resolution info
+ logger.log(Level.FINE, "Timer resolution: {0} ticks per second", LWJGL_TIMER_RES);
+ }
+
+ public void reset() {
+ lastFrameDiff = 0;
+ lastFPS = 0;
+ lastTPF = 0;
+
+ // init to -1 to indicate this is a new timer.
+ oldTime = -1;
+ //reset time
+ startTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
+
+ tpf = new long[TIMER_SMOOTHNESS];
+ smoothIndex = TIMER_SMOOTHNESS - 1;
+ invTimerRezSmooth = ( 1f / (LWJGL_TIMER_RES * TIMER_SMOOTHNESS));
+
+ // set tpf... -1 values will not be used for calculating the average in update()
+ for ( int i = tpf.length; --i >= 0; ) {
+ tpf[i] = -1;
+ }
+ }
+
+ /**
+ * @see Timer#getResolution()
+ */
+ public long getResolution() {
+ return LWJGL_TIMER_RES;
+ }
+
+ /**
+ * getFrameRate
returns the current frame rate since the last
+ * call to update
.
+ *
+ * @return the current frame rate.
+ */
+ public float getFrameRate() {
+ return lastFPS;
+ }
+
+ public float getTimePerFrame() {
+ return lastTPF;
+ }
+
+ /**
+ * update
recalulates the frame rate based on the previous
+ * call to update. It is assumed that update is called each frame.
+ */
+ public void update() {
+ long newTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
+ long oldTime = this.oldTime;
+ this.oldTime = newTime;
+ if ( oldTime == -1 ) {
+ // For the first frame use 60 fps. This value will not be counted in further averages.
+ // This is done so initialization code between creating the timer and the first
+ // frame is not counted as a single frame on it's own.
+ lastTPF = 1 / 60f;
+ lastFPS = 1f / lastTPF;
+ return;
+ }
+
+ long frameDiff = newTime - oldTime;
+ long lastFrameDiff = this.lastFrameDiff;
+ if ( lastFrameDiff > 0 && frameDiff > lastFrameDiff *100 ) {
+ frameDiff = lastFrameDiff *100;
+ }
+ this.lastFrameDiff = frameDiff;
+ tpf[smoothIndex] = frameDiff;
+ smoothIndex--;
+ if ( smoothIndex < 0 ) {
+ smoothIndex = tpf.length - 1;
+ }
+
+ lastTPF = 0.0f;
+ if (!allSmooth) {
+ int smoothCount = 0;
+ for ( int i = tpf.length; --i >= 0; ) {
+ if ( tpf[i] != -1 ) {
+ lastTPF += tpf[i];
+ smoothCount++;
+ }
+ }
+ if (smoothCount == tpf.length)
+ allSmooth = true;
+ lastTPF *= ( INV_LWJGL_TIMER_RES / smoothCount );
+ } else {
+ for ( int i = tpf.length; --i >= 0; ) {
+ if ( tpf[i] != -1 ) {
+ lastTPF += tpf[i];
+ }
+ }
+ lastTPF *= invTimerRezSmooth;
+ }
+ if ( lastTPF < FastMath.FLT_EPSILON ) {
+ lastTPF = FastMath.FLT_EPSILON;
+ }
+
+ lastFPS = 1f / lastTPF;
+ }
+
+ /**
+ * toString
returns the string representation of this timer
+ * in the format: Timer
handles the system's time related functionality. This
+ * allows the calculation of the framerate. To keep the framerate calculation
+ * accurate, a call to update each frame is required. Timer
is a
+ * singleton object and must be created via the getTimer
method.
+ *
+ * @author Mark Powell
+ * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
+ */
+public class LwjglTimer extends Timer {
+
+ private static final Logger logger = Logger.getLogger(LwjglTimer.class.getName());
+
+ //frame rate parameters.
+ private long oldTime;
+ private long startTime;
+
+ private float lastTPF, lastFPS;
+
+ private final static long LWJGL_TIMER_RES = 1;
+ private final static float INV_LWJGL_TIMER_RES = ( 1f / LWJGL_TIMER_RES );
+ public final static long LWJGL_TIME_TO_NANOS = (1000000000 / LWJGL_TIMER_RES);
+
+ /**
+ * Constructor builds a Timer
object. All values will be
+ * initialized to it's default values.
+ */
+ public LwjglTimer() {
+ reset();
+ logger.log(Level.FINE, "Timer resolution: {0} ticks per second", LWJGL_TIMER_RES);
+ }
+
+ public void reset() {
+ startTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
+ oldTime = getTime();
+ }
+
+ @Override
+ public float getTimeInSeconds() {
+ return getTime() * INV_LWJGL_TIMER_RES;
+ }
+
+ /**
+ * @see Timer#getTime()
+ */
+ public long getTime() {
+ return ((long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS) - startTime);
+ }
+
+ /**
+ * @see Timer#getResolution()
+ */
+ public long getResolution() {
+ return LWJGL_TIMER_RES;
+ }
+
+ /**
+ * getFrameRate
returns the current frame rate since the last
+ * call to update
.
+ *
+ * @return the current frame rate.
+ */
+ public float getFrameRate() {
+ return lastFPS;
+ }
+
+ public float getTimePerFrame() {
+ return lastTPF;
+ }
+
+ /**
+ * update
recalulates the frame rate based on the previous
+ * call to update. It is assumed that update is called each frame.
+ */
+ public void update() {
+ long curTime = getTime();
+ lastTPF = (curTime - oldTime) * (1.0f / LWJGL_TIMER_RES);
+ lastFPS = 1.0f / lastTPF;
+ oldTime = curTime;
+ }
+
+ /**
+ * toString
returns the string representation of this timer
+ * in the format: Timer
handles the system's time related functionality. This
+ * allows the calculation of the framerate. To keep the framerate calculation
+ * accurate, a call to update each frame is required. Timer
is a
+ * singleton object and must be created via the getTimer
method.
+ *
+ * @author Mark Powell
+ * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
+ */
+public class LwjglSmoothingTimer extends LwjglTimer {
+ private static final Logger logger = Logger.getLogger(LwjglSmoothingTimer.class
+ .getName());
+
+ private long lastFrameDiff;
+
+ //frame rate parameters.
+ private long oldTime;
+
+ private float lastTPF, lastFPS;
+
+ public static int TIMER_SMOOTHNESS = 32;
+
+ private long[] tpf;
+
+ private int smoothIndex;
+
+ private final static long LWJGL_TIMER_RES = 1;
+ private final static float INV_LWJGL_TIMER_RES = ( 1f / LWJGL_TIMER_RES );
+ private static float invTimerRezSmooth;
+
+ public final static long LWJGL_TIME_TO_NANOS = (1000000000 / LWJGL_TIMER_RES);
+
+ private long startTime;
+
+ private boolean allSmooth = false;
+
+ /**
+ * Constructor builds a Timer
object. All values will be
+ * initialized to it's default values.
+ */
+ public LwjglSmoothingTimer() {
+ reset();
+
+ //print timer resolution info
+ logger.log(Level.FINE, "Timer resolution: {0} ticks per second", LWJGL_TIMER_RES);
+ }
+
+ public void reset() {
+ lastFrameDiff = 0;
+ lastFPS = 0;
+ lastTPF = 0;
+
+ // init to -1 to indicate this is a new timer.
+ oldTime = -1;
+ //reset time
+ startTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
+
+ tpf = new long[TIMER_SMOOTHNESS];
+ smoothIndex = TIMER_SMOOTHNESS - 1;
+ invTimerRezSmooth = ( 1f / (LWJGL_TIMER_RES * TIMER_SMOOTHNESS));
+
+ // set tpf... -1 values will not be used for calculating the average in update()
+ for ( int i = tpf.length; --i >= 0; ) {
+ tpf[i] = -1;
+ }
+ }
+
+ /**
+ * @see Timer#getResolution()
+ */
+ public long getResolution() {
+ return LWJGL_TIMER_RES;
+ }
+
+ /**
+ * getFrameRate
returns the current frame rate since the last
+ * call to update
.
+ *
+ * @return the current frame rate.
+ */
+ public float getFrameRate() {
+ return lastFPS;
+ }
+
+ public float getTimePerFrame() {
+ return lastTPF;
+ }
+
+ /**
+ * update
recalulates the frame rate based on the previous
+ * call to update. It is assumed that update is called each frame.
+ */
+ public void update() {
+ long newTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
+ long oldTime = this.oldTime;
+ this.oldTime = newTime;
+ if ( oldTime == -1 ) {
+ // For the first frame use 60 fps. This value will not be counted in further averages.
+ // This is done so initialization code between creating the timer and the first
+ // frame is not counted as a single frame on it's own.
+ lastTPF = 1 / 60f;
+ lastFPS = 1f / lastTPF;
+ return;
+ }
+
+ long frameDiff = newTime - oldTime;
+ long lastFrameDiff = this.lastFrameDiff;
+ if ( lastFrameDiff > 0 && frameDiff > lastFrameDiff *100 ) {
+ frameDiff = lastFrameDiff *100;
+ }
+ this.lastFrameDiff = frameDiff;
+ tpf[smoothIndex] = frameDiff;
+ smoothIndex--;
+ if ( smoothIndex < 0 ) {
+ smoothIndex = tpf.length - 1;
+ }
+
+ lastTPF = 0.0f;
+ if (!allSmooth) {
+ int smoothCount = 0;
+ for ( int i = tpf.length; --i >= 0; ) {
+ if ( tpf[i] != -1 ) {
+ lastTPF += tpf[i];
+ smoothCount++;
+ }
+ }
+ if (smoothCount == tpf.length)
+ allSmooth = true;
+ lastTPF *= ( INV_LWJGL_TIMER_RES / smoothCount );
+ } else {
+ for ( int i = tpf.length; --i >= 0; ) {
+ if ( tpf[i] != -1 ) {
+ lastTPF += tpf[i];
+ }
+ }
+ lastTPF *= invTimerRezSmooth;
+ }
+ if ( lastTPF < FastMath.FLT_EPSILON ) {
+ lastTPF = FastMath.FLT_EPSILON;
+ }
+
+ lastFPS = 1f / lastTPF;
+ }
+
+ /**
+ * toString
returns the string representation of this timer
+ * in the format: Timer
handles the system's time related functionality. This
+ * allows the calculation of the framerate. To keep the framerate calculation
+ * accurate, a call to update each frame is required. Timer
is a
+ * singleton object and must be created via the getTimer
method.
+ *
+ * @author Mark Powell
+ * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
+ */
+public class LwjglTimer extends Timer {
+
+ private static final Logger logger = Logger.getLogger(LwjglTimer.class.getName());
+
+ //frame rate parameters.
+ private long oldTime;
+ private long startTime;
+
+ private float lastTPF, lastFPS;
+
+ private final static long LWJGL_TIMER_RES = 1;
+ private final static float INV_LWJGL_TIMER_RES = ( 1f / LWJGL_TIMER_RES );
+ public final static long LWJGL_TIME_TO_NANOS = (1000000000 / LWJGL_TIMER_RES);
+
+ /**
+ * Constructor builds a Timer
object. All values will be
+ * initialized to it's default values.
+ */
+ public LwjglTimer() {
+ reset();
+ logger.log(Level.FINE, "Timer resolution: {0} ticks per second", LWJGL_TIMER_RES);
+ }
+
+ public void reset() {
+ startTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
+ oldTime = getTime();
+ }
+
+ @Override
+ public float getTimeInSeconds() {
+ return getTime() * INV_LWJGL_TIMER_RES;
+ }
+
+ /**
+ * @see Timer#getTime()
+ */
+ public long getTime() {
+ return ((long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS) - startTime);
+ }
+
+ /**
+ * @see Timer#getResolution()
+ */
+ public long getResolution() {
+ return LWJGL_TIMER_RES;
+ }
+
+ /**
+ * getFrameRate
returns the current frame rate since the last
+ * call to update
.
+ *
+ * @return the current frame rate.
+ */
+ public float getFrameRate() {
+ return lastFPS;
+ }
+
+ public float getTimePerFrame() {
+ return lastTPF;
+ }
+
+ /**
+ * update
recalulates the frame rate based on the previous
+ * call to update. It is assumed that update is called each frame.
+ */
+ public void update() {
+ long curTime = getTime();
+ lastTPF = (curTime - oldTime) * (1.0f / LWJGL_TIMER_RES);
+ lastFPS = 1.0f / lastTPF;
+ oldTime = curTime;
+ }
+
+ /**
+ * toString
returns the string representation of this timer
+ * in the format:
* Represents the direction the light is shining.
* (1, 0, 0) would represent light shining in the +X direction.
- *
+ *
* @param dir the direction of the light.
*/
public final void setDirection(Vector3f dir){
@@ -113,12 +113,12 @@ public class DirectionalLight extends Light {
public boolean intersectsBox(BoundingBox box, TempVars vars) {
return true;
}
-
+
@Override
public boolean intersectsFrustum(Camera camera, TempVars vars) {
return true;
}
-
+
@Override
public Type getType() {
return Type.Directional;
From d8e964b2f0f7b1c7e729fcd748cbc9c6ea062596 Mon Sep 17 00:00:00 2001
From: Daniel Johansson Timer
handles the system's time related functionality. This
- * allows the calculation of the framerate. To keep the framerate calculation
- * accurate, a call to update each frame is required. Timer
is a
- * singleton object and must be created via the getTimer
method.
- *
- * @author Mark Powell
- * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
- */
-public class LwjglSmoothingTimer extends LwjglTimer {
- private static final Logger logger = Logger.getLogger(LwjglSmoothingTimer.class
- .getName());
-
- private long lastFrameDiff;
-
- //frame rate parameters.
- private long oldTime;
-
- private float lastTPF, lastFPS;
-
- public static int TIMER_SMOOTHNESS = 32;
-
- private long[] tpf;
-
- private int smoothIndex;
-
- private final static long LWJGL_TIMER_RES = 1;
- private final static float INV_LWJGL_TIMER_RES = ( 1f / LWJGL_TIMER_RES );
- private static float invTimerRezSmooth;
-
- public final static long LWJGL_TIME_TO_NANOS = (1000000000 / LWJGL_TIMER_RES);
-
- private long startTime;
-
- private boolean allSmooth = false;
-
- /**
- * Constructor builds a Timer
object. All values will be
- * initialized to it's default values.
- */
- public LwjglSmoothingTimer() {
- reset();
-
- //print timer resolution info
- logger.log(Level.FINE, "Timer resolution: {0} ticks per second", LWJGL_TIMER_RES);
- }
-
- public void reset() {
- lastFrameDiff = 0;
- lastFPS = 0;
- lastTPF = 0;
-
- // init to -1 to indicate this is a new timer.
- oldTime = -1;
- //reset time
- startTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
-
- tpf = new long[TIMER_SMOOTHNESS];
- smoothIndex = TIMER_SMOOTHNESS - 1;
- invTimerRezSmooth = ( 1f / (LWJGL_TIMER_RES * TIMER_SMOOTHNESS));
-
- // set tpf... -1 values will not be used for calculating the average in update()
- for ( int i = tpf.length; --i >= 0; ) {
- tpf[i] = -1;
- }
- }
-
- /**
- * @see Timer#getResolution()
- */
- public long getResolution() {
- return LWJGL_TIMER_RES;
- }
-
- /**
- * getFrameRate
returns the current frame rate since the last
- * call to update
.
- *
- * @return the current frame rate.
- */
- public float getFrameRate() {
- return lastFPS;
- }
-
- public float getTimePerFrame() {
- return lastTPF;
- }
-
- /**
- * update
recalulates the frame rate based on the previous
- * call to update. It is assumed that update is called each frame.
- */
- public void update() {
- long newTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
- long oldTime = this.oldTime;
- this.oldTime = newTime;
- if ( oldTime == -1 ) {
- // For the first frame use 60 fps. This value will not be counted in further averages.
- // This is done so initialization code between creating the timer and the first
- // frame is not counted as a single frame on it's own.
- lastTPF = 1 / 60f;
- lastFPS = 1f / lastTPF;
- return;
- }
-
- long frameDiff = newTime - oldTime;
- long lastFrameDiff = this.lastFrameDiff;
- if ( lastFrameDiff > 0 && frameDiff > lastFrameDiff *100 ) {
- frameDiff = lastFrameDiff *100;
- }
- this.lastFrameDiff = frameDiff;
- tpf[smoothIndex] = frameDiff;
- smoothIndex--;
- if ( smoothIndex < 0 ) {
- smoothIndex = tpf.length - 1;
- }
-
- lastTPF = 0.0f;
- if (!allSmooth) {
- int smoothCount = 0;
- for ( int i = tpf.length; --i >= 0; ) {
- if ( tpf[i] != -1 ) {
- lastTPF += tpf[i];
- smoothCount++;
- }
- }
- if (smoothCount == tpf.length)
- allSmooth = true;
- lastTPF *= ( INV_LWJGL_TIMER_RES / smoothCount );
- } else {
- for ( int i = tpf.length; --i >= 0; ) {
- if ( tpf[i] != -1 ) {
- lastTPF += tpf[i];
- }
- }
- lastTPF *= invTimerRezSmooth;
- }
- if ( lastTPF < FastMath.FLT_EPSILON ) {
- lastTPF = FastMath.FLT_EPSILON;
- }
-
- lastFPS = 1f / lastTPF;
- }
-
- /**
- * toString
returns the string representation of this timer
- * in the format:
- *
- * jme.utility.Timer@1db699b
- * Time: {LONG}
- * FPS: {LONG}
- *
- * @return the string representation of this object.
- */
- @Override
- public String toString() {
- String string = super.toString();
- string += "\nTime: " + oldTime;
- string += "\nFPS: " + getFrameRate();
- return string;
- }
-}
\ No newline at end of file
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglTimer.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglTimer.java
deleted file mode 100644
index c4a0e5025..000000000
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglTimer.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.system.lwjgl;
-
-import com.jme3.system.Timer;
-import org.lwjgl.glfw.GLFW;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Timer
handles the system's time related functionality. This
- * allows the calculation of the framerate. To keep the framerate calculation
- * accurate, a call to update each frame is required. Timer
is a
- * singleton object and must be created via the getTimer
method.
- *
- * @author Mark Powell
- * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
- */
-public class LwjglTimer extends Timer {
-
- private static final Logger logger = Logger.getLogger(LwjglTimer.class.getName());
-
- //frame rate parameters.
- private long oldTime;
- private long startTime;
-
- private float lastTPF, lastFPS;
-
- private final static long LWJGL_TIMER_RES = 1;
- private final static float INV_LWJGL_TIMER_RES = ( 1f / LWJGL_TIMER_RES );
- public final static long LWJGL_TIME_TO_NANOS = (1000000000 / LWJGL_TIMER_RES);
-
- /**
- * Constructor builds a Timer
object. All values will be
- * initialized to it's default values.
- */
- public LwjglTimer() {
- reset();
- logger.log(Level.FINE, "Timer resolution: {0} ticks per second", LWJGL_TIMER_RES);
- }
-
- public void reset() {
- startTime = (long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS);
- oldTime = getTime();
- }
-
- @Override
- public float getTimeInSeconds() {
- return getTime() * INV_LWJGL_TIMER_RES;
- }
-
- /**
- * @see Timer#getTime()
- */
- public long getTime() {
- return ((long) (GLFW.glfwGetTime() * LWJGL_TIME_TO_NANOS) - startTime);
- }
-
- /**
- * @see Timer#getResolution()
- */
- public long getResolution() {
- return LWJGL_TIMER_RES;
- }
-
- /**
- * getFrameRate
returns the current frame rate since the last
- * call to update
.
- *
- * @return the current frame rate.
- */
- public float getFrameRate() {
- return lastFPS;
- }
-
- public float getTimePerFrame() {
- return lastTPF;
- }
-
- /**
- * update
recalulates the frame rate based on the previous
- * call to update. It is assumed that update is called each frame.
- */
- public void update() {
- long curTime = getTime();
- lastTPF = (curTime - oldTime) * (1.0f / LWJGL_TIMER_RES);
- lastFPS = 1.0f / lastTPF;
- oldTime = curTime;
- }
-
- /**
- * toString
returns the string representation of this timer
- * in the format:
- *
- * jme.utility.Timer@1db699b
- * Time: {LONG}
- * FPS: {LONG}
- *
- * @return the string representation of this object.
- */
- @Override
- public String toString() {
- String string = super.toString();
- string += "\nTime: " + oldTime;
- string += "\nFPS: " + getFrameRate();
- return string;
- }
-}
\ No newline at end of file
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
index c5cb35e03..2f00eb700 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
@@ -42,6 +42,7 @@ import com.jme3.input.lwjgl.GlfwMouseInput;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
import com.jme3.system.JmeSystem;
+import com.jme3.system.NanoTimer;
import org.lwjgl.Sys;
import org.lwjgl.glfw.*;
@@ -73,6 +74,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
protected boolean allowSwapBuffers = false;
private long window = -1;
private final JmeContext.Type type;
+ private int frameRateLimit = -1;
+ private double frameSleepTime;
private GLFWErrorCallback errorCallback;
private GLFWWindowSizeCallback windowSizeCallback;
@@ -160,16 +163,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits());
glfwWindowHint(GLFW_SAMPLES, settings.getSamples());
glfwWindowHint(GLFW_STEREO, settings.useStereo3D() ? GL_TRUE : GL_FALSE);
-
- int frameRateCap = settings.getFrameRate();
-
- if (!autoFlush) {
- frameRateCap = 20;
- }
-
- if (frameRateCap > 0) {
- glfwWindowHint(GLFW_REFRESH_RATE, frameRateCap);
- }
+ glfwWindowHint(GLFW_REFRESH_RATE, settings.getFrequency());
// Not sure how else to support bits per pixel
if (settings.getBitsPerPixel() == 24) {
@@ -289,7 +283,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
});
}
- timer = new LwjglTimer();
+ timer = new NanoTimer();
// For canvas, this will create a pbuffer,
// allowing us to query information.
@@ -303,7 +297,6 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
} catch (Exception ex) {
try {
if (window != -1) {
- //glfwSetWindowShouldClose(window, GL_TRUE);
glfwDestroyWindow(window);
}
} catch (Exception ex2) {
@@ -360,11 +353,41 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
if (renderer != null) {
renderer.postFrame();
}
+
+ if (autoFlush) {
+ if (frameRateLimit != getSettings().getFrameRate()) {
+ setFrameRateLimit(getSettings().getFrameRate());
+ }
+ } else if (frameRateLimit != 20) {
+ setFrameRateLimit(20);
+ }
+
+ // If software frame rate limiting has been asked for, lets calculate sleep time based on a base value calculated
+ // from 1000 / frameRateLimit in milliseconds subtracting the time it has taken to render last frame.
+ // This gives an approximate limit within 3 fps of the given frame rate limit.
+ if (frameRateLimit > 0) {
+ final double sleep = frameSleepTime - (timer.getTimePerFrame() / 1000.0);
+ final long sleepMillis = (long) sleep;
+ final int additionalNanos = (int) ((sleep - sleepMillis) * 1000000.0);
+
+ if (sleepMillis >= 0 && additionalNanos >= 0) {
+ try {
+ Thread.sleep(sleepMillis, additionalNanos);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ }
+ }
+
+ private void setFrameRateLimit(int frameRateLimit) {
+ this.frameRateLimit = frameRateLimit;
+ frameSleepTime = 1000.0 / this.frameRateLimit;
}
/**
* De-initialize in the OpenGL thread.
*/
+
protected void deinitInThread() {
destroyContext();
@@ -379,7 +402,6 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
+ "Must set with JmeContext.setSystemListener().");
}
- registerNatives();
loadNatives();
LOGGER.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion());
@@ -445,6 +467,9 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
return window;
}
+
+ // TODO: Implement support for window icon when GLFW supports it.
+
private ByteBuffer[] imagesToByteBuffers(Object[] images) {
ByteBuffer[] out = new ByteBuffer[images.length];
for (int i = 0; i < images.length; i++) {
From c375974a9a88d9484122e358c89b7ea2db5fd98b Mon Sep 17 00:00:00 2001
From: Daniel Johansson