浏览代码

Miscellaneous OpenGL ES fixes (#720)

* Use correct HALF_FLOAT constant for GLES
* Support GLTracer and GL debug in Android
* Support instancing in GLTracer
* Don't use unsupported TEXTURE_{BASE,MAX}_LEVEL in GLES
* Support ABGR8 using swizzle extension
* Move glFramebufferTextureLayer to GLFbo
* Avoid RGB111110F in filters unless its actually supported
* Use the same depth format in all places in FPP
* Print the object with the problem in NativeObjectManager
* JMException does not exist on Android
Kirill Vainer 8 年之前
父节点
当前提交
6127f7eb7a
共有 26 个文件被更改,包括 133 次插入77 次删除
  1. 5 0
      jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java
  2. 8 2
      jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
  3. 2 5
      jme3-core/src/main/java/com/jme3/post/Filter.java
  4. 17 8
      jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java
  5. 1 2
      jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java
  6. 2 0
      jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java
  7. 0 1
      jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java
  8. 0 6
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java
  9. 7 0
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java
  10. 1 0
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java
  11. 1 0
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLFbo.java
  12. 18 8
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java
  13. 11 9
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
  14. 14 10
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java
  15. 9 2
      jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java
  16. 2 2
      jme3-core/src/main/java/com/jme3/util/NativeObjectManager.java
  17. 5 0
      jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java
  18. 0 6
      jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java
  19. 5 0
      jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLFbo.java
  20. 0 5
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
  21. 6 0
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java
  22. 5 0
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java
  23. 0 7
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
  24. 6 0
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java
  25. 5 0
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java
  26. 3 4
      jme3-terrain/src/main/java/com/jme3/terrain/heightmap/MidpointDisplacementHeightMap.java

+ 5 - 0
jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java

@@ -561,4 +561,9 @@ public class AndroidGL implements GL, GLExt, GLFbo {
     public void glBlendEquationSeparate(int colorMode, int alphaMode) {
         GLES20.glBlendEquationSeparate(colorMode, alphaMode);
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int target, int attachment, int texture, int level, int layer) {
+        throw new UnsupportedOperationException("OpenGL ES 2 does not support texture arrays");
+    }
 }

+ 8 - 2
jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java

@@ -53,9 +53,11 @@ import com.jme3.input.dummy.DummyKeyInput;
 import com.jme3.input.dummy.DummyMouseInput;
 import com.jme3.renderer.android.AndroidGL;
 import com.jme3.renderer.opengl.GL;
+import com.jme3.renderer.opengl.GLDebugES;
 import com.jme3.renderer.opengl.GLExt;
 import com.jme3.renderer.opengl.GLFbo;
 import com.jme3.renderer.opengl.GLRenderer;
+import com.jme3.renderer.opengl.GLTracer;
 import com.jme3.system.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
@@ -195,8 +197,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
 
         timer = new NanoTimer();
         Object gl = new AndroidGL();
-        // gl = GLTracer.createGlesTracer((GL)gl, (GLExt)gl);
-        // gl = new GLDebugES((GL)gl, (GLExt)gl);
+        if (settings.getBoolean("GraphicsDebug")) {
+            gl = new GLDebugES((GL) gl, (GLExt) gl, (GLFbo) gl);
+        }
+        if (settings.getBoolean("GraphicsTrace")) {
+            gl = GLTracer.createGlesTracer(gl, GL.class, GLFbo.class, GLExt.class);
+        }
         renderer = new GLRenderer((GL)gl, (GLExt)gl, (GLFbo)gl);
         renderer.initialize();
 

+ 2 - 5
jme3-core/src/main/java/com/jme3/post/Filter.java

@@ -213,13 +213,10 @@ public abstract class Filter implements Savable {
     }
 
     /**
-     * returns the default pass texture format
-     * default is {@link Format#RGB111110F}
-     * 
-     * @return
+     * returns the default pass texture format.
      */
     protected Format getDefaultPassTextureFormat() {
-        return Format.RGB111110F;
+        return processor.getDefaultPassTextureFormat();
     }
 
     /**

+ 17 - 8
jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java

@@ -66,7 +66,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
     private FrameBuffer renderFrameBuffer;
     private Texture2D filterTexture;
     private Texture2D depthTexture;
-    private SafeArrayList<Filter> filters = new SafeArrayList<Filter>(Filter.class);
+    private SafeArrayList<Filter> filters = new SafeArrayList<>(Filter.class);
     private AssetManager assetManager;        
     private Picture fsQuad;
     private boolean computeDepth = false;
@@ -85,6 +85,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
     private AppProfiler prof;
 
     private Format fbFormat = Format.RGB111110F;
+    private Format depthFormat = Format.Depth;
     
     /**
      * Create a FilterProcessor 
@@ -143,9 +144,13 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
         fsQuad = new Picture("filter full screen quad");
         fsQuad.setWidth(1);
         fsQuad.setHeight(1);
-        
-        if (fbFormat == Format.RGB111110F && !renderer.getCaps().contains(Caps.PackedFloatTexture)) {
-            fbFormat = Format.RGB8;
+
+        if (!renderer.getCaps().contains(Caps.PackedFloatTexture)) {
+            if (!renderer.getCaps().contains(Caps.FloatTexture)) {
+                fbFormat = Format.RGB8;
+            } else {
+                fbFormat = Format.RGB16F;
+            }
         }
         
         Camera cam = vp.getCamera();
@@ -161,6 +166,10 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
         reshape(vp, cam.getWidth(), cam.getHeight());
     }
 
+    public Format getDefaultPassTextureFormat() {
+        return fbFormat;
+    }
+    
     /**
      * init the given filter
      * @param filter
@@ -170,7 +179,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
         filter.setProcessor(this);
         if (filter.isRequiresDepthTexture()) {
             if (!computeDepth && renderFrameBuffer != null) {
-                depthTexture = new Texture2D(width, height, Format.Depth24);
+                depthTexture = new Texture2D(width, height, depthFormat);
                 renderFrameBuffer.setDepthTexture(depthTexture);
             }
             computeDepth = true;
@@ -469,20 +478,20 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
             renderFrameBufferMS = new FrameBuffer(width, height, numSamples);
             if (caps.contains(Caps.OpenGL32)) {
                 Texture2D msColor = new Texture2D(width, height, numSamples, fbFormat);
-                Texture2D msDepth = new Texture2D(width, height, numSamples, Format.Depth);
+                Texture2D msDepth = new Texture2D(width, height, numSamples, depthFormat);
                 renderFrameBufferMS.setDepthTexture(msDepth);
                 renderFrameBufferMS.setColorTexture(msColor);
                 filterTexture = msColor;
                 depthTexture = msDepth;
             } else {
-                renderFrameBufferMS.setDepthBuffer(Format.Depth);
+                renderFrameBufferMS.setDepthBuffer(depthFormat);
                 renderFrameBufferMS.setColorBuffer(fbFormat);
             }
         }
 
         if (numSamples <= 1 || !caps.contains(Caps.OpenGL32)) {
             renderFrameBuffer = new FrameBuffer(width, height, 1);
-            renderFrameBuffer.setDepthBuffer(Format.Depth);
+            renderFrameBuffer.setDepthBuffer(depthFormat);
             filterTexture = new Texture2D(width, height, fbFormat);
             renderFrameBuffer.setColorTexture(filterTexture);
         }

+ 1 - 2
jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java

@@ -50,6 +50,7 @@ public interface GL {
     public static final int GL_ARRAY_BUFFER = 0x8892;
     public static final int GL_BACK = 0x405;
     public static final int GL_BLEND = 0xBE2;
+    public static final int GL_BLUE = 0x1905;
     public static final int GL_BYTE = 0x1400;
     public static final int GL_CLAMP_TO_EDGE = 0x812F;
     public static final int GL_COLOR_BUFFER_BIT = 0x4000;
@@ -173,9 +174,7 @@ public interface GL {
     public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
     public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
     public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
-    public static final int GL_TEXTURE_BASE_LEVEL = 0x813C;
     public static final int GL_TEXTURE_MAG_FILTER = 0x2800;
-    public static final int GL_TEXTURE_MAX_LEVEL = 0x813D;
     public static final int GL_TEXTURE_MIN_FILTER = 0x2801;
     public static final int GL_TEXTURE_WRAP_S = 0x2802;
     public static final int GL_TEXTURE_WRAP_T = 0x2803;

+ 2 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java

@@ -65,6 +65,8 @@ public interface GL2 extends GL {
     public static final int GL_STACK_OVERFLOW = 0x503;
     public static final int GL_STACK_UNDERFLOW = 0x504;
     public static final int GL_TEXTURE_3D = 0x806F;
+    public static final int GL_TEXTURE_BASE_LEVEL = 0x813C;
+    public static final int GL_TEXTURE_MAX_LEVEL = 0x813D;
     public static final int GL_POINT_SPRITE = 0x8861;
     public static final int GL_TEXTURE_COMPARE_FUNC = 0x884D;
     public static final int GL_TEXTURE_COMPARE_MODE = 0x884C;

+ 0 - 1
jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java

@@ -86,7 +86,6 @@ public interface GL3 extends GL2 {
     public void glBindFragDataLocation(int param1, int param2, String param3); /// GL3+
     public void glBindVertexArray(int param1); /// GL3+
     public void glDeleteVertexArrays(IntBuffer arrays); /// GL3+
-    public void glFramebufferTextureLayer(int param1, int param2, int param3, int param4, int param5); /// GL3+
     public void glGenVertexArrays(IntBuffer param1); /// GL3+
     public String glGetString(int param1, int param2); /// GL3+
 }

+ 0 - 6
jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java

@@ -95,12 +95,6 @@ public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 {
         checkError();
     }
 
-    @Override
-    public void glFramebufferTextureLayer(int param1, int param2, int param3, int param4, int param5) {
-        gl3.glFramebufferTextureLayer(param1, param2, param3, param4, param5);
-        checkError();
-    }
-
     public void glBlendEquationSeparate(int colorMode, int alphaMode) {
         gl.glBlendEquationSeparate(colorMode, alphaMode);
         checkError();

+ 7 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java

@@ -598,8 +598,15 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
         return sync;
     }
 
+    @Override
     public void glBlendEquationSeparate(int colorMode, int alphaMode) {
         gl.glBlendEquationSeparate(colorMode, alphaMode);
         checkError();
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) {
+        glfbo.glFramebufferTextureLayerEXT(param1, param2, param3, param4, param5);
+        checkError();
+    }
 }

+ 1 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java

@@ -61,6 +61,7 @@ public interface GLExt {
 	public static final int GL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x8DBA;
 	public static final int GL_FRAMEBUFFER_SRGB_EXT = 0x8DB9;
 	public static final int GL_HALF_FLOAT_ARB = 0x140B;
+        public static final int GL_HALF_FLOAT_OES = 0x8D61;
 	public static final int GL_LUMINANCE16F_ARB = 0x881E;
 	public static final int GL_LUMINANCE32F_ARB = 0x8818;
 	public static final int GL_LUMINANCE_ALPHA16F_ARB = 0x881F;

+ 1 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLFbo.java

@@ -89,6 +89,7 @@ public interface GLFbo {
     public void glDeleteRenderbuffersEXT(IntBuffer param1);
     public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4);
     public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5);
+    public void glFramebufferTextureLayerEXT(int target, int attachment, int texture, int level, int layer);
     public void glGenFramebuffersEXT(IntBuffer param1);
     public void glGenRenderbuffersEXT(IntBuffer param1);
     public void glGenerateMipmapEXT(int param1);

+ 18 - 8
jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java

@@ -103,14 +103,19 @@ public final class GLImageFormats {
     public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
         GLImageFormat[][] formatToGL = new GLImageFormat[2][Image.Format.values().length];
         
+        int halfFloatFormat = GLExt.GL_HALF_FLOAT_ARB;
+        if (caps.contains(Caps.OpenGLES20)) {
+            halfFloatFormat = GLExt.GL_HALF_FLOAT_OES;
+        }
+        
         // Core Profile Formats (supported by both OpenGL Core 3.3 and OpenGL ES 3.0+)
         if (caps.contains(Caps.CoreProfile)) {
             formatSwiz(formatToGL,     Format.Alpha8,               GL3.GL_R8,                 GL.GL_RED,       GL.GL_UNSIGNED_BYTE);
             formatSwiz(formatToGL,     Format.Luminance8,           GL3.GL_R8,                 GL.GL_RED,       GL.GL_UNSIGNED_BYTE);
             formatSwiz(formatToGL,     Format.Luminance8Alpha8,     GL3.GL_RG8,                GL3.GL_RG,       GL.GL_UNSIGNED_BYTE);
-            formatSwiz(formatToGL,     Format.Luminance16F,         GL3.GL_R16F,               GL.GL_RED,       GLExt.GL_HALF_FLOAT_ARB);
+            formatSwiz(formatToGL,     Format.Luminance16F,         GL3.GL_R16F,               GL.GL_RED,       halfFloatFormat);
             formatSwiz(formatToGL,     Format.Luminance32F,         GL3.GL_R32F,               GL.GL_RED,       GL.GL_FLOAT);
-            formatSwiz(formatToGL,     Format.Luminance16FAlpha16F, GL3.GL_RG16F,              GL3.GL_RG,       GLExt.GL_HALF_FLOAT_ARB);
+            formatSwiz(formatToGL,     Format.Luminance16FAlpha16F, GL3.GL_RG16F,              GL3.GL_RG,       halfFloatFormat);
             
             formatSrgbSwiz(formatToGL, Format.Luminance8,           GLExt.GL_SRGB8_EXT,        GL.GL_RED,       GL.GL_UNSIGNED_BYTE);
             formatSrgbSwiz(formatToGL, Format.Luminance8Alpha8,     GLExt.GL_SRGB8_ALPHA8_EXT, GL3.GL_RG,       GL.GL_UNSIGNED_BYTE);
@@ -163,6 +168,11 @@ public final class GLImageFormats {
             }
             format(formatToGL, Format.RGB8,             GLExt.GL_RGBA8, GL.GL_RGB,             GL.GL_UNSIGNED_BYTE);
             format(formatToGL, Format.RGBA8,            GLExt.GL_RGBA8, GL.GL_RGBA,            GL.GL_UNSIGNED_BYTE);
+            
+            formatSwiz(formatToGL, Format.BGR8, GL2.GL_RGB8, GL2.GL_RGB, GL.GL_UNSIGNED_BYTE);
+            formatSwiz(formatToGL, Format.ARGB8, GLExt.GL_RGBA8, GL2.GL_RGBA, GL.GL_UNSIGNED_BYTE);
+            formatSwiz(formatToGL, Format.BGRA8, GLExt.GL_RGBA8, GL2.GL_RGBA, GL.GL_UNSIGNED_BYTE);
+            formatSwiz(formatToGL, Format.ABGR8, GLExt.GL_RGBA8, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
         } else {
             // Actually, the internal format isn't used for OpenGL ES 2! This is the same as the above..
             if (!caps.contains(Caps.CoreProfile)) {
@@ -182,25 +192,25 @@ public final class GLImageFormats {
         
         if (caps.contains(Caps.FloatTexture)) {
             if (!caps.contains(Caps.CoreProfile)) {
-                format(formatToGL, Format.Luminance16F,         GLExt.GL_LUMINANCE16F_ARB,       GL.GL_LUMINANCE,       GLExt.GL_HALF_FLOAT_ARB);
+                format(formatToGL, Format.Luminance16F,         GLExt.GL_LUMINANCE16F_ARB,       GL.GL_LUMINANCE,       halfFloatFormat);
                 format(formatToGL, Format.Luminance32F,         GLExt.GL_LUMINANCE32F_ARB,       GL.GL_LUMINANCE,       GL.GL_FLOAT);
-                format(formatToGL, Format.Luminance16FAlpha16F, GLExt.GL_LUMINANCE_ALPHA16F_ARB, GL.GL_LUMINANCE_ALPHA, GLExt.GL_HALF_FLOAT_ARB);
+                format(formatToGL, Format.Luminance16FAlpha16F, GLExt.GL_LUMINANCE_ALPHA16F_ARB, GL.GL_LUMINANCE_ALPHA, halfFloatFormat);
             }
-            format(formatToGL, Format.RGB16F,               GLExt.GL_RGB16F_ARB,             GL.GL_RGB,             GLExt.GL_HALF_FLOAT_ARB);
+            format(formatToGL, Format.RGB16F,               GLExt.GL_RGB16F_ARB,             GL.GL_RGB,             halfFloatFormat);
             format(formatToGL, Format.RGB32F,               GLExt.GL_RGB32F_ARB,             GL.GL_RGB,             GL.GL_FLOAT);
-            format(formatToGL, Format.RGBA16F,              GLExt.GL_RGBA16F_ARB,            GL.GL_RGBA,            GLExt.GL_HALF_FLOAT_ARB);
+            format(formatToGL, Format.RGBA16F,              GLExt.GL_RGBA16F_ARB,            GL.GL_RGBA,            halfFloatFormat);
             format(formatToGL, Format.RGBA32F,              GLExt.GL_RGBA32F_ARB,            GL.GL_RGBA,            GL.GL_FLOAT);
         }
         if (caps.contains(Caps.PackedFloatTexture)) {
             format(formatToGL, Format.RGB111110F,           GLExt.GL_R11F_G11F_B10F_EXT,     GL.GL_RGB, GLExt.GL_UNSIGNED_INT_10F_11F_11F_REV_EXT);
             if (caps.contains(Caps.FloatTexture)) {
-                format(formatToGL, Format.RGB16F_to_RGB111110F, GLExt.GL_R11F_G11F_B10F_EXT, GL.GL_RGB, GLExt.GL_HALF_FLOAT_ARB);
+                format(formatToGL, Format.RGB16F_to_RGB111110F, GLExt.GL_R11F_G11F_B10F_EXT, GL.GL_RGB, halfFloatFormat);
             }
         }
         if (caps.contains(Caps.SharedExponentTexture)) {
             format(formatToGL, Format.RGB9E5, GLExt.GL_RGB9_E5_EXT, GL.GL_RGB, GLExt.GL_UNSIGNED_INT_5_9_9_9_REV_EXT);
             if (caps.contains(Caps.FloatTexture)) {
-                format(formatToGL, Format.RGB16F_to_RGB9E5,     GLExt.GL_RGB9_E5_EXT,         GL.GL_RGB, GLExt.GL_HALF_FLOAT_ARB);
+                format(formatToGL, Format.RGB16F_to_RGB9E5,     GLExt.GL_RGB9_E5_EXT,         GL.GL_RGB, halfFloatFormat);
             }
         }
         

+ 11 - 9
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -1581,7 +1581,7 @@ public final class GLRenderer implements Renderer {
                     image.getId(),
                     0);
         } else {
-            gl3.glFramebufferTextureLayer(GLFbo.GL_FRAMEBUFFER_EXT, 
+            glfbo.glFramebufferTextureLayerEXT(GLFbo.GL_FRAMEBUFFER_EXT, 
                     convertAttachmentSlot(rb.getSlot()), 
                     image.getId(), 
                     0,
@@ -2203,14 +2203,16 @@ public final class GLRenderer implements Renderer {
                     // For OpenGL3 and up.
                     // We'll generate mipmaps via glGenerateMipmapEXT (see below)
                 }
-            } else if (img.hasMipmaps()) {
-                // Image already has mipmaps, set the max level based on the 
-                // number of mipmaps we have.
-                gl.glTexParameteri(target, GL.GL_TEXTURE_MAX_LEVEL, img.getMipMapSizes().length - 1);
-            } else {
-                // Image does not have mipmaps and they are not required.
-                // Specify that that the texture has no mipmaps.
-                gl.glTexParameteri(target, GL.GL_TEXTURE_MAX_LEVEL, 0);
+            } else if (caps.contains(Caps.OpenGL20)) {
+                if (img.hasMipmaps()) {
+                    // Image already has mipmaps, set the max level based on the 
+                    // number of mipmaps we have.
+                    gl.glTexParameteri(target, GL2.GL_TEXTURE_MAX_LEVEL, img.getMipMapSizes().length - 1);
+                } else {
+                    // Image does not have mipmaps and they are not required.
+                    // Specify that that the texture has no mipmaps.
+                    gl.glTexParameteri(target, GL2.GL_TEXTURE_MAX_LEVEL, 0);
+                }
             }
         } else {
             // Check if graphics card doesn't support multisample textures

+ 14 - 10
jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java

@@ -99,6 +99,7 @@ public final class GLTracer implements InvocationHandler {
         noEnumArgs("glEnableVertexAttribArray", 0);
         noEnumArgs("glDisableVertexAttribArray", 0);
         noEnumArgs("glVertexAttribPointer", 0, 1, 4, 5);
+        noEnumArgs("glVertexAttribDivisorARB", 0, 1);
         noEnumArgs("glDrawRangeElements", 1, 2, 3, 5);
         noEnumArgs("glDrawArrays", 1, 2);
         noEnumArgs("glDeleteBuffers", 0);
@@ -111,6 +112,7 @@ public final class GLTracer implements InvocationHandler {
         noEnumArgs("glRenderbufferStorageMultisampleEXT", 1, 3, 4);
         noEnumArgs("glFramebufferRenderbufferEXT", 3);
         noEnumArgs("glFramebufferTexture2DEXT", 3, 4);
+        noEnumArgs("glFramebufferTextureLayerEXT", 2, 3, 4);
         noEnumArgs("glBlitFramebufferEXT", 0, 1, 2, 3, 4, 5, 6, 7, 8);
         
         noEnumArgs("glCreateProgram", -1);
@@ -165,16 +167,17 @@ public final class GLTracer implements InvocationHandler {
     
     /**
      * Creates a tracer implementation that wraps OpenGL ES 2.
-     * 
+     *
      * @param glInterface OGL object to wrap
-     * @param glInterfaceClass The interface to implement
+     * @param glInterfaceClasses The interface(s) to implement
      * @return A tracer that implements the given interface
      */
-    public static Object createGlesTracer(Object glInterface, Class<?> glInterfaceClass) {
-        IntMap<String> constMap = generateConstantMap(GL.class, GLFbo.class, GLExt.class);
-        return Proxy.newProxyInstance(glInterface.getClass().getClassLoader(),
-                                      new Class<?>[] { glInterfaceClass }, 
-                                      new GLTracer(glInterface, constMap));
+    public static Object createGlesTracer(Object glInterface, Class<?>... glInterfaceClasses) {
+        IntMap<String> constMap = generateConstantMap(GL.class, GL2.class, GL3.class, GLFbo.class, GLExt.class);
+        return Proxy.newProxyInstance(
+                glInterface.getClass().getClassLoader(),
+                glInterfaceClasses,
+                new GLTracer(glInterface, constMap));
     }
 
     /**
@@ -301,7 +304,8 @@ public final class GLTracer implements InvocationHandler {
             // will be printed in darker color
             methodName = methodName.substring(2);
             if (methodName.equals("Clear")
-                    || methodName.equals("DrawRangeElements")) {
+                    || methodName.equals("DrawRangeElements")
+                    || methodName.equals("DrawElementsInstancedARB")) {
                 print(methodName);
             } else {
                 if (methodName.endsWith("EXT")) {
@@ -363,8 +367,8 @@ public final class GLTracer implements InvocationHandler {
         printEnum(param);
         print(", ");
         
-        if (param == GL.GL_TEXTURE_BASE_LEVEL
-                || param == GL.GL_TEXTURE_MAX_LEVEL) {
+        if (param == GL2.GL_TEXTURE_BASE_LEVEL
+                || param == GL2.GL_TEXTURE_MAX_LEVEL) {
             printInt(value);
         } else {
             printEnum(value);

+ 9 - 2
jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java

@@ -32,7 +32,6 @@
 package com.jme3.renderer.opengl;
 
 import com.jme3.renderer.Caps;
-import com.jme3.renderer.RenderContext;
 import com.jme3.renderer.RendererException;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
@@ -91,7 +90,7 @@ final class TextureUtil {
 
     public GLImageFormat getImageFormatWithError(Format fmt, boolean isSrgb) {
         //if the passed format is one kind of depth there isno point in getting the srgb format;
-        isSrgb = isSrgb && fmt != Format.Depth && fmt != Format.Depth16 && fmt != Format.Depth24 && fmt != Format.Depth24Stencil8 && fmt != Format.Depth32 && fmt != Format.Depth32F;
+        isSrgb = isSrgb && !fmt.isDepthFormat();
         GLImageFormat glFmt = getImageFormat(fmt, isSrgb);
         if (glFmt == null && isSrgb) {
             glFmt = getImageFormat(fmt, false);               
@@ -127,6 +126,14 @@ final class TextureUtil {
                 gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_RED);
                 gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_GREEN);
                 break;
+            case ABGR8:
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_ALPHA);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_BLUE);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_GREEN);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_RED);
+                break;
+            default:
+                throw new UnsupportedOperationException();
         }
     }
     

+ 2 - 2
jme3-core/src/main/java/com/jme3/util/NativeObjectManager.java

@@ -133,8 +133,8 @@ public class NativeObjectManager {
                 // Unregister it from cleanup list.
                 NativeObjectRef ref2 = refMap.remove(obj.getUniqueId());
                 if (ref2 == null) {
-                    throw new IllegalArgumentException("This NativeObject is not " + 
-                                                       "registered in this NativeObjectManager");
+                    throw new IllegalArgumentException("The " + obj + " NativeObject is not "
+                            + "registered in this NativeObjectManager");
                 }
 
                 assert ref == null || ref == ref2;

+ 5 - 0
jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java

@@ -611,4 +611,9 @@ public class IosGL implements GL, GLExt, GLFbo {
     public Object glFenceSync(int condition, int flags) {
         throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences");
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int target, int attachment, int texture, int level, int layer) {
+        throw new UnsupportedOperationException("OpenGL ES 2 does not support texture arrays");
+    }
 }

+ 0 - 6
jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java

@@ -634,10 +634,4 @@ public class JoglGL implements GL, GL2, GL3, GL4 {
         checkLimit(arrays);
         GLContext.getCurrentGL().getGL2ES3().glDeleteVertexArrays(arrays.limit(), arrays);
     }
-
-    @Override
-    public void glFramebufferTextureLayer(int param1, int param2, int param3, int param4, int param5) {
-        GLContext.getCurrentGL().getGL3().glFramebufferTextureLayer(param1, param2, param3, param4, param5);
-    }
-
 }

+ 5 - 0
jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLFbo.java

@@ -94,4 +94,9 @@ public class JoglGLFbo implements GLFbo {
     public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
         GLContext.getCurrentGL().glRenderbufferStorage(param1, param2, param3, param4);
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) {
+        GLContext.getCurrentGL().getGL3().glFramebufferTextureLayer(param1, param2, param3, param4, param5);
+    }
 }

+ 0 - 5
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java

@@ -493,9 +493,4 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 {
         checkLimit(arrays);
         ARBVertexArrayObject.glDeleteVertexArrays(arrays);
     }
-
-    @Override
-    public void glFramebufferTextureLayer(int param1, int param2, int param3, int param4, int param5) {
-        GL30.glFramebufferTextureLayer(param1, param2, param3, param4, param5);
-    }
 }

+ 6 - 0
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java

@@ -7,6 +7,7 @@ import java.nio.IntBuffer;
 import org.lwjgl.opengl.EXTFramebufferBlit;
 import org.lwjgl.opengl.EXTFramebufferMultisample;
 import org.lwjgl.opengl.EXTFramebufferObject;
+import org.lwjgl.opengl.EXTTextureArray;
 
 /**
  * Implements GLFbo via GL_EXT_framebuffer_object.
@@ -95,4 +96,9 @@ public final class LwjglGLFboEXT implements GLFbo {
     public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
         EXTFramebufferObject.glRenderbufferStorageEXT(param1, param2, param3, param4);
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int target, int attachment, int texture, int level, int layer) {
+        EXTTextureArray.glFramebufferTextureLayerEXT(target, attachment, texture, level, layer);
+    }
 }

+ 5 - 0
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java

@@ -93,4 +93,9 @@ public final class LwjglGLFboGL3 implements GLFbo {
     public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
         GL30.glRenderbufferStorage(param1, param2, param3, param4);
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) {
+        GL30.glFramebufferTextureLayer(param1, param2, param3, param4, param5);
+    }
 }

+ 0 - 7
jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java

@@ -36,8 +36,6 @@ import com.jme3.renderer.opengl.GL;
 import com.jme3.renderer.opengl.GL2;
 import com.jme3.renderer.opengl.GL3;
 import com.jme3.renderer.opengl.GL4;
-import com.jme3.system.NativeLibraryLoader;
-import com.jme3.system.Platform;
 import org.lwjgl.opengl.*;
 
 import java.nio.*;
@@ -519,9 +517,4 @@ public class LwjglGL implements GL, GL2, GL3, GL4 {
         checkLimit(arrays);
         ARBVertexArrayObject.glDeleteVertexArrays(arrays);
     }
-
-    @Override
-    public void glFramebufferTextureLayer(int param1, int param2, int param3, int param4, int param5) {
-        GL30.glFramebufferTextureLayer(param1, param2, param3, param4, param5);
-    }
 }

+ 6 - 0
jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java

@@ -39,6 +39,7 @@ import org.lwjgl.opengl.EXTFramebufferObject;
 
 import java.nio.Buffer;
 import java.nio.IntBuffer;
+import org.lwjgl.opengl.EXTTextureArray;
 
 /**
  * Implements GLFbo via GL_EXT_framebuffer_object.
@@ -127,4 +128,9 @@ public class LwjglGLFboEXT implements GLFbo {
     public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
         EXTFramebufferObject.glRenderbufferStorageEXT(param1, param2, param3, param4);
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int target, int attachment, int texture, int level, int layer) {
+        EXTTextureArray.glFramebufferTextureLayerEXT(target, attachment, texture, level, layer);
+    }
 }

+ 5 - 0
jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java

@@ -125,4 +125,9 @@ public class LwjglGLFboGL3 implements GLFbo {
     public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
         GL30.glRenderbufferStorage(param1, param2, param3, param4);
     }
+    
+    @Override
+    public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) {
+        GL30.glFramebufferTextureLayer(param1, param2, param3, param4, param5);
+    }
 }

+ 3 - 4
jme3-terrain/src/main/java/com/jme3/terrain/heightmap/MidpointDisplacementHeightMap.java

@@ -35,7 +35,6 @@ import com.jme3.math.FastMath;
 import java.util.Random;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.management.JMException;
 
 /**
  * <code>MidpointDisplacementHeightMap</code> generates an heightmap based on
@@ -72,11 +71,11 @@ public class MidpointDisplacementHeightMap extends AbstractHeightMap {
      *          typically a good choice
      * @param seed
      *          A seed to feed the random number generator.
-     * @throw JMException if size is not a power of two plus one.
+     * @throw IllegalArgumentException if size is not a power of two plus one.
      */
-    public MidpointDisplacementHeightMap(int size, float range, float persistence, long seed) throws Exception {
+    public MidpointDisplacementHeightMap(int size, float range, float persistence, long seed) {
         if (size < 0 || !FastMath.isPowerOfTwo(size - 1)) {
-            throw new JMException("The size is negative or not of the form 2^N +1"
+            throw new IllegalArgumentException("The size is negative or not of the form 2^N +1"
                     + " (a power of two plus one)");
         }
         this.size = size;