From 54ffe15dda5aebf5abb0a90a9f2a88d941decb76 Mon Sep 17 00:00:00 2001 From: shadowislord Date: Fri, 6 Jun 2014 20:39:37 -0400 Subject: [PATCH] * Switch to new native library loader * Deprecate old library loader * Add warning when the requested number of antialiasing samples cannot be satisfied * Cleaned up LwjglContext.determineMaxSamples() --- .../com/jme3/system/JmeDesktopSystem.java | 8 -- .../com/jme3/system/NativeLibraryLoader.java | 18 ++++ .../main/java/com/jme3/system/Natives.java | 7 ++ .../jme3/system/jogl/JoglAbstractDisplay.java | 2 + .../com/jme3/system/jogl/JoglContext.java | 17 +++ .../system/jogl/JoglNewtAbstractDisplay.java | 1 + .../jme3/system/jogl/JoglOffscreenBuffer.java | 1 + .../system/lwjgl/LwjglAbstractDisplay.java | 4 +- .../com/jme3/system/lwjgl/LwjglContext.java | 102 ++++++++---------- 9 files changed, 93 insertions(+), 67 deletions(-) diff --git a/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java b/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java index 5374e2496..f5de0c2ea 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java +++ b/jme3-desktop/src/main/java/com/jme3/system/JmeDesktopSystem.java @@ -307,13 +307,5 @@ public class JmeDesktopSystem extends JmeSystemDelegate { logger.log(Level.SEVERE, "Security error in creating log file", ex); } logger.log(Level.INFO, "Running on {0}", getFullName()); - - if (!lowPermissions) { - try { - Natives.extractNativeLibs(getPlatform(), settings); - } catch (IOException ex) { - logger.log(Level.SEVERE, "Error while copying native libraries", ex); - } - } } } diff --git a/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java b/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java index ed7994313..d12335594 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java +++ b/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java @@ -167,6 +167,24 @@ public final class NativeLibraryLoader { private NativeLibraryLoader() { } + /** + * Determine if native bullet is on the classpath. + * + * Currently the context extracts the native bullet libraries, so + * this method is needed to determine if it is needed. + * Ideally, native bullet should be responsible for its own natives. + * + * @return True native bullet is on the classpath, false otherwise. + */ + public static boolean isUsingNativeBullet() { + try { + Class clazz = Class.forName("com.jme3.bullet.util.NativeMeshUtil"); + return clazz != null; + } catch (ClassNotFoundException ex) { + return false; + } + } + /** * Specify a custom location where native libraries should * be extracted to. Ensure this is a unique path not used diff --git a/jme3-desktop/src/main/java/com/jme3/system/Natives.java b/jme3-desktop/src/main/java/com/jme3/system/Natives.java index 778436aab..423fda882 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/Natives.java +++ b/jme3-desktop/src/main/java/com/jme3/system/Natives.java @@ -41,7 +41,10 @@ import java.util.logging.Logger; /** * Helper class for extracting the natives (dll, so) from the jars. * This class should only be used internally. + * + * @deprecated Use {@link NativeLibraryLoader} instead. */ +@Deprecated public final class Natives { private static final Logger logger = Logger.getLogger(Natives.class.getName()); @@ -238,6 +241,10 @@ public final class Natives { } public static void extractNativeLibs(Platform platform, AppSettings settings) throws IOException { + if (true) { + throw new UnsupportedEncodingException("Now, why would you EVER want to do that?"); + } + String renderer = settings.getRenderer(); String audioRenderer = settings.getAudioRenderer(); boolean needLWJGL = false; diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java index 011fa53f2..8c6ec6e55 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java @@ -83,6 +83,8 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent protected boolean wasAnimating = false; protected void initGLCanvas() { + loadNatives(); + device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); //FIXME use the settings to know whether to use the max programmable profile diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java index 9e852c746..eca36d84b 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java @@ -40,16 +40,21 @@ import com.jme3.renderer.jogl.JoglRenderer; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.NanoTimer; +import com.jme3.system.NativeLibraryLoader; import com.jme3.system.SystemListener; import com.jme3.system.Timer; import java.nio.IntBuffer; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.media.opengl.GL; import javax.media.opengl.GL2GL3; import javax.media.opengl.GLContext; public abstract class JoglContext implements JmeContext { + private static final Logger logger = Logger.getLogger(JoglContext.class.getName()); + protected AtomicBoolean created = new AtomicBoolean(false); protected AtomicBoolean renderable = new AtomicBoolean(false); protected final Object createdLock = new Object(); @@ -63,6 +68,13 @@ public abstract class JoglContext implements JmeContext { protected MouseInput mouseInput; protected JoyInput joyInput; + public void loadNatives() { + // Not sure if need to load OpenAL here ... + if (NativeLibraryLoader.isUsingNativeBullet()) { + NativeLibraryLoader.loadNativeLibrary("bulletjme", true); + } + } + public void setSystemListener(SystemListener listener){ this.listener = listener; } @@ -162,6 +174,11 @@ public abstract class JoglContext implements JmeContext { samples = settings.getSamples(); int supportedSamples = determineMaxSamples(samples); if (supportedSamples < samples) { + logger.log(Level.WARNING, + "Couldn''t satisfy antialiasing samples requirement: x{0}. " + + "Video hardware only supports: x{1}", + new Object[]{samples, supportedSamples}); + samples = supportedSamples; } } diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java index 77b2c51ba..4899c9c39 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java @@ -79,6 +79,7 @@ public abstract class JoglNewtAbstractDisplay extends JoglContext implements GLE protected boolean wasAnimating = false; protected void initGLCanvas() { + loadNatives(); //FIXME use the settings to know whether to use the max programmable profile //then call GLProfile.getMaxProgrammable(true); //FIXME use the default profile only on embedded devices diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglOffscreenBuffer.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglOffscreenBuffer.java index 7f10c7161..ca3ebc31e 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglOffscreenBuffer.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglOffscreenBuffer.java @@ -121,6 +121,7 @@ public class JoglOffscreenBuffer extends JoglContext implements Runnable { } public void run(){ + loadNatives(); logger.log(Level.FINE, "Using JOGL {0}", NewtVersion.getInstance().getImplementationVersion()); initInThread(); while (!needClose.get()){ diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglAbstractDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglAbstractDisplay.java index 8197ae19c..2168cf0a2 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglAbstractDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglAbstractDisplay.java @@ -199,10 +199,12 @@ public abstract class LwjglAbstractDisplay extends LwjglContext implements Runna } public void run(){ - if (listener == null) + if (listener == null) { throw new IllegalStateException("SystemListener is not set on context!" + "Must set with JmeContext.setSystemListner()."); + } + loadNatives(); logger.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion()); if (!initInThread()) { logger.log(Level.SEVERE, "Display initialization failed. Cannot continue."); diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java index d9347f2c5..37640f3a5 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java @@ -42,6 +42,7 @@ import com.jme3.renderer.lwjgl.LwjglRenderer; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; +import com.jme3.system.NativeLibraryLoader; import com.jme3.system.SystemListener; import com.jme3.system.Timer; import java.util.concurrent.atomic.AtomicBoolean; @@ -115,7 +116,6 @@ public abstract class LwjglContext implements JmeContext { } protected int determineMaxSamples(int requestedSamples) { - boolean displayWasCurrent = false; try { // If we already have a valid context, determine samples using current // context. @@ -124,9 +124,10 @@ public abstract class LwjglContext implements JmeContext { return GL11.glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES); } else if (GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { return GL11.glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT); + } else { + // Unknown. + return Integer.MAX_VALUE; } - // Doesn't support any of the needed extensions .. continue down. - displayWasCurrent = true; } } catch (LWJGLException ex) { listener.handleError("Failed to check if display is current", ex); @@ -138,74 +139,59 @@ public abstract class LwjglContext implements JmeContext { } else { Pbuffer pb = null; - if (!displayWasCurrent) { - // OpenGL2 method: Create pbuffer and query samples - // from GL_ARB_framebuffer_object or GL_EXT_framebuffer_multisample. - try { - pb = new Pbuffer(1, 1, new PixelFormat(0, 0, 0), null); - pb.makeCurrent(); - - if (GLContext.getCapabilities().GL_ARB_framebuffer_object) { - return GL11.glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES); - } else if (GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { - return GL11.glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT); - } + // OpenGL2 method: Create pbuffer and query samples + // from GL_ARB_framebuffer_object or GL_EXT_framebuffer_multisample. + try { + pb = new Pbuffer(1, 1, new PixelFormat(0, 0, 0), null); + pb.makeCurrent(); - // OpenGL2 method failed. - } catch (LWJGLException ex) { - // Something else failed. - return Integer.MAX_VALUE; - } finally { - if (pb != null) { - pb.destroy(); - pb = null; - } + if (GLContext.getCapabilities().GL_ARB_framebuffer_object) { + return GL11.glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES); + } else if (GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { + return GL11.glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT); } - } - - // OpenGL1 method (DOESNT WORK RIGHT NOW ..) - requestedSamples = FastMath.nearestPowerOfTwo(requestedSamples); - try { - requestedSamples = Integer.MAX_VALUE; - /* - while (requestedSamples > 1) { - try { - pb = new Pbuffer(1, 1, new PixelFormat(16, 0, 8, 0, requestedSamples), null); - } catch (LWJGLException ex) { - if (ex.getMessage().startsWith("Failed to find ARB pixel format")) { - // Unsupported format, so continue. - requestedSamples = FastMath.nearestPowerOfTwo(requestedSamples / 2); - } else { - // Something else went wrong .. - return Integer.MAX_VALUE; - } - } finally { - if (pb != null){ - pb.destroy(); - pb = null; - } - } - }*/ - } finally { - if (displayWasCurrent) { - try { - Display.makeCurrent(); - } catch (LWJGLException ex) { - listener.handleError("Failed to make display current after checking samples", ex); - } + + // OpenGL2 method failed. + return Integer.MAX_VALUE; + } catch (LWJGLException ex) { + // Something else failed. + return Integer.MAX_VALUE; + } finally { + if (pb != null) { + pb.destroy(); } } - - return requestedSamples; } } + protected void loadNatives() { + if (JmeSystem.isLowPermissions()) { + return; + } + if ("LWJGL".equals(settings.getAudioRenderer())) { + NativeLibraryLoader.loadNativeLibrary("openal", true); + } + if (settings.useJoysticks()) { + NativeLibraryLoader.loadNativeLibrary("jinput", true); + NativeLibraryLoader.loadNativeLibrary("jinput-dx8", true); + } + if (NativeLibraryLoader.isUsingNativeBullet()) { + NativeLibraryLoader.loadNativeLibrary("bulletjme", true); + } + NativeLibraryLoader.loadNativeLibrary("lwjgl", true); + } + protected int getNumSamplesToUse() { int samples = 0; if (settings.getSamples() > 1){ samples = settings.getSamples(); int supportedSamples = determineMaxSamples(samples); if (supportedSamples < samples) { + logger.log(Level.WARNING, + "Couldn''t satisfy antialiasing samples requirement: x{0}. " + + "Video hardware only supports: x{1}", + new Object[]{samples, supportedSamples}); + samples = supportedSamples; } }