Procházet zdrojové kódy

Merge pull request #549 from shamanDevel/LWJGL3-update

Lwjgl3 update from 3.0.0b to 3.0.0
Kirill Vainer před 9 roky
rodič
revize
903522de91
26 změnil soubory, kde provedl 2692 přidání a 111 odebrání
  1. 3 0
      .travis.yml
  2. 2 0
      jme3-core/src/main/java/com/jme3/audio/openal/ALC.java
  3. 3 1
      jme3-lwjgl3/build.gradle
  4. 24 27
      jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java
  5. 1 1
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java
  6. 22 2
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java
  7. 31 3
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java
  8. 730 0
      jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIBuffer.java
  9. 218 0
      jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIUtil.java
  10. 1 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java
  11. 1 1
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java
  12. 37 41
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglDevice.java
  13. 1 1
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java
  14. 5 1
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java
  15. 1 2
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java
  16. 54 12
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglPlatform.java
  17. 4 3
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java
  18. 1 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/Utils.java
  19. 114 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/CLUtil.java
  20. 687 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/Info.java
  21. 215 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQuery.java
  22. 224 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryInt.java
  23. 224 0
      jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryObject.java
  24. 42 8
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
  25. 10 0
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java
  26. 37 8
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java

+ 3 - 0
.travis.yml

@@ -1,6 +1,9 @@
 language: java
 sudo: false
 
+jdk:
+  - oraclejdk8
+
 addons:
   ssh_known_hosts: updates.jmonkeyengine.org
 

+ 2 - 0
jme3-core/src/main/java/com/jme3/audio/openal/ALC.java

@@ -59,6 +59,8 @@ public interface ALC {
      */
     static final int ALC_DEFAULT_ALL_DEVICES_SPECIFIER = 0x1012;
     static final int ALC_ALL_DEVICES_SPECIFIER = 0x1013;
+
+    //public static ALCCapabilities createCapabilities(long device);
     
     public void createALC();
     public void destroyALC();

+ 3 - 1
jme3-lwjgl3/build.gradle

@@ -2,7 +2,9 @@ if (!hasProperty('mainClass')) {
     ext.mainClass = ''
 }
 
-def lwjglVersion = '3.0.0b'
+def lwjglVersion = '3.0.0'
+
+sourceCompatibility = '1.8'
 
 dependencies {
     compile project(':jme3-core')

+ 24 - 27
jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java

@@ -31,52 +31,49 @@
  */
 package com.jme3.audio.lwjgl;
 
-import com.jme3.audio.openal.ALC;
+import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
+import org.lwjgl.openal.AL;
+import org.lwjgl.openal.ALC;
 import org.lwjgl.openal.ALC10;
-import org.lwjgl.openal.ALContext;
-import org.lwjgl.openal.ALDevice;
+import org.lwjgl.openal.ALCCapabilities;
 import org.lwjgl.openal.SOFTPauseDevice;
 
-public class LwjglALC implements ALC {
+public class LwjglALC implements com.jme3.audio.openal.ALC {
 
-    private ALDevice device;
-    private ALContext context;
-
-    private long contextId;
-    private long deviceId;
+    private long device;
+    private long context;
 
     public void createALC() {
-        device = ALDevice.create();
-        context = ALContext.create(device);
-        context.makeCurrent();
-
-        contextId = ALC10.alcGetCurrentContext();
-        deviceId = ALC10.alcGetContextsDevice(contextId);
+        device = ALC10.alcOpenDevice((ByteBuffer) null);
+        ALCCapabilities deviceCaps = ALC.createCapabilities(device);
+        context = ALC10.alcCreateContext(device, (IntBuffer) null);
+        ALC10.alcMakeContextCurrent(context);
+        AL.createCapabilities(deviceCaps);
     }
 
     public void destroyALC() {
-        if (context != null) {
-            context.destroy();
-            context = null;
+        if (context != 0) {
+            ALC10.alcDestroyContext(context);
+            context = 0;
         }
 
-        if (device != null) {
-            device.destroy();
-            device = null;
+        if (device != 0) {
+            ALC10.alcCloseDevice(device);
+            device = 0;
         }
     }
 
     public boolean isCreated() {
-        return context != null;
+        return context != 0;
     }
 
     public String alcGetString(final int parameter) {
-        return ALC10.alcGetString(deviceId, parameter);
+        return ALC10.alcGetString(device, parameter);
     }
 
     public boolean alcIsExtensionPresent(final String extension) {
-        return ALC10.alcIsExtensionPresent(deviceId, extension);
+        return ALC10.alcIsExtensionPresent(device, extension);
     }
 
     public void alcGetInteger(final int param, final IntBuffer buffer, final int size) {
@@ -86,15 +83,15 @@ public class LwjglALC implements ALC {
         if (buffer.limit() != size) {
             throw new AssertionError();
         }
-        ALC10.alcGetIntegerv(deviceId, param, buffer);
+        ALC10.alcGetIntegerv(device, param, buffer);
     }
 
     public void alcDevicePauseSOFT() {
-        SOFTPauseDevice.alcDevicePauseSOFT(deviceId);
+        SOFTPauseDevice.alcDevicePauseSOFT(device);
     }
 
     public void alcDeviceResumeSOFT() {
-        SOFTPauseDevice.alcDeviceResumeSOFT(deviceId);
+        SOFTPauseDevice.alcDeviceResumeSOFT(device);
     }
 
 }

+ 1 - 1
jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java

@@ -65,7 +65,7 @@ public class GlfwJoystickInput implements JoyInput {
     @Override
     public Joystick[] loadJoysticks(final InputManager inputManager) {
         for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) {
-            if (glfwJoystickPresent(i) == GL11.GL_TRUE) {
+            if (glfwJoystickPresent(i)) {
                 final String name = glfwGetJoystickName(i);
                 final GlfwJoystick joystick = new GlfwJoystick(inputManager, this, i, name);
                 joysticks.put(i, joystick);

+ 22 - 2
jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java

@@ -87,6 +87,16 @@ public class GlfwKeyInput implements KeyInput {
 
                 keyInputEvents.add(event);
             }
+
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         glfwSetCharCallback(context.getWindowHandle(), charCallback = new GLFWCharCallback() {
@@ -106,6 +116,16 @@ public class GlfwKeyInput implements KeyInput {
 
                 keyInputEvents.add(released);
             }
+
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         initialized = true;
@@ -132,8 +152,8 @@ public class GlfwKeyInput implements KeyInput {
             return;
         }
 
-        keyCallback.release();
-        charCallback.release();
+        keyCallback.close();
+        charCallback.close();
         logger.fine("Keyboard destroyed.");
     }
 

+ 31 - 3
jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java

@@ -133,6 +133,16 @@ public class GlfwMouseInput implements MouseInput {
             public void invoke(long window, double xpos, double ypos) {
                 onCursorPos(window, xpos, ypos);
             }
+
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() {
@@ -140,6 +150,15 @@ public class GlfwMouseInput implements MouseInput {
             public void invoke(final long window, final double xOffset, final double yOffset) {
                 onWheelScroll(window, xOffset, yOffset * WHEEL_SCALE);
             }
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() {
@@ -147,6 +166,15 @@ public class GlfwMouseInput implements MouseInput {
             public void invoke(final long window, final int button, final int action, final int mods) {
                 onMouseButton(window, button, action, mods);
             }
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         setCursorVisible(cursorVisible);
@@ -177,9 +205,9 @@ public class GlfwMouseInput implements MouseInput {
             return;
         }
 
-        cursorPosCallback.release();
-        scrollCallback.release();
-        mouseButtonCallback.release();
+        cursorPosCallback.close();
+        scrollCallback.close();
+        mouseButtonCallback.close();
 
         for (long glfwCursor : jmeToGlfwCursorMap.values()) {
             glfwDestroyCursor(glfwCursor);

+ 730 - 0
jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIBuffer.java

@@ -0,0 +1,730 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ */
+package com.jme3.lwjgl3.utils;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.PointerBuffer;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import static org.lwjgl.system.Pointer.*;
+import static org.lwjgl.system.MathUtil.*;
+import org.lwjgl.system.MemoryUtil;
+import static org.lwjgl.system.MemoryUtil.*;
+
+/**
+ * Helper class for alternative API functions. Instead of the user passing their
+ * own buffer, thread-local instances of this class are used internally instead.
+ */
+public class APIBuffer {
+
+    private static final int DEFAULT_CAPACITY = 128;
+
+    private ByteBuffer buffer;
+    private long address;
+
+    private int offset;
+
+    private int stackDepth;
+    private int[] stack = new int[4];
+
+    public APIBuffer() {
+        buffer = BufferUtils.createByteBuffer(DEFAULT_CAPACITY);
+        address = memAddress(buffer);
+    }
+
+    /**
+     * Resets the parameter offset to 0.
+     */
+    public APIBuffer reset() {
+        offset = 0;
+        return this;
+    }
+
+    /**
+     * Pushes the current parameter offset to a stack.
+     */
+    public APIBuffer push() {
+        if (stackDepth == stack.length) {
+            stack = Arrays.copyOf(stack, stack.length << 1);
+        }
+
+        stack[stackDepth++] = offset;
+
+        // Upward align the current offset to the pointer size.
+        offset = (offset + (POINTER_SIZE - 1)) & -POINTER_SIZE;
+
+        return this;
+    }
+
+    /**
+     * Restores the last pushed parameter offset.
+     */
+    public APIBuffer pop() {
+        offset = stack[--stackDepth];
+        return this;
+    }
+
+    /**
+     * Returns the current parameter offset.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Sets the current parameter offset.
+     */
+    public void setOffset(int offset) {
+        this.offset = offset;
+    }
+
+    /**
+     * Returns the memory address of the internal {@link ByteBuffer}. This
+     * address may change after a call to one of the {@code <type>Param()}
+     * methods.
+     */
+    public long address() {
+        return address;
+    }
+
+    /**
+     * Returns the memory address of the specified {@code offset}. This address
+     * may change after a call to one of the {@code <type>Param()} methods.
+     */
+    public long address(int offset) {
+        return address + offset;
+    }
+
+    /**
+     * Returns the memory address of the specified {@code offset} or
+     * {@link MemoryUtil#NULL NULL} if the specified {@code value} is null. This
+     * address may change after a call to one of the {@code <type>Param()}
+     * methods.
+     */
+    public long addressSafe(Object value, int offset) {
+        return value == null ? NULL : address(offset);
+    }
+
+    /**
+     * Returns the {@link ByteBuffer} that backs this {@link APIBuffer}.
+     */
+    public ByteBuffer buffer() {
+        return buffer;
+    }
+
+    private void ensureCapacity(int capacity) {
+        if (capacity <= buffer.capacity()) {
+            return;
+        }
+
+        ByteBuffer resized = BufferUtils.createByteBuffer(mathRoundPoT(capacity));
+
+        resized.put(buffer);
+        resized.clear();
+
+        buffer = resized;
+        address = memAddress(resized);
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    private int param(int bytes) {
+        return param(bytes, bytes);
+    }
+
+    private int param(int bytes, int alignment) {
+        // Upward align the current offset to the specified alignment
+        int param = (offset + (alignment - 1)) & -alignment;
+        ensureCapacity(offset = param + bytes);
+        return param;
+    }
+
+    /**
+     * Ensures space for an additional boolean value and returns the address
+     * offset.
+     */
+    public int booleanParam() {
+        return param(1);
+    }
+
+    /**
+     * Ensures space for an additional byte value and returns the address
+     * offset.
+     */
+    public int byteParam() {
+        return param(1);
+    }
+
+    /**
+     * Ensures space for an additional short value and returns the address
+     * offset.
+     */
+    public int shortParam() {
+        return param(2);
+    }
+
+    /**
+     * Ensures space for an additional int value and returns the address offset.
+     */
+    public int intParam() {
+        return param(4);
+    }
+
+    /**
+     * Ensures space for an additional long value and returns the address
+     * offset.
+     */
+    public int longParam() {
+        return param(8);
+    }
+
+    /**
+     * Ensures space for an additional float value and returns the address
+     * offset.
+     */
+    public int floatParam() {
+        return param(4);
+    }
+
+    /**
+     * Ensures space for an additional double value and returns the address
+     * offset.
+     */
+    public int doubleParam() {
+        return param(8);
+    }
+
+    /**
+     * Ensures space for an additional pointer value and returns the address
+     * offset.
+     */
+    public int pointerParam() {
+        return param(POINTER_SIZE);
+    }
+
+    /**
+     * Ensures space for an additional buffer with the specified size (in bytes)
+     * and returns the address offset.
+     */
+    public int bufferParam(int size) {
+        return param(size, POINTER_SIZE);
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    /**
+     * Ensures space for an additional boolean value, sets the specified value
+     * at the allocated offset and returns that offset.
+     */
+    public int booleanParam(boolean value) {
+        int offset = booleanParam();
+        buffer.put(offset, value ? (byte) 1 : (byte) 0);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional byte value, sets the specified value at
+     * the allocated offset and returns that offset.
+     */
+    public int byteParam(byte value) {
+        int offset = byteParam();
+        buffer.put(offset, value);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional short value, sets the specified value at
+     * the allocated offset and returns that offset.
+     */
+    public int shortParam(short value) {
+        int offset = shortParam();
+        buffer.putShort(offset, value);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional int value, sets the specified value at
+     * the allocated offset and returns that offset.
+     */
+    public int intParam(int value) {
+        int offset = intParam();
+        buffer.putInt(offset, value);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional long value, sets the specified value at
+     * the allocated offset and returns that offset.
+     */
+    public int longParam(long value) {
+        int offset = longParam();
+        buffer.putLong(offset, value);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional float value, sets the specified value at
+     * the allocated offset and returns that offset.
+     */
+    public int floatParam(float value) {
+        int offset = floatParam();
+        buffer.putFloat(offset, value);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional double value, sets the specified value at
+     * the allocated offset and returns that offset.
+     */
+    public int doubleParam(double value) {
+        int offset = doubleParam();
+        buffer.putDouble(offset, value);
+        return offset;
+    }
+
+    /**
+     * Ensures space for an additional pointer value, sets the specified value
+     * at the allocated offset and returns that offset.
+     */
+    public int pointerParam(long value) {
+        int offset = pointerParam();
+        PointerBuffer.put(buffer, offset, value);
+        return offset;
+    }
+    // ----
+
+    /**
+     * Ensures space for an additional pointer buffer, sets the specified memory
+     * addresses and returns the address offset.
+     */
+    public int pointerArrayParam(long... pointers) {
+        int buffersAddress = bufferParam(pointers.length << POINTER_SHIFT);
+        for (int i = 0; i < pointers.length; i++) {
+            pointerParam(buffersAddress, i, pointers[i]);
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * Ensures space for an additional pointer buffer, sets the memory addresses
+     * of the specified buffers and returns the address offset.
+     */
+    public int pointerArrayParam(ByteBuffer... buffers) {
+        int buffersAddress = bufferParam(buffers.length << POINTER_SHIFT);
+        for (int i = 0; i < buffers.length; i++) {
+            pointerParam(buffersAddress, i, memAddress(buffers[i]));
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * Ensures space for two additional pointer buffers, sets the memory
+     * addresses and remaining bytes of the specified buffers and returns the
+     * address offset.
+     */
+    public int pointerArrayParamp(ByteBuffer... buffers) {
+        int buffersAddress = pointerArrayParam(buffers);
+
+        int buffersLengths = bufferParam(buffers.length << POINTER_SHIFT);
+        for (int i = 0; i < buffers.length; i++) {
+            pointerParam(buffersLengths, i, buffers[i].remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    /**
+     * ASCII encodes the specified strings with a null-terminator and ensures
+     * space for a buffer filled with the memory addresses of the encoded
+     * strings.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the memory address buffer
+     */
+    public int pointerArrayParamASCII(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memASCII(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * ASCII encodes the specified strings and ensures space for two additional
+     * buffers filled with the lengths and memory addresses of the encoded
+     * strings, respectively. The lengths are 4-bytes integers and the memory
+     * address buffer starts immediately after the lengths buffer.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the lengths buffer
+     */
+    public int pointerArrayParamASCIIi(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        int lengthsAddress = bufferParam(strings.length << 2);
+
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memASCII(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+            intParam(lengthsAddress, i, buffer.remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * ASCII encodes the specified strings and ensures space for two additional
+     * buffers filled with the lengths and memory addresses of the encoded
+     * strings, respectively. The lengths are pointer-sized integers and the
+     * memory address buffer starts immediately after the lengths buffer.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the lengths buffer
+     */
+    public int pointerArrayParamASCIIp(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        int lengthsAddress = bufferParam(strings.length << POINTER_SHIFT);
+
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memASCII(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+            pointerParam(lengthsAddress, i, buffer.remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * UTF8 encodes the specified strings with a null-terminator and ensures
+     * space for a buffer filled with the memory addresses of the encoded
+     * strings.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the memory address buffer
+     */
+    public int pointerArrayParamUTF8(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memUTF8(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * UTF8 encodes the specified strings and ensures space for two additional
+     * buffers filled with the lengths and memory addresses of the encoded
+     * strings, respectively. The lengths are 4-bytes integers and the memory
+     * address buffer starts immediately after the lengths buffer.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the lengths buffer
+     */
+    public int pointerArrayParamUTF8i(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        int lengthsAddress = bufferParam(strings.length << 2);
+
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memUTF8(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+            intParam(lengthsAddress, i, buffer.remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * UTF8 encodes the specified strings and ensures space for two additional
+     * buffers filled with the lengths and memory addresses of the encoded
+     * strings, respectively. The lengths are pointer-sized integers and the
+     * memory address buffer starts immediately after the lengths buffer.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the lengths buffer
+     */
+    public int pointerArrayParamUTF8p(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        int lengthsAddress = bufferParam(strings.length << POINTER_SHIFT);
+
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memUTF8(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+            pointerParam(lengthsAddress, i, buffer.remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * UTF16 encodes the specified strings with a null-terminator and ensures
+     * space for a buffer filled with the memory addresses of the encoded
+     * strings.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the memory address buffer
+     */
+    public int pointerArrayParamUTF16(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memUTF16(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * UTF16 encodes the specified strings and ensures space for two additional
+     * buffers filled with the lengths and memory addresses of the encoded
+     * strings, respectively. The lengths are 4-bytes integers and the memory
+     * address buffer starts immediately after the lengths buffer.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the lengths buffer
+     */
+    public int pointerArrayParamUTF16i(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        int lengthsAddress = bufferParam(strings.length << 2);
+
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memUTF16(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+            intParam(lengthsAddress, i, buffer.remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    /**
+     * UTF16 encodes the specified strings and ensures space for two additional
+     * buffers filled with the lengths and memory addresses of the encoded
+     * strings, respectively. The lengths are pointer-sized integers and the
+     * memory address buffer starts immediately after the lengths buffer.
+     *
+     * <p>
+     * The encoded buffers must be later freed with
+     * {@link #pointerArrayFree(int, int)}.</p>
+     *
+     * @return the offset to the lengths buffer
+     */
+    public int pointerArrayParamUTF16p(CharSequence... strings) {
+        int buffersAddress = bufferParam(strings.length << POINTER_SHIFT);
+        int lengthsAddress = bufferParam(strings.length << POINTER_SHIFT);
+
+        for (int i = 0; i < strings.length; i++) {
+            ByteBuffer buffer = MemoryUtil.memUTF16(strings[i]);
+
+            pointerParam(buffersAddress, i, memAddress(buffer));
+            pointerParam(lengthsAddress, i, buffer.remaining());
+        }
+
+        return buffersAddress;
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    /**
+     * Frees {@code length} memory blocks stored in the APIBuffer, starting at
+     * the specified {@code offset}.
+     */
+    public void pointerArrayFree(int offset, int length) {
+        for (int i = 0; i < length; i++) {
+            nmemFree(pointerValue(offset + (i << POINTER_SHIFT)));
+        }
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    /**
+     * Sets an int value at the specified index of the int buffer that starts at
+     * the specified offset.
+     */
+    public void intParam(int offset, int index, int value) {
+        buffer.putInt(offset + (index << 2), value);
+    }
+
+    /**
+     * Sets a pointer value at the specified index of the pointer buffer that
+     * starts at the specified offset.
+     */
+    public void pointerParam(int offset, int index, long value) {
+        PointerBuffer.put(buffer, offset + (index << POINTER_SHIFT), value);
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    /**
+     * Ensures space for the specified string encoded in ASCII, encodes the
+     * string at the allocated offset and returns that offset.
+     */
+    public int stringParamASCII(CharSequence value, boolean nullTerminated) {
+        if (value == null) {
+            return -1;
+        }
+
+        int offset = bufferParam(value.length() + (nullTerminated ? 1 : 0));
+        MemoryUtil.memASCII(value, nullTerminated, buffer, offset);
+        return offset;
+    }
+
+    /**
+     * Ensures space for the specified string encoded in UTF-8, encodes the
+     * string at the allocated offset and returns that offset.
+     */
+    public int stringParamUTF8(CharSequence value, boolean nullTerminated) {
+        if (value == null) {
+            return -1;
+        }
+
+        int encodedLen = MemoryUtil.memLengthUTF8(value, nullTerminated);
+        int offset = bufferParam(encodedLen);
+        MemoryUtil.memUTF8(value, nullTerminated, buffer, offset);
+        return offset;
+    }
+
+    /**
+     * Ensures space for the specified string encoded in UTF-16, encodes the
+     * string at the allocated offset and returns that offset.
+     */
+    public int stringParamUTF16(CharSequence value, boolean nullTerminated) {
+        if (value == null) {
+            return -1;
+        }
+
+        int offset = bufferParam((value.length() + (nullTerminated ? 1 : 0)) << 1);
+        MemoryUtil.memUTF16(value, nullTerminated, buffer, offset);
+        return offset;
+    }
+
+    // ---------------------------------------------------------------------------------------------------------------------
+    /**
+     * Returns the boolean value at the specified offset.
+     */
+    public boolean booleanValue(int offset) {
+        return buffer.get(offset) != 0;
+    }
+
+    /**
+     * Returns the boolean value at the specified offset.
+     */
+    public byte byteValue(int offset) {
+        return buffer.get(offset);
+    }
+
+    /**
+     * Returns the short value at the specified offset.
+     */
+    public short shortValue(int offset) {
+        return buffer.getShort(offset);
+    }
+
+    /**
+     * Returns the int value at the specified offset.
+     */
+    public int intValue(int offset) {
+        return buffer.getInt(offset);
+    }
+
+    /**
+     * Returns the long value at the specified offset.
+     */
+    public long longValue(int offset) {
+        return buffer.getLong(offset);
+    }
+
+    /**
+     * Returns the float value at the specified offset.
+     */
+    public float floatValue(int offset) {
+        return buffer.getFloat(offset);
+    }
+
+    /**
+     * Returns the double value at the specified offset.
+     */
+    public double doubleValue(int offset) {
+        return buffer.getDouble(offset);
+    }
+
+    /**
+     * Returns the pointer value at the specified offset.
+     */
+    public long pointerValue(int offset) {
+        return PointerBuffer.get(buffer, offset);
+    }
+
+    /**
+     * Returns the ASCII string value at the specified byte range.
+     */
+    public String stringValueASCII(int offset, int limit) {
+        buffer.position(offset);
+        buffer.limit(limit);
+        try {
+            return MemoryUtil.memASCII(buffer);
+        } finally {
+            buffer.clear();
+        }
+    }
+
+    /**
+     * Returns the UTF8 string value at the specified byte range.
+     */
+    public String stringValueUTF8(int offset, int limit) {
+        buffer.position(offset);
+        buffer.limit(limit);
+        try {
+            return MemoryUtil.memUTF8(buffer);
+        } finally {
+            buffer.clear();
+        }
+    }
+
+    /**
+     * Returns the UTF16 string value at the specified byte range.
+     */
+    public String stringValueUTF16(int offset, int limit) {
+        buffer.position(offset);
+        buffer.limit(limit);
+        try {
+            return MemoryUtil.memUTF16(buffer);
+        } finally {
+            buffer.clear();
+        }
+    }
+}

+ 218 - 0
jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIUtil.java

@@ -0,0 +1,218 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ */
+package com.jme3.lwjgl3.utils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility class useful to API bindings. [INTERNAL USE ONLY]
+ *
+ * <p>
+ * Method names in this class are prefixed with {@code api} to avoid ambiguities
+ * when used with static imports.</p>
+ */
+public final class APIUtil {
+
+    private static final ThreadLocal<APIBuffer> API_BUFFERS = new ThreadLocal<APIBuffer>() {
+        @Override
+        protected APIBuffer initialValue() {
+            return new APIBuffer();
+        }
+    };
+
+    private APIUtil() {
+    }
+
+    /**
+     * Returns a thread-local {@link APIBuffer} that has been reset.
+     */
+    public static APIBuffer apiBuffer() {
+        return API_BUFFERS.get().reset();
+    }
+
+    /**
+     * Returns a thread-local {@link APIBuffer}, without resetting it. This
+     * makes the APIBuffer work like a stack when used in nested API calls. The
+     * user is responsible for resetting the {@link APIBuffer} to an appropriate
+     * state before the nested call returns.
+     *
+     * @see APIBuffer#pop
+     */
+    public static APIBuffer apiStack() {
+        return API_BUFFERS.get().push();
+    }
+
+    /**
+     * A data class for API versioning information.
+     */
+    public static class APIVersion {
+
+        /**
+         * Returns the API major version.
+         */
+        public final int major;
+        /**
+         * Returns the API minor version.
+         */
+        public final int minor;
+
+        /**
+         * Returns the API revision. May be null.
+         */
+        public final String revision;
+        /**
+         * Returns the API implementation-specific versioning information. May
+         * be null.
+         */
+        public final String implementation;
+
+        public APIVersion(int major, int minor) {
+            this(major, minor, null, null);
+        }
+
+        public APIVersion(int major, int minor, String revision, String implementation) {
+            this.major = major;
+            this.minor = minor;
+            this.revision = revision;
+            this.implementation = implementation;
+        }
+
+    }
+
+    /**
+     * Parses a version string. The version string must have the format
+     * {@code MAJOR.MINOR.REVISION IMPL}, where {@code MAJOR} is the major
+     * version (integer), {@code MINOR} is the minor version (integer),
+     * {@code REVISION} is the revision version (string, optional) and
+     * {@code IMPL} is implementation-specific information (string, optional).
+     *
+     * @param version the API version string
+     *
+     * @return the parsed {@link APIVersion}
+     */
+    public static APIVersion apiParseVersion(String version) {
+        return apiParseVersion(version, null);
+    }
+
+    /**
+     * Parses a version string. The version string must have the format
+     * {@code PREFIX MAJOR.MINOR.REVISION IMPL}, where {@code PREFIX} is the
+     * specified prefix (string, optional), {@code MAJOR} is the major version
+     * (integer), {@code MINOR} is the minor version (integer), {@code REVISION}
+     * is the revision version (string, optional) and {@code IMPL} is
+     * implementation-specific information (string, optional).
+     *
+     * @param version the version string
+     * @param prefix the version string prefix, may be null
+     *
+     * @return the parsed {@link APIVersion}
+     */
+    public static APIVersion apiParseVersion(String version, String prefix) {
+        String pattern = "([0-9]+)[.]([0-9]+)([.]\\S+)?\\s*(.+)?";
+        if (prefix != null) {
+            pattern = prefix + "\\s+" + pattern;
+        }
+
+        Matcher matcher = Pattern.compile(pattern).matcher(version);
+        if (!matcher.matches()) {
+            throw new IllegalArgumentException(String.format("Malformed API version string [%s]", version));
+        }
+
+        return new APIVersion(
+                Integer.parseInt(matcher.group(1)),
+                Integer.parseInt(matcher.group(2)),
+                matcher.group(3),
+                matcher.group(4)
+        );
+    }
+
+    public static String apiUnknownToken(int token) {
+        return apiUnknownToken("Unknown", token);
+    }
+
+    public static String apiUnknownToken(String description, int token) {
+        return String.format("%s [0x%X]", description, token);
+    }
+
+    /**
+     * Returns a map of public static final integer fields in the specified
+     * classes, to their String representations. An optional filter can be
+     * specified to only include specific fields. The target map may be null, in
+     * which case a new map is allocated and returned.
+     *
+     * <p>
+     * This method is useful when debugging to quickly identify values returned
+     * from an API.</p>
+     *
+     * @param filter the filter to use (optional)
+     * @param target the target map (optional)
+     * @param tokenClasses the classes to get tokens from
+     *
+     * @return the token map
+     */
+    public static Map<Integer, String> apiClassTokens(TokenFilter filter, Map<Integer, String> target, Class<?>... tokenClasses) {
+        if (target == null) {
+            target = new HashMap<Integer, String>(64);
+        }
+
+        int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
+
+        for (Class<?> tokenClass : tokenClasses) {
+            if (tokenClass == null) {
+                continue;
+            }
+
+            for (Field field : tokenClass.getDeclaredFields()) {
+                // Get only <public static final int> fields.
+                if ((field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class) {
+                    try {
+                        int value = field.getInt(null);
+                        if (filter != null && !filter.accept(field, value)) {
+                            continue;
+                        }
+
+                        String name = target.get(value);
+                        target.put(value, name == null ? field.getName() : name + "|" + field.getName());
+                    } catch (IllegalAccessException e) {
+                        // Ignore
+                    }
+                }
+            }
+        }
+
+        return target;
+    }
+
+    public static Class<?> apiOptionalClass(String className) {
+        try {
+            return Class.forName(className);
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Simple interface for Field filtering.
+     */
+    public interface TokenFilter {
+
+        /**
+         * Should return true if the specified Field passes the filter.
+         *
+         * @param field the Field to test
+         * @param value the integer value of the field
+         *
+         * @return true if the Field is accepted
+         */
+        boolean accept(Field field, int value);
+
+    }
+
+}

+ 1 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglBuffer.java

@@ -32,6 +32,7 @@
 package com.jme3.opencl.lwjgl;
 
 import com.jme3.opencl.*;
+import com.jme3.opencl.lwjgl.info.Info;
 import java.nio.ByteBuffer;
 import org.lwjgl.opencl.*;
 

+ 1 - 1
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglContext.java

@@ -146,7 +146,7 @@ public class LwjglContext extends Context {
         }
         //get formats
         CLImageFormat.Buffer formatsB = new CLImageFormat.Buffer(BufferUtils.createByteBuffer(count * CLImageFormat.SIZEOF));
-        ret = CL10.clGetSupportedImageFormats(context, memFlags, typeFlag, formatsB, null);
+        ret = CL10.clGetSupportedImageFormats(context, memFlags, typeFlag, formatsB, (IntBuffer) null);
         Utils.checkError(ret, "clGetSupportedImageFormats");
         //convert formats
         ImageFormat[] formats = new ImageFormat[count];

+ 37 - 41
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglDevice.java

@@ -33,13 +33,12 @@ package com.jme3.opencl.lwjgl;
 
 import com.jme3.opencl.Device;
 import com.jme3.opencl.Platform;
+import com.jme3.opencl.lwjgl.info.Info;
 import java.util.Arrays;
 import java.util.Collection;
 import org.lwjgl.PointerBuffer;
 import org.lwjgl.opencl.CL10;
 import org.lwjgl.opencl.CL11;
-import org.lwjgl.opencl.CLDevice;
-import org.lwjgl.opencl.Info;
 
 /**
  *
@@ -47,18 +46,15 @@ import org.lwjgl.opencl.Info;
  */
 public final class LwjglDevice implements Device {
 
-    final CLDevice device;
+    final long device;
     final LwjglPlatform platform;
 
-    public LwjglDevice(CLDevice device, LwjglPlatform platform) {
+    public LwjglDevice(long device, LwjglPlatform platform) {
         this.device = device;
         this.platform = platform;
     }
     
     public long getDevice() {
-        return device.address();
-    }
-    public CLDevice getCLDevice() {
         return device;
     }
     
@@ -69,7 +65,7 @@ public final class LwjglDevice implements Device {
 
     @Override
     public DeviceType getDeviceType() {
-        int type = Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_TYPE);
+        int type = Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_TYPE);
         switch (type) {
             case CL10.CL_DEVICE_TYPE_ACCELERATOR: return DeviceType.ACCELEARTOR;
             case CL10.CL_DEVICE_TYPE_CPU: return DeviceType.CPU;
@@ -80,17 +76,17 @@ public final class LwjglDevice implements Device {
 
     @Override
     public int getVendorId() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_VENDOR_ID);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_VENDOR_ID);
     }
 
     @Override
     public boolean isAvailable() {
-        return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_AVAILABLE);
+        return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_AVAILABLE);
     }
 
     @Override
     public boolean hasCompiler() {
-        return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_COMPILER_AVAILABLE);
+        return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_COMPILER_AVAILABLE);
     }
 
     @Override
@@ -105,17 +101,17 @@ public final class LwjglDevice implements Device {
 
     @Override
     public boolean hasErrorCorrectingMemory() {
-        return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_ERROR_CORRECTION_SUPPORT);
+        return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_ERROR_CORRECTION_SUPPORT);
     }
 
     @Override
     public boolean hasUnifiedMemory() {
-        return Info.clGetDeviceInfoBoolean(device.address(), CL11.CL_DEVICE_HOST_UNIFIED_MEMORY);
+        return Info.clGetDeviceInfoBoolean(device, CL11.CL_DEVICE_HOST_UNIFIED_MEMORY);
     }
 
     @Override
     public boolean hasImageSupport() {
-        return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_IMAGE_SUPPORT);
+        return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_IMAGE_SUPPORT);
     }
     
     @Override
@@ -135,39 +131,39 @@ public final class LwjglDevice implements Device {
 
     @Override
     public Collection<? extends String> getExtensions() {
-        return Arrays.asList(Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_EXTENSIONS).split(" "));
+        return Arrays.asList(Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_EXTENSIONS).split(" "));
     }
 
     @Override
     public int getComputeUnits() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_COMPUTE_UNITS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_COMPUTE_UNITS);
     }
 
     @Override
     public int getClockFrequency() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_CLOCK_FREQUENCY);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_CLOCK_FREQUENCY);
     }
 
     @Override
     public int getAddressBits() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_ADDRESS_BITS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_ADDRESS_BITS);
     }
 
     @Override
     public boolean isLittleEndian() {
-        return Info.clGetDeviceInfoBoolean(device.address(), CL10.CL_DEVICE_ENDIAN_LITTLE);
+        return Info.clGetDeviceInfoBoolean(device, CL10.CL_DEVICE_ENDIAN_LITTLE);
     }
 
     @Override
     public long getMaximumWorkItemDimensions() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
     }
 
     @Override
     public long[] getMaximumWorkItemSizes() {
         int dim = (int) getMaximumWorkItemDimensions();
         PointerBuffer sizes = PointerBuffer.allocateDirect(dim);
-        Info.clGetDeviceInfoPointers(device.address(), CL10.CL_DEVICE_MAX_WORK_ITEM_SIZES, sizes);
+        Info.clGetDeviceInfoPointers(device, CL10.CL_DEVICE_MAX_WORK_ITEM_SIZES, sizes);
         long[] sx = new long[dim];
         sizes.get(sx);
         return sx;
@@ -175,74 +171,74 @@ public final class LwjglDevice implements Device {
 
     @Override
     public long getMaxiumWorkItemsPerGroup() {
-        return Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_MAX_WORK_GROUP_SIZE);
+        return Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_MAX_WORK_GROUP_SIZE);
     }
 
     @Override
     public int getMaximumSamplers() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_SAMPLERS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_SAMPLERS);
     }
 
     @Override
     public int getMaximumReadImages() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_READ_IMAGE_ARGS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_READ_IMAGE_ARGS);
     }
 
     @Override
     public int getMaximumWriteImages() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_WRITE_IMAGE_ARGS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_WRITE_IMAGE_ARGS);
     }
 
     @Override
     public long[] getMaximumImage2DSize() {
         return new long[] {
-            Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE2D_MAX_WIDTH),
-            Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE2D_MAX_HEIGHT)
+            Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE2D_MAX_WIDTH),
+            Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE2D_MAX_HEIGHT)
         };
     }
 
     @Override
     public long[] getMaximumImage3DSize() {
         return new long[] {
-            Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE3D_MAX_WIDTH),
-            Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE3D_MAX_HEIGHT),
-            Info.clGetDeviceInfoPointer(device.address(), CL10.CL_DEVICE_IMAGE3D_MAX_DEPTH)
+            Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE3D_MAX_WIDTH),
+            Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE3D_MAX_HEIGHT),
+            Info.clGetDeviceInfoPointer(device, CL10.CL_DEVICE_IMAGE3D_MAX_DEPTH)
         };
     }
     
     @Override
     public long getMaximumAllocationSize() {
-        return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_MAX_MEM_ALLOC_SIZE);
+        return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_MAX_MEM_ALLOC_SIZE);
     }
     
     @Override
     public long getGlobalMemorySize() {
-        return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_GLOBAL_MEM_SIZE);
+        return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_GLOBAL_MEM_SIZE);
     }
     
     @Override
     public long getLocalMemorySize() {
-        return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_LOCAL_MEM_SIZE);
+        return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_LOCAL_MEM_SIZE);
     }
     
     @Override
     public long getMaximumConstantBufferSize() {
-        return Info.clGetDeviceInfoLong(device.address(), CL10.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE);
+        return Info.clGetDeviceInfoLong(device, CL10.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE);
     }
     
     @Override
     public int getMaximumConstantArguments() {
-        return Info.clGetDeviceInfoInt(device.address(), CL10.CL_DEVICE_MAX_CONSTANT_ARGS);
+        return Info.clGetDeviceInfoInt(device, CL10.CL_DEVICE_MAX_CONSTANT_ARGS);
     }
 
     @Override
     public String getProfile() {
-        return Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_PROFILE);
+        return Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_PROFILE);
     }
 
     @Override
     public String getVersion() {
-        return  Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_VERSION);
+        return  Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_VERSION);
     }
 
     @Override
@@ -257,7 +253,7 @@ public final class LwjglDevice implements Device {
 
     @Override
     public String getCompilerVersion() {
-        return  Info.clGetDeviceInfoStringASCII(device.address(), CL11.CL_DEVICE_OPENCL_C_VERSION);
+        return  Info.clGetDeviceInfoStringASCII(device, CL11.CL_DEVICE_OPENCL_C_VERSION);
     }
 
     @Override
@@ -272,7 +268,7 @@ public final class LwjglDevice implements Device {
 
     @Override
     public String getDriverVersion() {
-        return  Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DRIVER_VERSION);
+        return  Info.clGetDeviceInfoStringASCII(device, CL10.CL_DRIVER_VERSION);
     }
 
     @Override
@@ -287,12 +283,12 @@ public final class LwjglDevice implements Device {
 
     @Override
     public String getName() {
-        return  Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_NAME);
+        return  Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_NAME);
     }
 
     @Override
     public String getVendor() {
-        return  Info.clGetDeviceInfoStringASCII(device.address(), CL10.CL_DEVICE_VENDOR);
+        return  Info.clGetDeviceInfoStringASCII(device, CL10.CL_DEVICE_VENDOR);
     }
 
     @Override

+ 1 - 1
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglEvent.java

@@ -32,9 +32,9 @@
 package com.jme3.opencl.lwjgl;
 
 import com.jme3.opencl.Event;
+import com.jme3.opencl.lwjgl.info.Info;
 import java.util.logging.Logger;
 import org.lwjgl.opencl.CL10;
-import org.lwjgl.opencl.Info;
 
 /**
  *

+ 5 - 1
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglImage.java

@@ -33,6 +33,7 @@ package com.jme3.opencl.lwjgl;
 
 import com.jme3.math.ColorRGBA;
 import com.jme3.opencl.*;
+import com.jme3.opencl.lwjgl.info.Info;
 import java.nio.ByteBuffer;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -272,7 +273,10 @@ public class LwjglImage extends Image {
     public ImageFormat getImageFormat() {
         Utils.b80.rewind();
         CLImageFormat format = new CLImageFormat(Utils.b80);
-        int ret = CL10.clGetImageInfo(image, CL10.CL_IMAGE_FORMAT, format.sizeof(), Utils.b80, null);
+        int limit = Utils.b80.limit();
+        Utils.b80.limit(format.sizeof());
+        int ret = CL10.clGetImageInfo(image, CL10.CL_IMAGE_FORMAT, Utils.b80, null);
+        Utils.b80.limit(limit);
         Utils.checkError(ret, "clGetImageInfo");
         return new ImageFormat(encodeImageChannelOrder(format.image_channel_order()), encodeImageChannelType(format.image_channel_data_type()));
     }

+ 1 - 2
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java

@@ -37,11 +37,10 @@ import com.jme3.math.Vector2f;
 import com.jme3.math.Vector4f;
 import com.jme3.opencl.*;
 import com.jme3.opencl.Buffer;
+import com.jme3.opencl.lwjgl.info.Info;
 import java.nio.*;
 import org.lwjgl.PointerBuffer;
 import org.lwjgl.opencl.CL10;
-import org.lwjgl.opencl.CLDevice;
-import org.lwjgl.opencl.Info;
 
 /**
  *

+ 54 - 12
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglPlatform.java

@@ -31,16 +31,20 @@
  */
 package com.jme3.opencl.lwjgl;
 
+import com.jme3.lwjgl3.utils.APIBuffer;
+import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer;
 import com.jme3.opencl.Device;
 import com.jme3.opencl.Platform;
+import com.jme3.opencl.lwjgl.info.Info;
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import org.lwjgl.PointerBuffer;
 import org.lwjgl.opencl.CL10;
-import org.lwjgl.opencl.CLDevice;
-import org.lwjgl.opencl.CLPlatform;
-import org.lwjgl.opencl.Info;
+import static org.lwjgl.system.Pointer.POINTER_SHIFT;
 
 /**
  *
@@ -48,14 +52,14 @@ import org.lwjgl.opencl.Info;
  */
 public final class LwjglPlatform implements Platform {
     
-    final CLPlatform platform;
+    final long platform;
     List<LwjglDevice> devices;
     
-    public LwjglPlatform(CLPlatform platform) {
+    public LwjglPlatform(long platform) {
         this.platform = platform;
     }
 
-    public CLPlatform getPlatform() {
+    public long getPlatform() {
         return platform;
     }
     
@@ -63,16 +67,54 @@ public final class LwjglPlatform implements Platform {
     public List<LwjglDevice> getDevices() {
         if (devices == null) {
             devices = new ArrayList<>();
-            for (CLDevice d : platform.getDevices(CL10.CL_DEVICE_TYPE_ALL)) {
+            for (long d : getDevices(CL10.CL_DEVICE_TYPE_ALL)) {
                 devices.add(new LwjglDevice(d, this));
             }
         }
         return devices;
     }
+    
+    /**
+     * Returns a list of the available devices on this platform that match the
+     * specified type, filtered by the specified filter.
+     * 
+     * Copied from the old release.
+     *
+     * @param device_type the device type
+     * @param filter the device filter
+     *
+     * @return the available devices
+     */
+    private long[] getDevices(int device_type) {
+        int[] count = new int[1];
+        int errcode = CL10.clGetDeviceIDs(platform, device_type, null, count);
+        if (errcode == CL10.CL_DEVICE_NOT_FOUND) {
+            return new long[0];
+        }
+        Utils.checkError(errcode, "clGetDeviceIDs");
+
+        int num_devices = count[0];
+        if (num_devices == 0) {
+            return new long[0];
+        }
+
+        PointerBuffer devices = PointerBuffer.allocateDirect(num_devices);
+
+        errcode = CL10.clGetDeviceIDs(platform, device_type,devices, (IntBuffer) null);
+        Utils.checkError(errcode, "clGetDeviceIDs");
+
+        long[] deviceIDs = new long[num_devices];
+        devices.rewind();
+        for (int i = 0; i < num_devices; i++) {
+            deviceIDs[i] = devices.get();
+        }
+
+        return deviceIDs;
+    }
 
     @Override
     public String getProfile() {
-        return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_PROFILE);
+        return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_PROFILE);
     }
 
     @Override
@@ -87,7 +129,7 @@ public final class LwjglPlatform implements Platform {
 
     @Override
     public String getVersion() {
-        return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_VERSION);
+        return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_VERSION);
     }
 
     @Override
@@ -102,12 +144,12 @@ public final class LwjglPlatform implements Platform {
 
     @Override
     public String getName() {
-        return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_NAME);
+        return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_NAME);
     }
 
     @Override
     public String getVendor() {
-        return Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_VENDOR);
+        return Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_VENDOR);
     }
 
     @Override
@@ -122,7 +164,7 @@ public final class LwjglPlatform implements Platform {
 
     @Override
     public Collection<? extends String> getExtensions() {
-        return Arrays.asList(Info.clGetPlatformInfoStringASCII(platform.address(), CL10.CL_PLATFORM_EXTENSIONS).split(" "));
+        return Arrays.asList(Info.clGetPlatformInfoStringASCII(platform, CL10.CL_PLATFORM_EXTENSIONS).split(" "));
     }
 
 	@Override

+ 4 - 3
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/LwjglProgram.java

@@ -32,14 +32,15 @@
 package com.jme3.opencl.lwjgl;
 
 import com.jme3.opencl.*;
+import com.jme3.opencl.lwjgl.info.Info;
 import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.lwjgl.BufferUtils;
 import org.lwjgl.PointerBuffer;
 import org.lwjgl.opencl.*;
 import org.lwjgl.system.MemoryUtil;
-import org.lwjgl.system.Pointer;
 
 /**
  *
@@ -94,7 +95,7 @@ public class LwjglProgram extends Program {
         final ByteBuffer buffer = BufferUtils.createByteBuffer(count);
         ret = CL10.clGetProgramBuildInfo(program, device, CL10.CL_PROGRAM_BUILD_LOG, buffer, null);
         Utils.checkError(ret, "clGetProgramBuildInfo");
-        return MemoryUtil.memDecodeASCII(buffer);
+        return MemoryUtil.memASCII(buffer);
     }
     
     private String Log() {
@@ -123,7 +124,7 @@ public class LwjglProgram extends Program {
         Utils.checkError(ret, "clCreateKernelsInProgram");
         int count = Utils.tempBuffers[0].b16i.get(0);
         PointerBuffer buf = PointerBuffer.allocateDirect(count);
-        ret = CL10.clCreateKernelsInProgram(program, buf, null);
+        ret = CL10.clCreateKernelsInProgram(program, buf, (IntBuffer) null);
         Utils.checkError(ret, "clCreateKernelsInProgram");
         Kernel[] kx = new Kernel[count];
         for (int i=0; i<count; ++i) {

+ 1 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/Utils.java

@@ -34,6 +34,7 @@ package com.jme3.opencl.lwjgl;
 import com.jme3.opencl.MappingAccess;
 import com.jme3.opencl.MemoryAccess;
 import com.jme3.opencl.OpenCLException;
+import com.jme3.opencl.lwjgl.info.CLUtil;
 import java.nio.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;

+ 114 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/CLUtil.java

@@ -0,0 +1,114 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ */
+package com.jme3.opencl.lwjgl.info;
+
+import com.jme3.lwjgl3.utils.APIUtil.TokenFilter;
+import com.jme3.opencl.OpenCLException;
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiPredicate;
+import org.lwjgl.opencl.CL10;
+
+import static org.lwjgl.opencl.CL10.*;
+import org.lwjgl.opencl.CL11;
+import org.lwjgl.opencl.CL12;
+import org.lwjgl.opencl.CL20;
+import org.lwjgl.opencl.INTELAccelerator;
+import org.lwjgl.opencl.KHRICD;
+import static org.lwjgl.system.APIUtil.*;
+
+public final class CLUtil {
+
+    /**
+     * Maps OpenCL error token values to their String representations.
+     */
+    private static final Map<Integer, String> CL_ERROR_TOKENS = apiClassTokens(
+            new BiPredicate<Field, Integer>() {
+        private final List<String> EXCLUDE = Arrays.asList("CL_DEVICE_TYPE_ALL", "CL_BUILD_NONE", "CL_BUILD_ERROR", "CL_BUILD_IN_PROGRESS");
+
+        @Override
+        public boolean test(Field field, Integer value) {
+            return value < 0 && !EXCLUDE.contains(field.getName()); // OpenCL errors have negative values.
+        }
+    },
+            null,
+            CL10.class,
+            apiOptionalClass("org.lwjgl.opencl.CL10GL"),
+            CL11.class,
+            CL12.class,
+            CL20.class,
+            apiOptionalClass("org.lwjgl.opencl.APPLEGLSharing"),
+            INTELAccelerator.class,
+            apiOptionalClass("org.lwjgl.opencl.KHRGLSharing"),
+            apiOptionalClass("org.lwjgl.opencl.KHREGLEvent"),
+            apiOptionalClass("org.lwjgl.opencl.KHREGLImage"),
+            KHRICD.class
+    /*, EXTDeviceFission.class*/
+    );
+
+    private CLUtil() {
+    }
+
+    /**
+     * Checks the {@code errcode} present in the current position of the
+     * specified {@code errcode_ret} buffer and throws an
+     * {@link OpenCLException} if it's not equal to {@link CL10#CL_SUCCESS}.
+     *
+     * @param errcode_ret the {@code errcode} buffer
+     *
+     * @throws OpenCLException
+     */
+    public static void checkCLError(ByteBuffer errcode_ret) {
+        checkCLError(errcode_ret.getInt(errcode_ret.position()));
+    }
+
+    /**
+     * Checks the {@code errcode} present in the current position of the
+     * specified {@code errcode_ret} buffer and throws an
+     * {@link OpenCLException} if it's not equal to {@link CL10#CL_SUCCESS}.
+     *
+     * @param errcode_ret the {@code errcode} buffer
+     *
+     * @throws OpenCLException
+     */
+    public static void checkCLError(IntBuffer errcode_ret) {
+        checkCLError(errcode_ret.get(errcode_ret.position()));
+    }
+
+    /**
+     * Checks the specified {@code errcode} and throws an
+     * {@link OpenCLException} if it's not equal to {@link CL10#CL_SUCCESS}.
+     *
+     * @param errcode the {@code errcode} to check
+     *
+     * @throws OpenCLException
+     */
+    public static void checkCLError(int errcode) {
+        if (errcode != CL_SUCCESS) {
+            throw new OpenCLException(getErrcodeName(errcode));
+        }
+    }
+
+    /**
+     * Returns the token name of the specified {@code errcode}.
+     *
+     * @param errcode the {@code errcode}
+     *
+     * @return the {@code errcode} token name
+     */
+    public static String getErrcodeName(int errcode) {
+        String errname = CL_ERROR_TOKENS.get(errcode);
+        if (errname == null) {
+            errname = apiUnknownToken(errcode);
+        }
+
+        return errname;
+    }
+
+}

+ 687 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/Info.java

@@ -0,0 +1,687 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ * MACHINE GENERATED FILE, DO NOT EDIT
+ */
+package com.jme3.opencl.lwjgl.info;
+
+import org.lwjgl.PointerBuffer;
+
+import static org.lwjgl.opencl.CL10.*;
+import static org.lwjgl.opencl.CL12.*;
+import static org.lwjgl.opencl.CL20.*;
+import static org.lwjgl.opencl.CL10GL.*;
+
+/**
+ * This class provides methods that can be used to query information about
+ * OpenCL objects. These methods are similar to the corresponding
+ * {@code clGet&lt;Type&gt;Info} function for each object type, except that only
+ * a single value is returned. Which one of these methods should be used depends
+ * on the type of the information being queried.
+ */
+public final class Info {
+
+    private Info() {
+    }
+
+    // ------------------------------------
+    // Platform (CL10.clGetPlatformInfo)
+    // ------------------------------------
+    private static final InfoQuery PLATFORM = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetPlatformInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * String version of: {@link CL10#clGetPlatformInfo GetPlatformInfo}
+     */
+    public static String clGetPlatformInfoStringASCII(long platform, int param_name) {
+        return PLATFORM.getStringASCII(platform, param_name);
+    }
+
+    /**
+     * String with explicit length version of: {@link CL10#clGetPlatformInfo GetPlatformInfo}
+     */
+    public static String clGetPlatformInfoStringASCII(long platform, int param_name, int param_value_size) {
+        return PLATFORM.getStringASCII(platform, param_name, param_value_size);
+    }
+
+    /**
+     * UTF-8 string version of: {@link CL10#clGetPlatformInfo GetPlatformInfo}
+     */
+    public static String clGetPlatformInfoStringUTF8(long platform, int param_name) {
+        return PLATFORM.getStringUTF8(platform, param_name);
+    }
+
+    /**
+     * UTF-8 string with explicit length version of:
+     * {@link CL10#clGetPlatformInfo GetPlatformInfo}
+     */
+    public static String clGetPlatformInfoStringUTF8(long platform, int param_name, int param_value_size) {
+        return PLATFORM.getStringUTF8(platform, param_name, param_value_size);
+    }
+
+    // ------------------------------------
+    // Device (CL10.clGetDeviceInfo)
+    // ------------------------------------
+    private static final InfoQuery DEVICE = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetDeviceInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single boolean value version of:
+     * {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static boolean clGetDeviceInfoBoolean(long device, int param_name) {
+        return DEVICE.getBoolean(device, param_name);
+    }
+
+    /**
+     * Single int value version of: {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static int clGetDeviceInfoInt(long device, int param_name) {
+        return DEVICE.getInt(device, param_name);
+    }
+
+    /**
+     * Single long value version of: {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static long clGetDeviceInfoLong(long device, int param_name) {
+        return DEVICE.getLong(device, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static long clGetDeviceInfoPointer(long device, int param_name) {
+        return DEVICE.getPointer(device, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static int clGetDeviceInfoPointers(long device, int param_name, PointerBuffer target) {
+        return DEVICE.getPointers(device, param_name, target);
+    }
+
+    /**
+     * String version of: {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static String clGetDeviceInfoStringASCII(long device, int param_name) {
+        return DEVICE.getStringASCII(device, param_name);
+    }
+
+    /**
+     * String with explicit length version of: {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static String clGetDeviceInfoStringASCII(long device, int param_name, int param_value_size) {
+        return DEVICE.getStringASCII(device, param_name, param_value_size);
+    }
+
+    /**
+     * UTF-8 string version of: {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static String clGetDeviceInfoStringUTF8(long device, int param_name) {
+        return DEVICE.getStringUTF8(device, param_name);
+    }
+
+    /**
+     * UTF-8 string with explicit length version of:
+     * {@link CL10#clGetDeviceInfo GetDeviceInfo}
+     */
+    public static String clGetDeviceInfoStringUTF8(long device, int param_name, int param_value_size) {
+        return DEVICE.getStringUTF8(device, param_name, param_value_size);
+    }
+
+    // ------------------------------------
+    // Context (CL10.clGetContextInfo)
+    // ------------------------------------
+    private static final InfoQuery CONTEXT = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetContextInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of: {@link CL10#clGetContextInfo GetContextInfo}
+     */
+    public static int clGetContextInfoInt(long context, int param_name) {
+        return CONTEXT.getInt(context, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetContextInfo GetContextInfo}
+     */
+    public static long clGetContextInfoPointer(long context, int param_name) {
+        return CONTEXT.getPointer(context, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetContextInfo GetContextInfo}
+     */
+    public static int clGetContextInfoPointers(long context, int param_name, PointerBuffer target) {
+        return CONTEXT.getPointers(context, param_name, target);
+    }
+
+    // ------------------------------------
+    // Command Queue (CL10.clGetCommandQueueInfo)
+    // ------------------------------------
+    private static final InfoQuery COMMAND_QUEUE = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetCommandQueueInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of:
+     * {@link CL10#clGetCommandQueueInfo GetCommandQueueInfo}
+     */
+    public static int clGetCommandQueueInfoInt(long command_queue, int param_name) {
+        return COMMAND_QUEUE.getInt(command_queue, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetCommandQueueInfo GetCommandQueueInfo}
+     */
+    public static long clGetCommandQueueInfoPointer(long command_queue, int param_name) {
+        return COMMAND_QUEUE.getPointer(command_queue, param_name);
+    }
+
+    /**
+     * PointBuffer version of:
+     * {@link CL10#clGetCommandQueueInfo GetCommandQueueInfo}
+     */
+    public static int clGetCommandQueueInfoPointers(long command_queue, int param_name, PointerBuffer target) {
+        return COMMAND_QUEUE.getPointers(command_queue, param_name, target);
+    }
+
+    // ------------------------------------
+    // Mem Object (CL10.clGetMemObjectInfo)
+    // ------------------------------------
+    private static final InfoQuery MEM_OBJECT = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetMemObjectInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single boolean value version of:
+     * {@link CL10#clGetMemObjectInfo GetMemObjectInfo}
+     */
+    public static boolean clGetMemObjectInfoBoolean(long memobj, int param_name) {
+        return MEM_OBJECT.getBoolean(memobj, param_name);
+    }
+
+    /**
+     * Single int value version of:
+     * {@link CL10#clGetMemObjectInfo GetMemObjectInfo}
+     */
+    public static int clGetMemObjectInfoInt(long memobj, int param_name) {
+        return MEM_OBJECT.getInt(memobj, param_name);
+    }
+
+    /**
+     * Single long value version of:
+     * {@link CL10#clGetMemObjectInfo GetMemObjectInfo}
+     */
+    public static long clGetMemObjectInfoLong(long memobj, int param_name) {
+        return MEM_OBJECT.getLong(memobj, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetMemObjectInfo GetMemObjectInfo}
+     */
+    public static long clGetMemObjectInfoPointer(long memobj, int param_name) {
+        return MEM_OBJECT.getPointer(memobj, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetMemObjectInfo GetMemObjectInfo}
+     */
+    public static int clGetMemObjectInfoPointers(long memobj, int param_name, PointerBuffer target) {
+        return MEM_OBJECT.getPointers(memobj, param_name, target);
+    }
+
+    // ------------------------------------
+    // Image (CL10.clGetImageInfo)
+    // ------------------------------------
+    private static final InfoQuery IMAGE = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetImageInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of: {@link CL10#clGetImageInfo GetImageInfo}
+     */
+    public static int clGetImageInfoInt(long image, int param_name) {
+        return IMAGE.getInt(image, param_name);
+    }
+
+    /**
+     * Single pointer value version of: {@link CL10#clGetImageInfo GetImageInfo}
+     */
+    public static long clGetImageInfoPointer(long image, int param_name) {
+        return IMAGE.getPointer(image, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetImageInfo GetImageInfo}
+     */
+    public static int clGetImageInfoPointers(long image, int param_name, PointerBuffer target) {
+        return IMAGE.getPointers(image, param_name, target);
+    }
+
+    // ------------------------------------
+    // Pipe (CL20.clGetPipeInfo)
+    // ------------------------------------
+    private static final InfoQuery PIPE = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetPipeInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of: {@link CL20#clGetPipeInfo GetPipeInfo}
+     */
+    public static int clGetPipeInfoInt(long pipe, int param_name) {
+        return PIPE.getInt(pipe, param_name);
+    }
+
+    // ------------------------------------
+    // Program (CL10.clGetProgramInfo)
+    // ------------------------------------
+    private static final InfoQuery PROGRAM = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetProgramInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of: {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static int clGetProgramInfoInt(long program, int param_name) {
+        return PROGRAM.getInt(program, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static long clGetProgramInfoPointer(long program, int param_name) {
+        return PROGRAM.getPointer(program, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static int clGetProgramInfoPointers(long program, int param_name, PointerBuffer target) {
+        return PROGRAM.getPointers(program, param_name, target);
+    }
+
+    /**
+     * String version of: {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static String clGetProgramInfoStringASCII(long program, int param_name) {
+        return PROGRAM.getStringASCII(program, param_name);
+    }
+
+    /**
+     * String with explicit length version of: {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static String clGetProgramInfoStringASCII(long program, int param_name, int param_value_size) {
+        return PROGRAM.getStringASCII(program, param_name, param_value_size);
+    }
+
+    /**
+     * UTF-8 string version of: {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static String clGetProgramInfoStringUTF8(long program, int param_name) {
+        return PROGRAM.getStringUTF8(program, param_name);
+    }
+
+    /**
+     * UTF-8 string with explicit length version of:
+     * {@link CL10#clGetProgramInfo GetProgramInfo}
+     */
+    public static String clGetProgramInfoStringUTF8(long program, int param_name, int param_value_size) {
+        return PROGRAM.getStringUTF8(program, param_name, param_value_size);
+    }
+
+    // ------------------------------------
+    // Program Build (CL10.clGetProgramBuildInfo)
+    // ------------------------------------
+    private static final InfoQueryObject PROGRAM_BUILD = new InfoQueryObject() {
+        @Override
+        protected int get(long pointer, long arg, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetProgramBuildInfo(pointer, arg, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of:
+     * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static int clGetProgramBuildInfoInt(long program, long device, int param_name) {
+        return PROGRAM_BUILD.getInt(program, device, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static long clGetProgramBuildInfoPointer(long program, long device, int param_name) {
+        return PROGRAM_BUILD.getPointer(program, device, param_name);
+    }
+
+    /**
+     * PointBuffer version of:
+     * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static int clGetProgramBuildInfoPointers(long program, long device, int param_name, PointerBuffer target) {
+        return PROGRAM_BUILD.getPointers(program, device, param_name, target);
+    }
+
+    /**
+     * String version of: {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static String clGetProgramBuildInfoStringASCII(long program, long device, int param_name) {
+        return PROGRAM_BUILD.getStringASCII(program, device, param_name);
+    }
+
+    /**
+     * String with explicit length version of: {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static String clGetProgramBuildInfoStringASCII(long program, long device, int param_name, int param_value_size) {
+        return PROGRAM_BUILD.getStringASCII(program, device, param_name, param_value_size);
+    }
+
+    /**
+     * UTF-8 string version of:
+     * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static String clGetProgramBuildInfoStringUTF8(long program, long device, int param_name) {
+        return PROGRAM_BUILD.getStringUTF8(program, device, param_name);
+    }
+
+    /**
+     * UTF-8 string with explicit length version of:
+     * {@link CL10#clGetProgramBuildInfo GetProgramBuildInfo}
+     */
+    public static String clGetProgramBuildInfoStringUTF8(long program, long device, int param_name, int param_value_size) {
+        return PROGRAM_BUILD.getStringUTF8(program, device, param_name, param_value_size);
+    }
+
+    // ------------------------------------
+    // Kernel (CL10.clGetKernelInfo)
+    // ------------------------------------
+    private static final InfoQuery KERNEL = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetKernelInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of: {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static int clGetKernelInfoInt(long kernel, int param_name) {
+        return KERNEL.getInt(kernel, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static long clGetKernelInfoPointer(long kernel, int param_name) {
+        return KERNEL.getPointer(kernel, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static int clGetKernelInfoPointers(long kernel, int param_name, PointerBuffer target) {
+        return KERNEL.getPointers(kernel, param_name, target);
+    }
+
+    /**
+     * String version of: {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static String clGetKernelInfoStringASCII(long kernel, int param_name) {
+        return KERNEL.getStringASCII(kernel, param_name);
+    }
+
+    /**
+     * String with explicit length version of: {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static String clGetKernelInfoStringASCII(long kernel, int param_name, int param_value_size) {
+        return KERNEL.getStringASCII(kernel, param_name, param_value_size);
+    }
+
+    /**
+     * UTF-8 string version of: {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static String clGetKernelInfoStringUTF8(long kernel, int param_name) {
+        return KERNEL.getStringUTF8(kernel, param_name);
+    }
+
+    /**
+     * UTF-8 string with explicit length version of:
+     * {@link CL10#clGetKernelInfo GetKernelInfo}
+     */
+    public static String clGetKernelInfoStringUTF8(long kernel, int param_name, int param_value_size) {
+        return KERNEL.getStringUTF8(kernel, param_name, param_value_size);
+    }
+
+    // ------------------------------------
+    // Kernel WorkGroup (CL10.clGetKernelWorkGroupInfo)
+    // ------------------------------------
+    private static final InfoQueryObject KERNEL_WORKGROUP = new InfoQueryObject() {
+        @Override
+        protected int get(long pointer, long arg, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetKernelWorkGroupInfo(pointer, arg, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single long value version of:
+     * {@link CL10#clGetKernelWorkGroupInfo GetKernelWorkGroupInfo}
+     */
+    public static long clGetKernelWorkGroupInfoLong(long kernel, long device, int param_name) {
+        return KERNEL_WORKGROUP.getLong(kernel, device, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetKernelWorkGroupInfo GetKernelWorkGroupInfo}
+     */
+    public static long clGetKernelWorkGroupInfoPointer(long kernel, long device, int param_name) {
+        return KERNEL_WORKGROUP.getPointer(kernel, device, param_name);
+    }
+
+    /**
+     * PointBuffer version of:
+     * {@link CL10#clGetKernelWorkGroupInfo GetKernelWorkGroupInfo}
+     */
+    public static int clGetKernelWorkGroupInfoPointers(long kernel, long device, int param_name, PointerBuffer target) {
+        return KERNEL_WORKGROUP.getPointers(kernel, device, param_name, target);
+    }
+
+    // ------------------------------------
+    // Kernel Arg (CL12.clGetKernelArgInfo)
+    // ------------------------------------
+    private static final InfoQueryInt KERNEL_ARG = new InfoQueryInt() {
+        @Override
+        protected int get(long pointer, int arg, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetKernelArgInfo(pointer, arg, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of:
+     * {@link CL12#clGetKernelArgInfo GetKernelArgInfo}
+     */
+    public static int clGetKernelArgInfoInt(long kernel, int arg_indx, int param_name) {
+        return KERNEL_ARG.getInt(kernel, arg_indx, param_name);
+    }
+
+    /**
+     * Single long value version of:
+     * {@link CL12#clGetKernelArgInfo GetKernelArgInfo}
+     */
+    public static long clGetKernelArgInfoLong(long kernel, int arg_indx, int param_name) {
+        return KERNEL_ARG.getLong(kernel, arg_indx, param_name);
+    }
+
+    /**
+     * String version of: {@link CL12#clGetKernelArgInfo GetKernelArgInfo}
+     */
+    public static String clGetKernelArgInfoStringASCII(long kernel, int arg_indx, int param_name) {
+        return KERNEL_ARG.getStringASCII(kernel, arg_indx, param_name);
+    }
+
+    /**
+     * String with explicit length version of: {@link CL12#clGetKernelArgInfo GetKernelArgInfo}
+     */
+    public static String clGetKernelArgInfoStringASCII(long kernel, int arg_indx, int param_name, int param_value_size) {
+        return KERNEL_ARG.getStringASCII(kernel, arg_indx, param_name, param_value_size);
+    }
+
+    /**
+     * UTF-8 string version of: {@link CL12#clGetKernelArgInfo GetKernelArgInfo}
+     */
+    public static String clGetKernelArgInfoStringUTF8(long kernel, int arg_indx, int param_name) {
+        return KERNEL_ARG.getStringUTF8(kernel, arg_indx, param_name);
+    }
+
+    /**
+     * UTF-8 string with explicit length version of:
+     * {@link CL12#clGetKernelArgInfo GetKernelArgInfo}
+     */
+    public static String clGetKernelArgInfoStringUTF8(long kernel, int arg_indx, int param_name, int param_value_size) {
+        return KERNEL_ARG.getStringUTF8(kernel, arg_indx, param_name, param_value_size);
+    }
+
+    // ------------------------------------
+    // Sampler (CL10.clGetSamplerInfo)
+    // ------------------------------------
+    private static final InfoQuery SAMPLER = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetSamplerInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single boolean value version of:
+     * {@link CL10#clGetSamplerInfo GetSamplerInfo}
+     */
+    public static boolean clGetSamplerInfoBoolean(long sampler, int param_name) {
+        return SAMPLER.getBoolean(sampler, param_name);
+    }
+
+    /**
+     * Single int value version of: {@link CL10#clGetSamplerInfo GetSamplerInfo}
+     */
+    public static int clGetSamplerInfoInt(long sampler, int param_name) {
+        return SAMPLER.getInt(sampler, param_name);
+    }
+
+    /**
+     * Single pointer value version of:
+     * {@link CL10#clGetSamplerInfo GetSamplerInfo}
+     */
+    public static long clGetSamplerInfoPointer(long sampler, int param_name) {
+        return SAMPLER.getPointer(sampler, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetSamplerInfo GetSamplerInfo}
+     */
+    public static int clGetSamplerInfoPointers(long sampler, int param_name, PointerBuffer target) {
+        return SAMPLER.getPointers(sampler, param_name, target);
+    }
+
+    // ------------------------------------
+    // Event (CL10.clGetEventInfo)
+    // ------------------------------------
+    private static final InfoQuery EVENT = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetEventInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of: {@link CL10#clGetEventInfo GetEventInfo}
+     */
+    public static int clGetEventInfoInt(long event, int param_name) {
+        return EVENT.getInt(event, param_name);
+    }
+
+    /**
+     * Single pointer value version of: {@link CL10#clGetEventInfo GetEventInfo}
+     */
+    public static long clGetEventInfoPointer(long event, int param_name) {
+        return EVENT.getPointer(event, param_name);
+    }
+
+    /**
+     * PointBuffer version of: {@link CL10#clGetEventInfo GetEventInfo}
+     */
+    public static int clGetEventInfoPointers(long event, int param_name, PointerBuffer target) {
+        return EVENT.getPointers(event, param_name, target);
+    }
+
+    // ------------------------------------
+    // Event Profiling (CL10.clGetEventProfilingInfo)
+    // ------------------------------------
+    private static final InfoQuery EVENT_PROFILING = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetEventProfilingInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single long value version of:
+     * {@link CL10#clGetEventProfilingInfo GetEventProfilingInfo}
+     */
+    public static long clGetEventProfilingInfoLong(long event, int param_name) {
+        return EVENT_PROFILING.getLong(event, param_name);
+    }
+
+    // ------------------------------------
+    // GL Texture (CL10GL.clGetGLTextureInfo)
+    // ------------------------------------
+    private static final InfoQuery GL_TEXTURE = new InfoQuery() {
+        @Override
+        protected int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret) {
+            return nclGetGLTextureInfo(pointer, param_name, param_value_size, param_value, param_value_size_ret);
+        }
+    };
+
+    /**
+     * Single int value version of:
+     * {@link CL10GL#clGetGLTextureInfo GetGLTextureInfo}
+     */
+    public static int clGetGLTextureInfoInt(long memobj, int param_name) {
+        return GL_TEXTURE.getInt(memobj, param_name);
+    }
+
+}

+ 215 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQuery.java

@@ -0,0 +1,215 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ */
+package com.jme3.opencl.lwjgl.info;
+
+import com.jme3.lwjgl3.utils.APIBuffer;
+import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer;
+import static com.jme3.opencl.lwjgl.info.CLUtil.checkCLError;
+import org.lwjgl.PointerBuffer;
+
+import static org.lwjgl.system.Checks.*;
+import static org.lwjgl.system.MemoryUtil.*;
+import static org.lwjgl.system.Pointer.*;
+
+/**
+ * Base class for OpenCL object information queries.
+ * <p/>
+ * All methods require the object being queried (a pointer value) and the
+ * integer parameter name.
+ *
+ * @see Info
+ */
+abstract class InfoQuery {
+
+    protected abstract int get(long pointer, int param_name, long param_value_size, long param_value, long param_value_size_ret);
+
+    InfoQuery() {
+    }
+
+    /**
+     * Returns the integer value for the specified {@code param_name}, converted
+     * to a boolean.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's boolean value
+     */
+    boolean getBoolean(long object, int param_name) {
+        return getInt(object, param_name) != 0;
+    }
+
+    /**
+     * Returns the integer value for the specified {@code param_name}.
+     * <p/>
+     * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}),
+     * {@link #getPointer} should be used instead.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's int value
+     */
+    int getInt(long object, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, param_name, 4L, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.intValue(0);
+    }
+
+    /**
+     * Returns the long value for the specified {@code param_name}.
+     * <p/>
+     * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}),
+     * {@link #getPointer} should be used instead.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's long value
+     */
+    long getLong(long object, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, param_name, 8L, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.longValue(0);
+    }
+
+    /**
+     * Returns the pointer value for the specified {@code param_name}.
+     * <p/>
+     * This method should also be used for integer parameters that may be 32 or
+     * 64 bits (e.g. {@code size_t}).
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's pointer value
+     */
+    long getPointer(long object, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, param_name, POINTER_SIZE, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.pointerValue(0);
+    }
+
+    /**
+     * Writes the pointer list for the specified {@code param_name} into
+     * {@code target}.
+     * <p/>
+     * This method should also be used for integer parameters that may be 32 or
+     * 64 bits (e.g. {@code size_t}).
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     * @param target the buffer in which to put the returned pointer list
+     *
+     * @return how many pointers were actually returned
+     */
+    int getPointers(long object, int param_name, PointerBuffer target) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, param_name, target.remaining() * POINTER_SIZE, memAddress(target), __buffer.address());
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return (int) (__buffer.pointerValue(0) >> POINTER_SHIFT);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be ASCII encoded.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's string value
+     */
+    String getStringASCII(long object, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int bytes = getString(object, param_name, __buffer);
+        return __buffer.stringValueASCII(0, bytes);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be ASCII encoded and have length equal to {@code
+     * param_value_size}.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     * @param param_value_size the explicit string length
+     *
+     * @return the parameter's string value
+     */
+    String getStringASCII(long object, int param_name, int param_value_size) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, param_name, param_value_size, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.stringValueASCII(0, param_value_size);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be UTF-8 encoded.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's string value
+     */
+    String getStringUTF8(long object, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int bytes = getString(object, param_name, __buffer);
+        return __buffer.stringValueUTF8(0, bytes);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be UTF-8 encoded and have length equal to {@code
+     * param_value_size}.
+     *
+     * @param object the object to query
+     * @param param_name the parameter to query
+     * @param param_value_size the explicit string length
+     *
+     * @return the parameter's string value
+     */
+    String getStringUTF8(long object, int param_name, int param_value_size) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, param_name, param_value_size, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.stringValueUTF8(0, param_value_size);
+    }
+
+    private int getString(long object, int param_name, APIBuffer __buffer) {
+        // Get string length
+        int errcode = get(object, param_name, 0, NULL, __buffer.address());
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+
+        int bytes = (int) __buffer.pointerValue(0);
+        __buffer.bufferParam(bytes);
+
+        // Get string
+        errcode = get(object, param_name, bytes, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+
+        return bytes - 1; // all OpenCL char[] parameters are null-terminated
+    }
+
+}

+ 224 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryInt.java

@@ -0,0 +1,224 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ */
+package com.jme3.opencl.lwjgl.info;
+
+import com.jme3.lwjgl3.utils.APIBuffer;
+import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer;
+import static com.jme3.opencl.lwjgl.info.CLUtil.checkCLError;
+import org.lwjgl.PointerBuffer;
+
+import static org.lwjgl.system.Checks.*;
+import static org.lwjgl.system.MemoryUtil.*;
+import static org.lwjgl.system.Pointer.*;
+
+/**
+ * Base class for OpenCL object information queries.
+ * <p/>
+ * All methods require the object being queried (a pointer value), a second
+ * integer argument and the integer parameter name.
+ *
+ * @see Info
+ */
+abstract class InfoQueryInt {
+
+    protected abstract int get(long pointer, int arg, int param_name, long param_value_size, long param_value, long param_value_size_ret);
+
+    InfoQueryInt() {
+    }
+
+    /**
+     * Returns the integer value for the specified {@code param_name}, converted
+     * to a boolean.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's boolean value
+     */
+    boolean getBoolean(long object, int arg, int param_name) {
+        return getInt(object, arg, param_name) != 0;
+    }
+
+    /**
+     * Returns the integer value for the specified {@code param_name}.
+     * <p/>
+     * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}),
+     * {@link #getPointer} should be used instead.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's int value
+     */
+    int getInt(long object, int arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, 4L, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.intValue(0);
+    }
+
+    /**
+     * Returns the long value for the specified {@code param_name}.
+     * <p/>
+     * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}),
+     * {@link #getPointer} should be used instead.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's long value
+     */
+    long getLong(long object, int arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, 8L, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.longValue(0);
+    }
+
+    /**
+     * Returns the pointer value for the specified {@code param_name}.
+     * <p/>
+     * This method should also be used for integer parameters that may be 32 or
+     * 64 bits (e.g. {@code size_t}).
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's pointer value
+     */
+    long getPointer(long object, int arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, POINTER_SIZE, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.pointerValue(0);
+    }
+
+    /**
+     * Writes the pointer list for the specified {@code param_name} into
+     * {@code target}.
+     * <p/>
+     * This method should also be used for integer parameters that may be 32 or
+     * 64 bits (e.g. {@code size_t}).
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     * @param target the buffer in which to put the returned pointer list
+     *
+     * @return how many pointers were actually returned
+     */
+    int getPointers(long object, int arg, int param_name, PointerBuffer target) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, target.remaining() * POINTER_SIZE, memAddress(target), __buffer.address());
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return (int) (__buffer.pointerValue(0) >> POINTER_SHIFT);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be ASCII encoded.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's string value
+     */
+    String getStringASCII(long object, int arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int bytes = getString(object, arg, param_name, __buffer);
+        return __buffer.stringValueASCII(0, bytes);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be ASCII encoded and have length equal to {@code
+     * param_value_size}.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     * @param param_value_size the explicit string length
+     *
+     * @return the parameter's string value
+     */
+    String getStringASCII(long object, int arg, int param_name, int param_value_size) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.stringValueASCII(0, param_value_size);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be UTF-8 encoded.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's string value
+     */
+    String getStringUTF8(long object, int arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int bytes = getString(object, arg, param_name, __buffer);
+        return __buffer.stringValueUTF8(0, bytes);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be UTF-8 encoded and have length equal to {@code
+     * param_value_size}.
+     *
+     * @param object the object to query
+     * @param arg an integer argument
+     * @param param_name the parameter to query
+     * @param param_value_size the explicit string length
+     *
+     * @return the parameter's string value
+     */
+    String getStringUTF8(long object, int arg, int param_name, int param_value_size) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.stringValueUTF8(0, param_value_size);
+    }
+
+    private int getString(long object, int arg, int param_name, APIBuffer __buffer) {
+        // Get string length
+        int errcode = get(object, arg, param_name, 0, NULL, __buffer.address());
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+
+        int bytes = (int) __buffer.pointerValue(0);
+        __buffer.bufferParam(bytes + POINTER_SIZE);
+
+        // Get string
+        errcode = get(object, arg, param_name, bytes, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+
+        return bytes - 1; // all OpenCL char[] parameters are null-terminated
+    }
+
+}

+ 224 - 0
jme3-lwjgl3/src/main/java/com/jme3/opencl/lwjgl/info/InfoQueryObject.java

@@ -0,0 +1,224 @@
+/*
+ * Copyright LWJGL. All rights reserved.
+ * License terms: http://lwjgl.org/license.php
+ */
+package com.jme3.opencl.lwjgl.info;
+
+import com.jme3.lwjgl3.utils.APIBuffer;
+import static com.jme3.lwjgl3.utils.APIUtil.apiBuffer;
+import static com.jme3.opencl.lwjgl.info.CLUtil.checkCLError;
+import org.lwjgl.PointerBuffer;
+
+import static org.lwjgl.system.Checks.*;
+import static org.lwjgl.system.MemoryUtil.*;
+import static org.lwjgl.system.Pointer.*;
+
+/**
+ * Base class for OpenCL object information queries.
+ * <p/>
+ * All methods require the object being queried (a pointer value), a second
+ * object argument (another pointer value) and the integer parameter name.
+ *
+ * @see org.lwjgl.opencl.Info
+ */
+abstract class InfoQueryObject {
+
+    protected abstract int get(long pointer, long arg, int param_name, long param_value_size, long param_value, long param_value_size_ret);
+
+    InfoQueryObject() {
+    }
+
+    /**
+     * Returns the integer value for the specified {@code param_name}, converted
+     * to a boolean.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's boolean value
+     */
+    boolean getBoolean(long object, long arg, int param_name) {
+        return getInt(object, arg, param_name) != 0;
+    }
+
+    /**
+     * Returns the integer value for the specified {@code param_name}.
+     * <p/>
+     * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}),
+     * {@link #getPointer} should be used instead.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's int value
+     */
+    int getInt(long object, long arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, 4L, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.intValue(0);
+    }
+
+    /**
+     * Returns the long value for the specified {@code param_name}.
+     * <p/>
+     * For integer parameters that may be 32 or 64 bits (e.g. {@code size_t}),
+     * {@link #getPointer} should be used instead.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's long value
+     */
+    long getLong(long object, long arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, 8L, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.longValue(0);
+    }
+
+    /**
+     * Returns the pointer value for the specified {@code param_name}.
+     * <p/>
+     * This method should also be used for integer parameters that may be 32 or
+     * 64 bits (e.g. {@code size_t}).
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's pointer value
+     */
+    long getPointer(long object, long arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, POINTER_SIZE, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.pointerValue(0);
+    }
+
+    /**
+     * Writes the pointer list for the specified {@code param_name} into
+     * {@code target}.
+     * <p/>
+     * This method should also be used for integer parameters that may be 32 or
+     * 64 bits (e.g. {@code size_t}).
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     * @param target the buffer in which to put the returned pointer list
+     *
+     * @return how many pointers were actually returned
+     */
+    int getPointers(long object, long arg, int param_name, PointerBuffer target) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, target.remaining() * POINTER_SIZE, memAddress(target), __buffer.address());
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return (int) (__buffer.pointerValue(0) >> POINTER_SHIFT);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be ASCII encoded.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's string value
+     */
+    String getStringASCII(long object, long arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int bytes = getString(object, arg, param_name, __buffer);
+        return __buffer.stringValueASCII(0, bytes);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be ASCII encoded and have length equal to {@code
+     * param_value_size}.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     * @param param_value_size the explicit string length
+     *
+     * @return the parameter's string value
+     */
+    String getStringASCII(long object, long arg, int param_name, int param_value_size) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.stringValueASCII(0, param_value_size);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be UTF-8 encoded.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     *
+     * @return the parameter's string value
+     */
+    String getStringUTF8(long object, long arg, int param_name) {
+        APIBuffer __buffer = apiBuffer();
+        int bytes = getString(object, arg, param_name, __buffer);
+        return __buffer.stringValueUTF8(0, bytes);
+    }
+
+    /**
+     * Returns the string value for the specified {@code param_name}. The raw
+     * bytes returned are assumed to be UTF-8 encoded and have length equal to {@code
+     * param_value_size}.
+     *
+     * @param object the object to query
+     * @param arg an object argument
+     * @param param_name the parameter to query
+     * @param param_value_size the explicit string length
+     *
+     * @return the parameter's string value
+     */
+    String getStringUTF8(long object, long arg, int param_name, int param_value_size) {
+        APIBuffer __buffer = apiBuffer();
+        int errcode = get(object, arg, param_name, param_value_size, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+        return __buffer.stringValueUTF8(0, param_value_size);
+    }
+
+    private int getString(long object, long arg, int param_name, APIBuffer __buffer) {
+        // Get string length
+        int errcode = get(object, arg, param_name, 0, NULL, __buffer.address());
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+
+        int bytes = (int) __buffer.pointerValue(0);
+        __buffer.bufferParam(bytes + POINTER_SIZE);
+
+        // Get string
+        errcode = get(object, arg, param_name, bytes, __buffer.address(), NULL);
+        if (DEBUG) {
+            checkCLError(errcode);
+        }
+
+        return bytes - 1; // all OpenCL char[] parameters are null-terminated
+    }
+
+}

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

@@ -50,6 +50,7 @@ import com.jme3.renderer.lwjgl.LwjglGLFboEXT;
 import com.jme3.renderer.lwjgl.LwjglGLFboGL3;
 import com.jme3.renderer.opengl.*;
 import com.jme3.system.*;
+import java.nio.IntBuffer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -105,9 +106,9 @@ public abstract class LwjglContext implements JmeContext {
 
     protected int determineMaxSamples() {
         // If we already have a valid context, determine samples using current context.
-        if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object") == GLFW_TRUE) {
+        if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object")) {
             return glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES);
-        } else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample") == GLFW_TRUE) {
+        } else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample")) {
             return glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT);
         }
 
@@ -197,7 +198,40 @@ public abstract class LwjglContext implements JmeContext {
         renderable.set(true);
         
     }
-    
+
+    /**
+     * Returns a list of the available platforms, filtered by the specified
+     * filter.
+     *
+     * Copied from the old release
+     *
+     * @param filter the platform filter
+     *
+     * @return the available platforms
+     */
+    private static long[] getPlatforms() {
+        int[] count = new int[1];
+        int errcode = CL10.clGetPlatformIDs(null, count);
+        Utils.checkError(errcode, "clGetDeviceIDs");
+
+        int num_platforms = count[0];
+        if (num_platforms == 0) {
+            return new long[0];
+        }
+
+        PointerBuffer platforms = PointerBuffer.allocateDirect(num_platforms);
+        errcode = CL10.clGetPlatformIDs(platforms, (IntBuffer) null);
+        Utils.checkError(errcode, "clGetDeviceIDs");
+
+        platforms.rewind();
+        long[] platformIDs = new long[num_platforms];
+        for (int i = 0; i < num_platforms; i++) {
+            platformIDs[i] = platforms.get();
+        }
+
+        return platformIDs;
+    }
+
     protected void initOpenCL(long window) {
         logger.info("Initialize OpenCL with LWJGL3");
         
@@ -211,7 +245,7 @@ public abstract class LwjglContext implements JmeContext {
         //load platforms and devices
         StringBuilder platformInfos = new StringBuilder();
         ArrayList<LwjglPlatform> platforms = new ArrayList<>();
-        for (CLPlatform p : CLPlatform.getPlatforms()) {
+        for (long p : getPlatforms()) {
             platforms.add(new LwjglPlatform(p));
         }
         platformInfos.append("Available OpenCL platforms:");
@@ -260,7 +294,7 @@ public abstract class LwjglContext implements JmeContext {
             chooser = new DefaultPlatformChooser();
         }
         List<? extends Device> choosenDevices = chooser.chooseDevices(platforms);
-        List<CLDevice> devices = new ArrayList<>(choosenDevices.size());
+        List<Long> devices = new ArrayList<>(choosenDevices.size());
         LwjglPlatform platform = null;
         for (Device d : choosenDevices) {
             if (!(d instanceof LwjglDevice)) {
@@ -274,7 +308,7 @@ public abstract class LwjglContext implements JmeContext {
                 logger.severe("attempt to use devices from different platforms");
                 return;
             }
-            devices.add(ld.getCLDevice());
+            devices.add(ld.getDevice());
         }
         if (devices.isEmpty()) {
             logger.warning("no devices specified, no OpenCL context created");
@@ -294,7 +328,7 @@ public abstract class LwjglContext implements JmeContext {
         
         logger.info("OpenCL context created");
     }
-    private long createContext(final CLPlatform platform, final List<CLDevice> devices, long window) throws Exception {
+    private long createContext(final long platform, final List<Long> devices, long window) throws Exception {
         
         final int propertyCount = 2 + 4 + 1;
 
@@ -330,7 +364,7 @@ public abstract class LwjglContext implements JmeContext {
 
         Utils.errorBuffer.rewind();
         PointerBuffer deviceBuffer = PointerBuffer.allocateDirect(devices.size());
-        for (CLDevice d : devices) {
+        for (long d : devices) {
             deviceBuffer.put(d);
         }
         deviceBuffer.flip();

+ 10 - 0
jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java

@@ -75,4 +75,14 @@ class LwjglGLDebugOutputHandler extends GLDebugMessageARBCallback {
 
         System.err.println(String.format(MESSAGE_FORMAT, id, sourceStr, typeStr, severityStr, message));
     }
+
+    @Override
+    public void close() {
+        super.close();
+    }
+
+    @Override
+    public void callback(long args) {
+        super.callback(args);
+    }
 }

+ 37 - 8
jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java

@@ -132,9 +132,19 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
                 final String message = GLFWErrorCallback.getDescription(description);
                 listener.handleError(message, new Exception(message));
             }
+
+            @Override
+            public void close(){
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
-        if (glfwInit() != GLFW_TRUE) {
+        if (!glfwInit()) {
             throw new IllegalStateException("Unable to initialize GLFW");
         }
 
@@ -161,7 +171,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
         glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
         glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GLFW_TRUE : GLFW_FALSE);
 
-        glfwWindowHint(GLFW_DOUBLE_BUFFER, GLFW_TRUE);
+        //glfwWindowHint(GLFW_DOUBLE_BUFFER, GLFW_TRUE);
         glfwWindowHint(GLFW_DEPTH_BITS, settings.getDepthBits());
         glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits());
         glfwWindowHint(GLFW_SAMPLES, settings.getSamples());
@@ -206,12 +216,21 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
                 settings.setResolution(width, height);
                 listener.reshape(width, height);
             }
+
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         glfwSetWindowFocusCallback(window, windowFocusCallback = new GLFWWindowFocusCallback() {
             @Override
-            public void invoke(final long window, final int focused) {
-                final boolean focus = (focused == GL_TRUE);
+            public void invoke(final long window, final boolean focus) {
                 if (wasActive != focus) {
                     if (!wasActive) {
                         listener.gainFocus();
@@ -223,6 +242,16 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
                     wasActive = !wasActive;
                 }
             }
+
+            @Override
+            public void close() {
+                super.close();
+            }
+
+            @Override
+            public void callback(long args) {
+                super.callback(args);
+            }
         });
 
         // Center the window
@@ -260,17 +289,17 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
             }
 
             if (errorCallback != null) {
-                errorCallback.release();
+                errorCallback.close();
                 errorCallback = null;
             }
 
             if (windowSizeCallback != null) {
-                windowSizeCallback.release();
+                windowSizeCallback.close();
                 windowSizeCallback = null;
             }
 
             if (windowFocusCallback != null) {
-                windowFocusCallback.release();
+                windowFocusCallback.close();
                 windowFocusCallback = null;
             }
 
@@ -460,7 +489,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
                 break;
             }
 
-            if (glfwWindowShouldClose(window) == GL_TRUE) {
+            if (glfwWindowShouldClose(window)) {
                 listener.requestClose(false);
             }
         }