瀏覽代碼

Merge pull request #1276 from MeFisto94/fix-gldebug

Fixes #1272 - Improve GLDebugDesktop by reducing manual overrides
MeFisto94 5 年之前
父節點
當前提交
2379cfba77

+ 5 - 11
jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java

@@ -52,13 +52,7 @@ import com.jme3.input.controls.SoftTextDialogInputListener;
 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.GLES_30;
-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.renderer.opengl.*;
 import com.jme3.system.*;
 import com.jme3.util.AndroidBufferAllocator;
 import com.jme3.util.BufferAllocatorFactory;
@@ -209,14 +203,14 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
         });
 
         timer = new NanoTimer();
-        Object gl = new AndroidGL();
+        GL gl = new AndroidGL();
         if (settings.getBoolean("GraphicsDebug")) {
-            gl = new GLDebugES((GL) gl, (GLExt) gl, (GLFbo) gl);
+            gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GLES_30.class, GLFbo.class, GLExt.class);
         }
         if (settings.getBoolean("GraphicsTrace")) {
-            gl = GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class);
+            gl = (GL)GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class);
         }
-        renderer = new GLRenderer((GL)gl, (GLExt)gl, (GLFbo)gl);
+        renderer = new GLRenderer(gl, (GLExt)gl, (GLFbo)gl);
         renderer.initialize();
 
         JmeSystem.setSoftTextDialogInput(this);

+ 91 - 2
jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebug.java

@@ -1,11 +1,66 @@
+/*
+ * Copyright (c) 2009-2020 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.renderer.opengl;
 
 import com.jme3.renderer.RendererException;
 
-public abstract class GLDebug {
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 
+/**
+ * This class uses Reflection to intercept method calls to the Proxy Object ({@link #createProxy(GL, Object, Class[])}
+ * and extends them with the Error Checking in {@link #checkError()}.<br/>
+ * This means we don't have to generate a class with overrides for every possible method just to add a
+ * {@link #checkError()} call.<br/>
+ * Note that we should not call {@link #checkError()} for {@link GL#glGetError()}, it doesn't make sense.<br />
+ * Note that this class is general purpose and as such every class instance (every object) can be guarded as long as
+ * the passed gl instance is valid.<br/>
+ *
+ * @author MeFisto94
+ */
+public class GLDebug implements InvocationHandler {
+    protected Object obj;
     protected GL gl;
-    
+    protected Method methodGlGetError;
+
+    private GLDebug(GL gl, Object obj) throws NoSuchMethodException {
+        this.gl = gl;
+        this.obj = obj;
+        methodGlGetError = GL.class.getMethod("glGetError");
+        /* The NoSuchMethodException shouldn't be thrown, but since we're in a constructor and cannot fail safe
+         * otherwise, we throw it. */
+    }
+
     protected String decodeError(int err) {
         String errMsg;
         switch (err) {
@@ -46,4 +101,38 @@ public abstract class GLDebug {
             throw new RendererException("An OpenGL error occurred - " + decodeError(err));
         }
     }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        Object result = method.invoke(obj, args);
+
+        if (method.equals(methodGlGetError)) {
+            return result;
+        }
+
+        checkError();
+        return result;
+    }
+
+    /**
+     * Creates a debug-proxied object, which will call {@link GL#glGetError()} after every method invocation and throw
+     * a {@link com.jme3.renderer.RendererException} if there was a GL Error.
+     *
+     * @param gl The GL Context, required to call {@link GL#glGetError()}
+     * @param obj The object which methods will be proxied
+     * @param implementedInterfaces The interfaces/class this object implements
+     * @return The Proxy object (or null if an error occured)
+     */
+    public static Object createProxy(GL gl, Object obj, Class<?>... implementedInterfaces) {
+        try {
+            return Proxy.newProxyInstance(
+                    GLDebug.class.getClassLoader(),
+                    implementedInterfaces,
+                    new GLDebug(gl, obj)
+            );
+        } catch (NoSuchMethodException nsme) {
+            throw new IllegalArgumentException ("Could not initialize the proxy because the glGetError method wasn't " +
+                    "found!", nsme);
+        }
+    }
 }

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

@@ -1,147 +0,0 @@
-package com.jme3.renderer.opengl;
-
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 {
-
-    private final GL2 gl2;
-    private final GL3 gl3;
-    private final GL4 gl4;
-    
-    public GLDebugDesktop(GL gl, GLExt glext, GLFbo glfbo) {
-        super(gl, glext, glfbo);
-        this.gl2 = gl instanceof GL2 ? (GL2) gl : null;
-        this.gl3 = gl instanceof GL3 ? (GL3) gl : null;
-        this.gl4 = gl instanceof GL4 ? (GL4) gl : null;
-    }
-    
-    @Override
-    public void glAlphaFunc(int func, float ref) {
-        gl2.glAlphaFunc(func, ref);
-        checkError();
-    }
-
-    @Override
-    public void glPointSize(float size) {
-        gl2.glPointSize(size);
-        checkError();
-    }
-
-    @Override
-    public void glPolygonMode(int face, int mode) {
-        gl2.glPolygonMode(face, mode);
-        checkError();
-    }
-
-    @Override
-    public void glDrawBuffer(int mode) {
-        gl2.glDrawBuffer(mode);
-        checkError();
-    }
-
-    @Override
-    public void glReadBuffer(int mode) {
-        gl2.glReadBuffer(mode);
-        checkError();
-    }
-
-    @Override
-    public void glCompressedTexImage3D(int target, int level, int internalformat, int width, int height, int depth, int border, ByteBuffer data) {
-        gl2.glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, data);
-        checkError();
-    }
-
-    @Override
-    public void glCompressedTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, ByteBuffer data) {
-        gl2.glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, data);
-        checkError();
-    }
-
-    @Override
-    public void glTexImage3D(int target, int level, int internalFormat, int width, int height, int depth, int border, int format, int type, ByteBuffer data) {
-        gl2.glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
-        checkError();
-    }
-
-    @Override
-    public void glTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, ByteBuffer data) {
-        gl2.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
-        checkError();
-    }
-
-    @Override
-    public void glBindFragDataLocation(int param1, int param2, String param3) {
-        gl3.glBindFragDataLocation(param1, param2, param3);
-        checkError();
-    }
-
-    @Override
-    public void glBindVertexArray(int param1) {
-        gl3.glBindVertexArray(param1);
-        checkError();
-    }
-
-    @Override
-    public void glGenVertexArrays(IntBuffer param1) {
-        gl3.glGenVertexArrays(param1);
-        checkError();
-    }
-    
-    @Override
-    public String glGetString(int param1, int param2) {
-        String result = gl3.glGetString(param1, param2);
-        checkError();
-        return result;
-    }
-
-    @Override
-    public int glGetUniformBlockIndex(final int program, final String uniformBlockName) {
-        final int result = gl3.glGetUniformBlockIndex(program, uniformBlockName);
-        checkError();
-        return result;
-    }
-
-    @Override
-    public void glBindBufferBase(final int target, final int index, final int buffer) {
-        gl3.glBindBufferBase(target, index, buffer);
-        checkError();
-    }
-
-    @Override
-    public void glDeleteVertexArrays(IntBuffer arrays) {
-        gl3.glDeleteVertexArrays(arrays);
-        checkError();
-    }
-
-    @Override
-    public void glPatchParameter(int count) {
-        gl4.glPatchParameter(count);
-        checkError();
-    }
-
-    @Override
-    public int glGetProgramResourceIndex(int program, int programInterface, String name) {
-        final int result = gl4.glGetProgramResourceIndex(program, programInterface, name);
-        checkError();
-        return result;
-    }
-
-    @Override
-    public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding) {
-        gl4.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
-        checkError();
-    }
-
-    @Override
-    public void glBlendEquationSeparate(int colorMode, int alphaMode) {
-        gl.glBlendEquationSeparate(colorMode, alphaMode);
-        checkError();
-    }
-
-    @Override
-    public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) {
-        gl3.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
-        checkError();
-    }
-}

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

@@ -1,773 +0,0 @@
-package com.jme3.renderer.opengl;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-
-public class GLDebugES extends GLDebug implements GL, GL2, GLES_30, GLFbo, GLExt {
-
-    private final GLFbo glfbo;
-    private final GLExt glext;
-
-    public GLDebugES(GL gl, GLExt glext, GLFbo glfbo) {
-        this.gl = gl;
-        this.glext = glext;
-        this.glfbo = glfbo;
-    }
-
-    @Override
-    public void resetStats() {
-        gl.resetStats();
-    }
-    
-    @Override
-    public void glActiveTexture(int texture) {
-        gl.glActiveTexture(texture);
-        checkError();
-    }
-
-    @Override
-    public void glAttachShader(int program, int shader) {
-        gl.glAttachShader(program, shader);
-        checkError();
-    }
-
-    @Override
-    public void glBeginQuery(int target, int query) {
-        gl.glBeginQuery(target, query);
-        checkError();
-    }
-
-    @Override
-    public void glBindBuffer(int target, int buffer) {
-        gl.glBindBuffer(target, buffer);
-        checkError();
-    }
-
-    @Override
-    public void glBindTexture(int target, int texture) {
-        gl.glBindTexture(target, texture);
-        checkError();
-    }
-
-    @Override
-    public void glBlendFunc(int sfactor, int dfactor) {
-        gl.glBlendFunc(sfactor, dfactor);
-        checkError();
-    }
-    
-    @Override
-    public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dFactorAlpha)
-    {
-       gl.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dFactorAlpha);
-       checkError();
-    }
-
-    @Override
-    public void glBufferData(int target, FloatBuffer data, int usage) {
-        gl.glBufferData(target, data, usage);
-        checkError();
-    }
-
-    @Override
-    public void glBufferData(int target, ShortBuffer data, int usage) {
-        gl.glBufferData(target, data, usage);
-        checkError();
-    }
-
-    @Override
-    public void glBufferData(int target, ByteBuffer data, int usage) {
-        gl.glBufferData(target, data, usage);
-        checkError();
-    }
-
-    @Override
-    public void glBufferSubData(int target, long offset, FloatBuffer data) {
-        gl.glBufferSubData(target, offset, data);
-        checkError();
-    }
-
-    @Override
-    public void glBufferSubData(int target, long offset, ShortBuffer data) {
-        gl.glBufferSubData(target, offset, data);
-        checkError();
-    }
-
-    @Override
-    public void glBufferSubData(int target, long offset, ByteBuffer data) {
-        gl.glBufferSubData(target, offset, data);
-        checkError();
-    }
-
-    @Override
-    public void glClear(int mask) {
-        gl.glClear(mask);
-        checkError();
-    }
-
-    @Override
-    public void glClearColor(float red, float green, float blue, float alpha) {
-        gl.glClearColor(red, green, blue, alpha);
-        checkError();
-    }
-
-    @Override
-    public void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
-        gl.glColorMask(red, green, blue, alpha);
-        checkError();
-    }
-
-    @Override
-    public void glCompileShader(int shader) {
-        gl.glCompileShader(shader);
-        checkError();
-    }
-
-    @Override
-    public void glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, ByteBuffer data) {
-        gl.glCompressedTexImage2D(target, level, internalformat, width, height, border, data);
-        checkError();
-    }
-
-    @Override
-    public void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, ByteBuffer data) {
-        gl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data);
-        checkError();
-    }
-
-    @Override
-    public int glCreateProgram() {
-        int program = gl.glCreateProgram();
-        checkError();
-        return program;
-    }
-
-    @Override
-    public int glCreateShader(int shaderType) {
-        int shader = gl.glCreateShader(shaderType);
-        checkError();
-        return shader;
-    }
-
-    @Override
-    public void glCullFace(int mode) {
-        gl.glCullFace(mode);
-        checkError();
-    }
-
-    @Override
-    public void glDeleteBuffers(IntBuffer buffers) {
-        gl.glDeleteBuffers(buffers);
-        checkError();
-    }
-
-    @Override
-    public void glDeleteProgram(int program) {
-        gl.glDeleteProgram(program);
-        checkError();
-    }
-
-    @Override
-    public void glDeleteShader(int shader) {
-        gl.glDeleteShader(shader);
-        checkError();
-    }
-
-    @Override
-    public void glDeleteTextures(IntBuffer textures) {
-        gl.glDeleteTextures(textures);
-        checkError();
-    }
-
-    @Override
-    public void glDepthFunc(int func) {
-        gl.glDepthFunc(func);
-        checkError();
-    }
-
-    @Override
-    public void glDepthMask(boolean flag) {
-        gl.glDepthMask(flag);
-        checkError();
-    }
-
-    @Override
-    public void glDepthRange(double nearVal, double farVal) {
-        gl.glDepthRange(nearVal, farVal);
-        checkError();
-    }
-
-    @Override
-    public void glDetachShader(int program, int shader) {
-        gl.glDetachShader(program, shader);
-        checkError();
-    }
-
-    @Override
-    public void glDisable(int cap) {
-        gl.glDisable(cap);
-        checkError();
-    }
-
-    @Override
-    public void glDisableVertexAttribArray(int index) {
-        gl.glDisableVertexAttribArray(index);
-        checkError();
-    }
-
-    @Override
-    public void glDrawArrays(int mode, int first, int count) {
-        gl.glDrawArrays(mode, first, count);
-        checkError();
-    }
-
-    @Override
-    public void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices) {
-        gl.glDrawRangeElements(mode, start, end, count, type, indices);
-        checkError();
-    }
-
-    @Override
-    public void glEnable(int cap) {
-        gl.glEnable(cap);
-        checkError();
-    }
-
-    @Override
-    public void glEnableVertexAttribArray(int index) {
-        gl.glEnableVertexAttribArray(index);
-        checkError();
-    }
-
-    @Override
-    public void glEndQuery(int target) {
-        checkError();
-    }
-
-    @Override
-    public void glGenBuffers(IntBuffer buffers) {
-        gl.glGenBuffers(buffers);
-        checkError();
-    }
-
-    @Override
-    public void glGenTextures(IntBuffer textures) {
-        gl.glGenTextures(textures);
-        checkError();
-    }
-
-    @Override
-    public void glGenQueries(int num, IntBuffer ids) {
-        glGenQueries(num, ids);
-        checkError();
-    }
-
-    @Override
-    public int glGetAttribLocation(int program, String name) {
-        int location = gl.glGetAttribLocation(program, name);
-        checkError();
-        return location;
-    }
-
-    @Override
-    public void glGetBoolean(int pname, ByteBuffer params) {
-        gl.glGetBoolean(pname, params);
-        checkError();
-    }
-
-    @Override
-    public int glGetError() {
-        // No need to check for error here? Haha
-        return gl.glGetError();
-    }
-
-    @Override
-    public void glGetInteger(int pname, IntBuffer params) {
-        gl.glGetInteger(pname, params);
-        checkError();
-    }
-
-    @Override
-    public void glGetProgram(int program, int pname, IntBuffer params) {
-        gl.glGetProgram(program, pname, params);
-        checkError();
-    }
-
-    @Override
-    public String glGetProgramInfoLog(int program, int maxSize) {
-        String infoLog =  gl.glGetProgramInfoLog(program, maxSize);
-        checkError();
-        return infoLog;
-    }
-
-    @Override
-    public long glGetQueryObjectui64(int query, int pname) {
-        long res = gl.glGetQueryObjectui64(query, pname);
-        checkError();
-        return res;
-    }
-
-    @Override
-    public int glGetQueryObjectiv(int query, int pname) {
-        int res = gl.glGetQueryObjectiv(query, pname);
-        checkError();
-        return res;
-    }
-
-    @Override
-    public void glGetShader(int shader, int pname, IntBuffer params) {
-        gl.glGetShader(shader, pname, params);
-        checkError();
-    }
-
-    @Override
-    public String glGetShaderInfoLog(int shader, int maxSize) {
-        String infoLog = gl.glGetShaderInfoLog(shader, maxSize);
-        checkError();
-        return infoLog;
-    }
-
-    @Override
-    public String glGetString(int name) {
-        String string = gl.glGetString(name);
-        checkError();
-        return string;
-    }
-
-    @Override
-    public int glGetUniformLocation(int program, String name) {
-        int location = gl.glGetUniformLocation(program, name);
-        checkError();
-        return location;
-    }
-
-    @Override
-    public boolean glIsEnabled(int cap) {
-        boolean enabled = gl.glIsEnabled(cap);
-        checkError();
-        return enabled;
-    }
-
-    @Override
-    public void glLineWidth(float width) {
-        gl.glLineWidth(width);
-        checkError();
-    }
-
-    @Override
-    public void glLinkProgram(int program) {
-        gl.glLinkProgram(program);
-        checkError();
-    }
-
-    @Override
-    public void glPixelStorei(int pname, int param) {
-        gl.glPixelStorei(pname, param);
-        checkError();
-    }
-
-    @Override
-    public void glPolygonOffset(float factor, float units) {
-        gl.glPolygonOffset(factor, units);
-        checkError();
-    }
-
-    @Override
-    public void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer data) {
-        gl.glReadPixels(x, y, width, height, format, type, data);
-        checkError();
-    }
-    
-    @Override
-    public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset) {
-        gl.glReadPixels(x, y, width, height, format, type, offset);
-        checkError();
-    }
-
-    @Override
-    public void glScissor(int x, int y, int width, int height) {
-        gl.glScissor(x, y, width, height);
-        checkError();
-    }
-
-    @Override
-    public void glShaderSource(int shader, String[] string, IntBuffer length) {
-        gl.glShaderSource(shader, string, length);
-        checkError();
-    }
-
-    @Override
-    public void glStencilFuncSeparate(int face, int func, int ref, int mask) {
-        gl.glStencilFuncSeparate(face, func, ref, mask);
-        checkError();
-    }
-
-    @Override
-    public void glStencilOpSeparate(int face, int sfail, int dpfail, int dppass) {
-        gl.glStencilOpSeparate(face, sfail, dpfail, dppass);
-        checkError();
-    }
-
-    @Override
-    public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, ByteBuffer data) {
-        gl.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
-        checkError();
-    }
-
-    @Override
-    public void glTexParameterf(int target, int pname, float param) {
-        gl.glTexParameterf(target, pname, param);
-        checkError();
-    }
-
-    @Override
-    public void glTexParameteri(int target, int pname, int param) {
-        gl.glTexParameteri(target, pname, param);
-        checkError();
-    }
-
-    @Override
-    public void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, ByteBuffer data) {
-        gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
-        checkError();
-    }
-
-    @Override
-    public void glUniform1(int location, FloatBuffer value) {
-        gl.glUniform1(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform1(int location, IntBuffer value) {
-        gl.glUniform1(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform1f(int location, float v0) {
-        gl.glUniform1f(location, v0);
-        checkError();
-    }
-
-    @Override
-    public void glUniform1i(int location, int v0) {
-        gl.glUniform1i(location, v0);
-        checkError();
-    }
-
-    @Override
-    public void glUniform2(int location, IntBuffer value) {
-        gl.glUniform2(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform2(int location, FloatBuffer value) {
-        gl.glUniform2(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform2f(int location, float v0, float v1) {
-        gl.glUniform2f(location, v0, v1);
-        checkError();
-    }
-
-    @Override
-    public void glUniform3(int location, IntBuffer value) {
-        gl.glUniform3(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform3(int location, FloatBuffer value) {
-        gl.glUniform3(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform3f(int location, float v0, float v1, float v2) {
-        gl.glUniform3f(location, v0, v1, v2);
-        checkError();
-    }
-
-    @Override
-    public void glUniform4(int location, FloatBuffer value) {
-        gl.glUniform4(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform4(int location, IntBuffer value) {
-        gl.glUniform4(location, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniform4f(int location, float v0, float v1, float v2, float v3) {
-        gl.glUniform4f(location, v0, v1, v2, v3);
-        checkError();
-    }
-
-    @Override
-    public void glUniformMatrix3(int location, boolean transpose, FloatBuffer value) {
-        gl.glUniformMatrix3(location, transpose, value);
-        checkError();
-    }
-
-    @Override
-    public void glUniformMatrix4(int location, boolean transpose, FloatBuffer value) {
-        gl.glUniformMatrix4(location, transpose, value);
-        checkError();
-    }
-
-    @Override
-    public void glUseProgram(int program) {
-        gl.glUseProgram(program);
-        checkError();
-    }
-
-    @Override
-    public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer) {
-        gl.glVertexAttribPointer(index, size, type, normalized, stride, pointer);
-        checkError();
-    }
-
-    @Override
-    public void glViewport(int x, int y, int width, int height) {
-        gl.glViewport(x, y, width, height);
-        checkError();
-    }
-
-    @Override
-    public void glBindFramebufferEXT(int param1, int param2) {
-        glfbo.glBindFramebufferEXT(param1, param2);
-        checkError();
-    }
-
-    @Override
-    public void glBindRenderbufferEXT(int param1, int param2) {
-        glfbo.glBindRenderbufferEXT(param1, param2);
-        checkError();
-    }
-
-    @Override
-    public int glCheckFramebufferStatusEXT(int param1) {
-        int result = glfbo.glCheckFramebufferStatusEXT(param1);
-        checkError();
-        return result;
-    }
-
-    @Override
-    public void glDeleteFramebuffersEXT(IntBuffer param1) {
-        glfbo.glDeleteFramebuffersEXT(param1);
-        checkError();
-    }
-
-    @Override
-    public void glDeleteRenderbuffersEXT(IntBuffer param1) {
-        glfbo.glDeleteRenderbuffersEXT(param1);
-        checkError();
-    }
-
-    @Override
-    public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
-        glfbo.glFramebufferRenderbufferEXT(param1, param2, param3, param4);
-        checkError();
-    }
-
-    @Override
-    public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
-        glfbo.glFramebufferTexture2DEXT(param1, param2, param3, param4, param5);
-        checkError();
-    }
-
-    @Override
-    public void glGenFramebuffersEXT(IntBuffer param1) {
-        glfbo.glGenFramebuffersEXT(param1);
-        checkError();
-    }
-
-    @Override
-    public void glGenRenderbuffersEXT(IntBuffer param1) {
-        glfbo.glGenRenderbuffersEXT(param1);
-        checkError();
-    }
-
-    @Override
-    public void glGenerateMipmapEXT(int param1) {
-        glfbo.glGenerateMipmapEXT(param1);
-        checkError();
-    }
-
-    @Override
-    public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
-        glfbo.glRenderbufferStorageEXT(param1, param2, param3, param4);
-        checkError();
-    }
-
-    @Override
-    public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
-        glfbo.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-        checkError();
-    }
-
-    @Override
-    public void glBufferData(int target, long data_size, int usage) {
-        gl.glBufferData(target, data_size, usage);
-        checkError();
-    }
-
-    @Override
-    public void glGetBufferSubData(int target, long offset, ByteBuffer data) {
-        gl.glGetBufferSubData(target, offset, data);
-        checkError();
-    }
-    
-    @Override
-    public void glBufferData(int target, IntBuffer data, int usage) {
-        glext.glBufferData(target, data, usage);
-        checkError();
-    }
-
-    @Override
-    public void glBufferSubData(int target, long offset, IntBuffer data) {
-        glext.glBufferSubData(target, offset, data);
-        checkError();
-    }
-
-    @Override
-    public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount) {
-        glext.glDrawArraysInstancedARB(mode, first, count, primcount);
-        checkError();
-    }
-
-    @Override
-    public void glDrawBuffers(IntBuffer bufs) {
-        glext.glDrawBuffers(bufs);
-        checkError();
-    }
-
-    @Override
-    public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount) {
-        glext.glDrawElementsInstancedARB(mode, indices_count, type, indices_buffer_offset, primcount);
-        checkError();
-    }
-
-    @Override
-    public void glGetMultisample(int pname, int index, FloatBuffer val) {
-        glext.glGetMultisample(pname, index, val);
-        checkError();
-    }
-
-    @Override
-    public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
-        glfbo.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
-        checkError();
-    }
-
-    @Override
-    public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations) {
-        glext.glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
-        checkError();
-    }
-
-    @Override
-    public void glVertexAttribDivisorARB(int index, int divisor) {
-        glext.glVertexAttribDivisorARB(index, divisor);
-        checkError();
-    }
-
-    @Override
-    public int glClientWaitSync(Object sync, int flags, long timeout) {
-        int result = glext.glClientWaitSync(sync, flags, timeout);
-        checkError();
-        return result;
-    }
-
-    @Override
-    public void glDeleteSync(Object sync) {
-        glext.glDeleteSync(sync);
-        checkError();
-    }
-
-    @Override
-    public Object glFenceSync(int condition, int flags) {
-        Object sync = glext.glFenceSync(condition, flags);
-        checkError();
-        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();
-    }
-
-    @Override
-    public void glAlphaFunc(int func, float ref) {
-        ((GL2)gl).glAlphaFunc(func, ref);
-        checkError();
-    }
-
-    @Override
-    public void glPointSize(float size) {
-        ((GL2)gl).glPointSize(size);
-        checkError();
-    }
-
-    @Override
-    public void glPolygonMode(int face, int mode) {
-        ((GL2)gl).glPolygonMode(face, mode);
-        checkError();
-    }
-
-    @Override
-    public void glDrawBuffer(int mode) {
-        ((GL2)gl).glDrawBuffer(mode);
-        checkError();
-    }
-
-    @Override
-    public void glReadBuffer(int mode) {
-        ((GL2)gl).glReadBuffer(mode);
-        checkError();
-    }
-
-    @Override
-    public void glCompressedTexImage3D(int target, int level, int internalFormat, int width, int height, int depth,
-                                           int border, ByteBuffer data) {
-        ((GL2)gl).glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, data);
-        checkError();
-    }
-
-    @Override
-    public void glCompressedTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width,
-                                              int height, int depth, int format, ByteBuffer data) {
-        ((GL2)gl).glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, data);
-        checkError();
-    }
-
-    @Override
-    public void glTexImage3D(int target, int level, int internalFormat, int width, int height, int depth, int border,
-                                 int format, int type, ByteBuffer data) {
-        ((GL2)gl).glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
-        checkError();
-    }
-
-    @Override
-    public void glTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height,
-                                    int depth, int format, int type, ByteBuffer data) {
-        ((GL2)gl).glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
-        checkError();
-    }
-
-}

+ 12 - 15
jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java

@@ -31,18 +31,18 @@
  */
 package com.jme3.system.ios;
 
-import com.jme3.input.*;
+import com.jme3.input.JoyInput;
+import com.jme3.input.KeyInput;
+import com.jme3.input.MouseInput;
+import com.jme3.input.TouchInput;
 import com.jme3.input.dummy.DummyKeyInput;
 import com.jme3.input.dummy.DummyMouseInput;
-import com.jme3.system.*;
 import com.jme3.input.ios.IosInputHandler;
 import com.jme3.opencl.Context;
 import com.jme3.renderer.ios.IosGL;
-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.*;
+import com.jme3.system.*;
+
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -155,16 +155,13 @@ public class IGLESContext implements JmeContext {
     @Override
     public void create(boolean waitFor) {
         logger.log(Level.FINE, "IGLESContext create");
-        
-        GL gl = new IosGL();
-        GLExt glext = (GLExt) gl;
+        IosGL gl = new IosGL();
 
-//        if (settings.getBoolean("GraphicsDebug")) {
-            gl = new GLDebugES(gl, glext, (GLFbo) glext);
-            glext = (GLExt) gl;
-//        }
+        if (settings.getBoolean("GraphicsDebug")) {
+            gl = (IosGL)GLDebug.createProxy(gl, gl, GL.class, GLExt.class, GLFbo.class);
+        }
 
-        renderer = new GLRenderer(gl, glext, (GLFbo) glext);
+        renderer = new GLRenderer(gl, gl, gl);
         renderer.initialize();
         
         input = new IosInputHandler();

+ 4 - 4
jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java

@@ -49,7 +49,7 @@ import com.jme3.renderer.jogl.JoglGLFbo;
 import com.jme3.renderer.opengl.GL2;
 import com.jme3.renderer.opengl.GL3;
 import com.jme3.renderer.opengl.GL4;
-import com.jme3.renderer.opengl.GLDebugDesktop;
+import com.jme3.renderer.opengl.GLDebug;
 import com.jme3.renderer.opengl.GLExt;
 import com.jme3.renderer.opengl.GLFbo;
 import com.jme3.renderer.opengl.GLRenderer;
@@ -178,9 +178,9 @@ public abstract class JoglContext implements JmeContext {
         	GLFbo glfbo = new JoglGLFbo();
 
             if (settings.getBoolean("GraphicsDebug")) {
-                gl    = new GLDebugDesktop(gl, glext, glfbo);
-                glext = (GLExt) gl;
-                glfbo = (GLFbo) gl;
+                gl = (com.jme3.renderer.opengl.GL) GLDebug.createProxy(gl, gl, com.jme3.renderer.opengl.GL.class, GL2.class, GL3.class, GL4.class);
+                glext = (GLExt) GLDebug.createProxy(gl, glext, GLExt.class);
+                glfbo = (GLFbo) GLDebug.createProxy(gl, glfbo, GLFbo.class);
             }
 
             if (settings.getBoolean("GraphicsTiming")) {

+ 4 - 4
jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java

@@ -50,7 +50,7 @@ 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.renderer.opengl.GLDebugDesktop;
+import com.jme3.renderer.opengl.GLDebug;
 import com.jme3.renderer.opengl.GLExt;
 import com.jme3.renderer.opengl.GLFbo;
 import com.jme3.renderer.opengl.GLRenderer;
@@ -270,9 +270,9 @@ public abstract class LwjglContext implements JmeContext {
             }
             
             if (settings.getBoolean("GraphicsDebug")) {
-                gl = new GLDebugDesktop(gl, glext, glfbo);
-                glext = (GLExt) gl;
-                glfbo = (GLFbo) gl;
+                gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GL3.class, GL4.class);
+                glext = (GLExt) GLDebug.createProxy(gl, glext, GLExt.class);
+                glfbo = (GLFbo) GLDebug.createProxy(gl, glfbo, GLFbo.class);
             }
             if (settings.getBoolean("GraphicsTiming")) {
                 GLTimingState timingState = new GLTimingState();

+ 3 - 3
jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java

@@ -196,9 +196,9 @@ public abstract class LwjglContext implements JmeContext {
         }
 
         if (settings.getBoolean("GraphicsDebug")) {
-            gl = new GLDebugDesktop(gl, glext, glfbo);
-            glext = (GLExt) gl;
-            glfbo = (GLFbo) gl;
+            gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GL3.class, GL4.class);
+            glext = (GLExt) GLDebug.createProxy(gl, glext, GLExt.class);
+            glfbo = (GLFbo) GLDebug.createProxy(gl, glfbo, GLFbo.class);
         }
 
         if (settings.getBoolean("GraphicsTiming")) {

+ 3 - 3
jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglContextVR.java

@@ -167,9 +167,9 @@ public abstract class LwjglContextVR implements JmeContext {
             }
 
             if (settings.getBoolean("GraphicsDebug")) {
-                gl = new GLDebugDesktop(gl, glext, glfbo);
-                glext = (GLExt) gl;
-                glfbo = (GLFbo) gl;
+                gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GL3.class, GL4.class);
+                glext = (GLExt) GLDebug.createProxy(gl, glext, GLExt.class);
+                glfbo = (GLFbo) GLDebug.createProxy(gl, glfbo, GLFbo.class);
             }
 
             if (settings.getBoolean("GraphicsTiming")) {