refactored and upgraed lwjgl3 module.

monkanim
javasabr 7 years ago committed by Rémy Bouquet
parent 28353cf747
commit 555a348692
  1. 2
      jme3-lwjgl3/build.gradle
  2. 62
      jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglAL.java
  3. 26
      jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java
  4. 37
      jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglEFX.java
  5. 26
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwJoystickInput.java
  6. 75
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java
  7. 10
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyMap.java
  8. 194
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java
  9. 18
      jme3-lwjgl3/src/main/java/com/jme3/lwjgl3/utils/APIUtil.java
  10. 584
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
  11. 45
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java
  12. 85
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java
  13. 85
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java
  14. 25
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglRender.java
  15. 202
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
  16. 10
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglGLDebugOutputHandler.java
  17. 119
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java

@ -2,7 +2,7 @@ if (!hasProperty('mainClass')) {
ext.mainClass = ''
}
def lwjglVersion = '3.1.2'
def lwjglVersion = '3.1.5'
sourceCompatibility = '1.8'

@ -31,8 +31,6 @@
*/package com.jme3.audio.lwjgl;
import com.jme3.audio.openal.AL;
import com.jme3.system.NativeLibraryLoader;
import com.jme3.system.Platform;
import org.lwjgl.openal.AL10;
import org.lwjgl.openal.AL11;
@ -40,101 +38,123 @@ import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
/**
* The LWJGL implementation of {@link AL}.
*/
public final class LwjglAL implements AL {
public LwjglAL() {
}
public String alGetString(int parameter) {
@Override
public String alGetString(final int parameter) {
return AL10.alGetString(parameter);
}
@Override
public int alGenSources() {
return AL10.alGenSources();
}
@Override
public int alGetError() {
return AL10.alGetError();
}
public void alDeleteSources(int numSources, IntBuffer sources) {
@Override
public void alDeleteSources(final int numSources, final IntBuffer sources) {
if (sources.position() != 0) throw new AssertionError();
if (sources.limit() != numSources) throw new AssertionError();
AL10.alDeleteSources(sources);
}
public void alGenBuffers(int numBuffers, IntBuffer buffers) {
@Override
public void alGenBuffers(final int numBuffers, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numBuffers) throw new AssertionError();
AL10.alGenBuffers(buffers);
}
public void alDeleteBuffers(int numBuffers, IntBuffer buffers) {
@Override
public void alDeleteBuffers(final int numBuffers, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numBuffers) throw new AssertionError();
AL10.alDeleteBuffers(buffers);
}
public void alSourceStop(int source) {
@Override
public void alSourceStop(final int source) {
AL10.alSourceStop(source);
}
public void alSourcei(int source, int param, int value) {
@Override
public void alSourcei(final int source, final int param, final int value) {
AL10.alSourcei(source, param, value);
}
public void alBufferData(int buffer, int format, ByteBuffer data, int size, int frequency) {
@Override
public void alBufferData(final int buffer, final int format, final ByteBuffer data, final int size, final int frequency) {
if (data.position() != 0) throw new AssertionError();
if (data.limit() != size) throw new AssertionError();
AL10.alBufferData(buffer, format, data, frequency);
}
public void alSourcePlay(int source) {
@Override
public void alSourcePlay(final int source) {
AL10.alSourcePlay(source);
}
public void alSourcePause(int source) {
@Override
public void alSourcePause(final int source) {
AL10.alSourcePause(source);
}
public void alSourcef(int source, int param, float value) {
@Override
public void alSourcef(final int source, final int param, final float value) {
AL10.alSourcef(source, param, value);
}
public void alSource3f(int source, int param, float value1, float value2, float value3) {
@Override
public void alSource3f(final int source, final int param, final float value1, final float value2, final float value3) {
AL10.alSource3f(source, param, value1, value2, value3);
}
public int alGetSourcei(int source, int param) {
@Override
public int alGetSourcei(final int source, final int param) {
return AL10.alGetSourcei(source, param);
}
public void alSourceUnqueueBuffers(int source, int numBuffers, IntBuffer buffers) {
@Override
public void alSourceUnqueueBuffers(final int source, final int numBuffers, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numBuffers) throw new AssertionError();
AL10.alSourceUnqueueBuffers(source, buffers);
}
public void alSourceQueueBuffers(int source, int numBuffers, IntBuffer buffers) {
@Override
public void alSourceQueueBuffers(final int source, final int numBuffers, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numBuffers) throw new AssertionError();
AL10.alSourceQueueBuffers(source, buffers);
}
public void alListener(int param, FloatBuffer data) {
@Override
public void alListener(final int param, final FloatBuffer data) {
AL10.alListenerfv(param, data);
}
public void alListenerf(int param, float value) {
@Override
public void alListenerf(final int param, final float value) {
AL10.alListenerf(param, value);
}
public void alListener3f(int param, float value1, float value2, float value3) {
@Override
public void alListener3f(final int param, final float value1, final float value2, final float value3) {
AL10.alListener3f(param, value1, value2, value3);
}
public void alSource3i(int source, int param, int value1, int value2, int value3) {
@Override
public void alSource3i(final int source, final int param, final int value1, final int value2, final int value3) {
AL11.alSource3i(source, param, value1, value2, value3);
}
}

@ -31,19 +31,27 @@
*/
package com.jme3.audio.lwjgl;
import org.lwjgl.openal.*;
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.ALCCapabilities;
import org.lwjgl.openal.SOFTPauseDevice;
/**
* The LWJGL implementation of {@link com.jme3.audio.openal.ALC}.
*/
public class LwjglALC implements com.jme3.audio.openal.ALC {
/**
* The device id.
*/
private long device;
/**
* The context id.
*/
private long context;
@Override
public void createALC() {
device = ALC10.alcOpenDevice((ByteBuffer) null);
ALCCapabilities deviceCaps = ALC.createCapabilities(device);
@ -52,6 +60,7 @@ public class LwjglALC implements com.jme3.audio.openal.ALC {
AL.createCapabilities(deviceCaps);
}
@Override
public void destroyALC() {
if (context != 0) {
ALC10.alcDestroyContext(context);
@ -64,18 +73,22 @@ public class LwjglALC implements com.jme3.audio.openal.ALC {
}
}
@Override
public boolean isCreated() {
return context != 0;
}
@Override
public String alcGetString(final int parameter) {
return ALC10.alcGetString(device, parameter);
}
@Override
public boolean alcIsExtensionPresent(final String extension) {
return ALC10.alcIsExtensionPresent(device, extension);
}
@Override
public void alcGetInteger(final int param, final IntBuffer buffer, final int size) {
if (buffer.position() != 0) {
throw new AssertionError();
@ -86,12 +99,13 @@ public class LwjglALC implements com.jme3.audio.openal.ALC {
ALC10.alcGetIntegerv(device, param, buffer);
}
@Override
public void alcDevicePauseSOFT() {
SOFTPauseDevice.alcDevicePauseSOFT(device);
}
@Override
public void alcDeviceResumeSOFT() {
SOFTPauseDevice.alcDeviceResumeSOFT(device);
}
}

@ -36,62 +36,75 @@ import org.lwjgl.openal.EXTEfx;
import java.nio.IntBuffer;
/**
* The LWJGL implementation of {@link EFX}.
*/
public class LwjglEFX implements EFX {
public void alGenAuxiliaryEffectSlots(int numSlots, IntBuffer buffers) {
@Override
public void alGenAuxiliaryEffectSlots(final int numSlots, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numSlots) throw new AssertionError();
EXTEfx.alGenAuxiliaryEffectSlots(buffers);
}
public void alGenEffects(int numEffects, IntBuffer buffers) {
@Override
public void alGenEffects(final int numEffects, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numEffects) throw new AssertionError();
EXTEfx.alGenEffects(buffers);
}
public void alEffecti(int effect, int param, int value) {
@Override
public void alEffecti(final int effect, final int param, final int value) {
EXTEfx.alEffecti(effect, param, value);
}
public void alAuxiliaryEffectSloti(int effectSlot, int param, int value) {
@Override
public void alAuxiliaryEffectSloti(final int effectSlot, final int param, final int value) {
EXTEfx.alAuxiliaryEffectSloti(effectSlot, param, value);
}
public void alDeleteEffects(int numEffects, IntBuffer buffers) {
@Override
public void alDeleteEffects(final int numEffects, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numEffects) throw new AssertionError();
EXTEfx.alDeleteEffects(buffers);
}
public void alDeleteAuxiliaryEffectSlots(int numEffectSlots, IntBuffer buffers) {
@Override
public void alDeleteAuxiliaryEffectSlots(final int numEffectSlots, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numEffectSlots) throw new AssertionError();
EXTEfx.alDeleteAuxiliaryEffectSlots(buffers);
}
public void alGenFilters(int numFilters, IntBuffer buffers) {
@Override
public void alGenFilters(final int numFilters, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numFilters) throw new AssertionError();
EXTEfx.alGenFilters(buffers);
}
public void alFilteri(int filter, int param, int value) {
@Override
public void alFilteri(final int filter, final int param, final int value) {
EXTEfx.alFilteri(filter, param, value);
}
public void alFilterf(int filter, int param, float value) {
@Override
public void alFilterf(final int filter, final int param, final float value) {
EXTEfx.alFilterf(filter, param, value);
}
public void alDeleteFilters(int numFilters, IntBuffer buffers) {
@Override
public void alDeleteFilters(final int numFilters, final IntBuffer buffers) {
if (buffers.position() != 0) throw new AssertionError();
if (buffers.limit() != numFilters) throw new AssertionError();
EXTEfx.alDeleteFilters(buffers);
}
public void alEffectf(int effect, int param, float value) {
@Override
public void alEffectf(final int effect, final int param, final float value) {
EXTEfx.alEffectf(effect, param, value);
}
}

@ -31,10 +31,10 @@
*/
package com.jme3.input.lwjgl;
import static org.lwjgl.glfw.GLFW.*;
import com.jme3.input.*;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.input.event.JoyButtonEvent;
import org.lwjgl.opengl.GL11;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
@ -42,9 +42,9 @@ import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import static org.lwjgl.glfw.GLFW.*;
/**
* The LWJGL implementation of {@link JoyInput}.
*
* @author Daniel Johansson (dannyjo)
* @since 3.1
*/
@ -52,11 +52,13 @@ public class GlfwJoystickInput implements JoyInput {
private static final Logger LOGGER = Logger.getLogger(InputManager.class.getName());
private boolean initialized = false;
private RawInputListener listener;
private Map<Integer, GlfwJoystick> joysticks = new HashMap<Integer, GlfwJoystick>();
private Map<Integer, GlfwJoystick> joysticks = new HashMap<>();
private boolean initialized = false;
public void setJoyRumble(int joyId, float amount) {
@Override
public void setJoyRumble(final int joyId, final float amount) {
if (joyId >= joysticks.size()) {
throw new IllegalArgumentException();
}
@ -111,10 +113,12 @@ public class GlfwJoystickInput implements JoyInput {
return String.valueOf(index);
}
@Override
public void initialize() {
initialized = true;
}
@Override
public void update() {
for (final Map.Entry<Integer, GlfwJoystick> entry : joysticks.entrySet()) {
// Axes
@ -135,18 +139,22 @@ public class GlfwJoystickInput implements JoyInput {
}
}
@Override
public void destroy() {
initialized = false;
}
@Override
public boolean isInitialized() {
return initialized;
}
public void setInputListener(RawInputListener listener) {
@Override
public void setInputListener(final RawInputListener listener) {
this.listener = listener;
}
@Override
public long getInputTimeNanos() {
return 0;
}
@ -156,7 +164,7 @@ public class GlfwJoystickInput implements JoyInput {
private JoystickAxis povAxisX;
private JoystickAxis povAxisY;
public GlfwJoystick(InputManager inputManager, JoyInput joyInput, int joyId, String name) {
public GlfwJoystick(final InputManager inputManager, final JoyInput joyInput, final int joyId, final String name) {
super(inputManager, joyInput, joyId, name);
}
@ -171,7 +179,7 @@ public class GlfwJoystickInput implements JoyInput {
}
@Override
protected void addButton(JoystickButton button) {
protected void addButton(final JoystickButton button) {
super.addButton(button);
}

@ -32,11 +32,11 @@
package com.jme3.input.lwjgl;
import static org.lwjgl.glfw.GLFW.*;
import com.jme3.input.KeyInput;
import com.jme3.input.RawInputListener;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.system.lwjgl.LwjglWindow;
import org.lwjgl.glfw.GLFWCharCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
@ -44,37 +44,54 @@ import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Logger;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_LAST;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_SPACE;
import static org.lwjgl.glfw.GLFW.GLFW_PRESS;
import static org.lwjgl.glfw.GLFW.GLFW_REPEAT;
import static org.lwjgl.glfw.GLFW.glfwGetTime;
import static org.lwjgl.glfw.GLFW.glfwSetCharCallback;
import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback;
/**
* The LWJGL implementation of {@link KeyInput}.
*/
public class GlfwKeyInput implements KeyInput {
private static final Logger logger = Logger.getLogger(GlfwKeyInput.class.getName());
/**
* The queue of key events.
*/
private final Queue<KeyInputEvent> keyInputEvents = new LinkedList<>();
/**
* The LWJGL context.
*/
private LwjglWindow context;
private RawInputListener listener;
private boolean initialized;
/**
* The key callback.
*/
private GLFWKeyCallback keyCallback;
/**
* The char callback.
*/
private GLFWCharCallback charCallback;
private Queue<KeyInputEvent> keyInputEvents = new LinkedList<KeyInputEvent>();
public GlfwKeyInput(LwjglWindow context) {
/**
* The raw input listener.
*/
private RawInputListener listener;
private boolean initialized;
public GlfwKeyInput(final LwjglWindow context) {
this.context = context;
}
@Override
public void initialize() {
if (!context.isRenderable()) {
return;
}
glfwSetKeyCallback(context.getWindowHandle(), keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
public void invoke(final long window, final int key, final int scancode, final int action, final int mods) {
if (key < 0 || key > GLFW_KEY_LAST) {
return;
@ -87,22 +104,11 @@ 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() {
@Override
public void invoke(long window, int codepoint) {
public void invoke(final long window, final int codepoint) {
final char keyChar = (char) codepoint;
@ -116,16 +122,6 @@ 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;
@ -137,6 +133,7 @@ public class GlfwKeyInput implements KeyInput {
return GLFW_KEY_LAST - GLFW_KEY_SPACE;
}
@Override
public void update() {
if (!context.isRenderable()) {
return;
@ -147,6 +144,7 @@ public class GlfwKeyInput implements KeyInput {
}
}
@Override
public void destroy() {
if (!context.isRenderable()) {
return;
@ -157,14 +155,17 @@ public class GlfwKeyInput implements KeyInput {
logger.fine("Keyboard destroyed.");
}
@Override
public boolean isInitialized() {
return initialized;
}
public void setInputListener(RawInputListener listener) {
@Override
public void setInputListener(final RawInputListener listener) {
this.listener = listener;
}
@Override
public long getInputTimeNanos() {
return (long) (glfwGetTime() * 1000000000);
}

@ -36,10 +36,10 @@ import static com.jme3.input.KeyInput.*;
public class GlfwKeyMap {
private static final int[] glfwToJmeKeyMap = new int[GLFW_KEY_LAST + 1];
private static final int[] GLFW_TO_JME_KEY_MAP = new int[GLFW_KEY_LAST + 1];
private static void reg(int jmeKey, int glfwKey) {
glfwToJmeKeyMap[glfwKey] = jmeKey;
private static void reg(final int jmeKey, final int glfwKey) {
GLFW_TO_JME_KEY_MAP[glfwKey] = jmeKey;
}
static {
@ -165,7 +165,7 @@ public class GlfwKeyMap {
reg(KEY_RMETA, GLFW_KEY_RIGHT_SUPER);
}
public static int toJmeKeyCode(int glfwKey) {
return glfwToJmeKeyMap[glfwKey];
public static int toJmeKeyCode(final int glfwKey) {
return GLFW_TO_JME_KEY_MAP[glfwKey];
}
}

@ -31,6 +31,7 @@
*/
package com.jme3.input.lwjgl;
import static org.lwjgl.glfw.GLFW.*;
import com.jme3.cursors.plugins.JmeCursor;
import com.jme3.input.MouseInput;
import com.jme3.input.RawInputListener;
@ -38,19 +39,17 @@ import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.system.lwjgl.LwjglWindow;
import com.jme3.util.BufferUtils;
import org.lwjgl.glfw.*;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.logging.Logger;
import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFWCursorPosCallback;
import org.lwjgl.glfw.GLFWImage;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import org.lwjgl.glfw.GLFWScrollCallback;
import org.lwjgl.system.MemoryUtil;
/**
* Captures mouse input using GLFW callbacks. It then temporarily stores these
@ -68,34 +67,86 @@ public class GlfwMouseInput implements MouseInput {
private static final int WHEEL_SCALE = 120;
private static long[] createGlfwCursor(final JmeCursor jmeCursor) {
long[] cursorArray = new long[jmeCursor.getNumImages()];
for (int i = 0; i < jmeCursor.getNumImages(); i++) {
final ByteBuffer buffer = transformCursorImage(jmeCursor.getImagesData(), jmeCursor.getWidth(), jmeCursor.getHeight(), i);
final GLFWImage glfwImage = new GLFWImage(BufferUtils.createByteBuffer(GLFWImage.SIZEOF));
glfwImage.set(jmeCursor.getWidth(), jmeCursor.getHeight(), buffer);
final int hotspotX = jmeCursor.getXHotSpot();
final int hotspotY = jmeCursor.getHeight() - jmeCursor.getYHotSpot();
cursorArray[i] = glfwCreateCursor(glfwImage, hotspotX, hotspotY);
}
return cursorArray;
}
private static ByteBuffer transformCursorImage(final IntBuffer imageData, final int width, final int height,
final int index) {
final ByteBuffer byteBuffer = BufferUtils.createByteBuffer(width * height * 4);
// Transform image: ARGB -> RGBA, vertical flip
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) {
int pixel = imageData.get(width * height * index + y * width + x);
byteBuffer.put((byte) ((pixel >> 16) & 0xFF)); // red
byteBuffer.put((byte) ((pixel >> 8) & 0xFF)); // green
byteBuffer.put((byte) (pixel & 0xFF)); // blue
byteBuffer.put((byte) ((pixel >> 24) & 0xFF)); // alpha
}
}
byteBuffer.flip();
return byteBuffer;
}
private final Map<JmeCursor, long[]> jmeToGlfwCursorMap = new HashMap<>();
private final Queue<MouseMotionEvent> mouseMotionEvents = new LinkedList<>();
private final Queue<MouseButtonEvent> mouseButtonEvents = new LinkedList<>();
private final LwjglWindow context;
private RawInputListener listener;
private boolean cursorVisible = true;
private long[] currentCursor;
private IntBuffer currentCursorDelays;
private int currentCursorFrame = 0;
private GLFWCursorPosCallback cursorPosCallback;
private GLFWScrollCallback scrollCallback;
private GLFWMouseButtonCallback mouseButtonCallback;
private long[] currentCursor;
private double currentCursorFrameStartTime = 0.0;
private int currentCursorFrame = 0;
private int mouseX;
private int mouseY;
private int mouseWheel;
private boolean initialized;
private GLFWCursorPosCallback cursorPosCallback;
private GLFWScrollCallback scrollCallback;
private GLFWMouseButtonCallback mouseButtonCallback;
private final Queue<MouseMotionEvent> mouseMotionEvents = new ArrayDeque<>();
private final Queue<MouseButtonEvent> mouseButtonEvents = new ArrayDeque<>();
private int currentWidth;
private int currentHeight;
private final Map<JmeCursor, long[]> jmeToGlfwCursorMap = new HashMap<>();
private boolean cursorVisible;
private boolean initialized;
public GlfwMouseInput(LwjglWindow context) {
public GlfwMouseInput(final LwjglWindow context) {
this.context = context;
this.cursorVisible = true;
}
private void onCursorPos(long window, double xpos, double ypos) {
private void onCursorPos(final long window, final double xpos, final double ypos) {
int xDelta;
int yDelta;
int x = (int) Math.round(xpos);
int y = context.getSettings().getHeight() - (int) Math.round(ypos);
int y = currentHeight - (int) Math.round(ypos);
if (mouseX == 0) {
mouseX = x;
@ -117,7 +168,7 @@ public class GlfwMouseInput implements MouseInput {
}
}
private void onWheelScroll(long window, double xOffset, double yOffset) {
private void onWheelScroll(final long window, final double xOffset, final double yOffset) {
mouseWheel += yOffset;
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(mouseX, mouseY, 0, 0, mouseWheel, (int) Math.round(yOffset));
mouseMotionEvent.setTime(getInputTimeNanos());
@ -125,61 +176,54 @@ public class GlfwMouseInput implements MouseInput {
}
private void onMouseButton(final long window, final int button, final int action, final int mods) {
final MouseButtonEvent mouseButtonEvent = new MouseButtonEvent(convertButton(button), action == GLFW_PRESS, mouseX, mouseY);
final boolean pressed = action == GLFW_PRESS;
final MouseButtonEvent mouseButtonEvent = new MouseButtonEvent(convertButton(button), pressed, mouseX, mouseY);
mouseButtonEvent.setTime(getInputTimeNanos());
mouseButtonEvents.add(mouseButtonEvent);
}
@Override
public void initialize() {
glfwSetCursorPosCallback(context.getWindowHandle(), cursorPosCallback = new GLFWCursorPosCallback() {
@Override
public void invoke(long window, double xpos, double ypos) {
onCursorPos(window, xpos, ypos);
}
@Override
public void close() {
super.close();
final long window = context.getWindowHandle();
try (MemoryStack stack = MemoryStack.stackPush()) {
final IntBuffer width = stack.callocInt(1);
final IntBuffer height = stack.callocInt(1);
glfwGetWindowSize(window, width, height);
currentWidth = width.get();
currentHeight = height.get();
}
glfwSetCursorPosCallback(window, cursorPosCallback = new GLFWCursorPosCallback() {
@Override
public void callback(long args) {
super.callback(args);
public void invoke(final long window, final double xpos, final double ypos) {
onCursorPos(window, xpos, ypos);
}
});
glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() {
glfwSetScrollCallback(window, scrollCallback = new GLFWScrollCallback() {
@Override
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() {
glfwSetMouseButtonCallback(window, mouseButtonCallback = new GLFWMouseButtonCallback() {
@Override
public void invoke(final long window, final int button, final int action, final int mods) {
onMouseButton(window, button, action, mods);
}
});
glfwSetWindowSizeCallback(window, new GLFWWindowSizeCallback() {
@Override
public void close() {
super.close();
}
@Override
public void callback(long args) {
super.callback(args);
public void invoke(final long window, final int width, final int height) {
currentHeight = height;
currentWidth = width;
}
});
@ -224,6 +268,7 @@ public class GlfwMouseInput implements MouseInput {
@Override
public void destroy() {
if (!context.isRenderable()) {
return;
}
@ -234,11 +279,13 @@ public class GlfwMouseInput implements MouseInput {
currentCursor = null;
currentCursorDelays = null;
for (long[] glfwCursors : jmeToGlfwCursorMap.values()) {
for (long glfwCursor : glfwCursors) {
glfwDestroyCursor(glfwCursor);
}
}
jmeToGlfwCursorMap.clear();
logger.fine("Mouse destroyed.");
@ -269,58 +316,23 @@ public class GlfwMouseInput implements MouseInput {
return (long) (glfwGetTime() * 1000000000);
}
private ByteBuffer transformCursorImage(IntBuffer imageData, int w, int h, int index) {
ByteBuffer buf = BufferUtils.createByteBuffer(w * h * 4);
// Transform image: ARGB -> RGBA, vertical flip
for (int y = h - 1; y >= 0; --y) {
for (int x = 0; x < w; ++x) {
int pixel = imageData.get(w * h * index + y * w + x);
buf.put((byte) ((pixel >> 16) & 0xFF)); // red
buf.put((byte) ((pixel >> 8) & 0xFF)); // green
buf.put((byte) (pixel & 0xFF)); // blue
buf.put((byte) ((pixel >> 24) & 0xFF)); // alpha
}
}
buf.flip();
return buf;
}
private long[] createGlfwCursor(JmeCursor jmeCursor) {
long[] cursorArray = new long[jmeCursor.getNumImages()];
for (int i = 0; i < jmeCursor.getNumImages(); i++) {
ByteBuffer buf = transformCursorImage(jmeCursor.getImagesData(), jmeCursor.getWidth(), jmeCursor.getHeight(), i);
GLFWImage glfwImage = new GLFWImage(BufferUtils.createByteBuffer(GLFWImage.SIZEOF));
glfwImage.set(jmeCursor.getWidth(), jmeCursor.getHeight(), buf);
int hotspotX = jmeCursor.getXHotSpot();
int hotspotY = jmeCursor.getHeight() - jmeCursor.getYHotSpot();
cursorArray[i] = glfwCreateCursor(glfwImage, hotspotX, hotspotY);
}
return cursorArray;
}
@Override
public void setNativeCursor(JmeCursor jmeCursor) {
public void setNativeCursor(final JmeCursor jmeCursor) {
if (jmeCursor != null) {
long[] glfwCursor = jmeToGlfwCursorMap.get(jmeCursor);
if (glfwCursor == null) {
glfwCursor = createGlfwCursor(jmeCursor);
jmeToGlfwCursorMap.put(jmeCursor, glfwCursor);
}
final long[] glfwCursor = jmeToGlfwCursorMap.computeIfAbsent(jmeCursor, GlfwMouseInput::createGlfwCursor);
currentCursorFrame = 0;
currentCursor = glfwCursor;
currentCursorDelays = null;
currentCursorFrameStartTime = glfwGetTime();
if (jmeCursor.getImagesDelay() != null) {
currentCursorDelays = jmeCursor.getImagesDelay();
}
glfwSetCursor(context.getWindowHandle(), glfwCursor[currentCursorFrame]);
} else {
currentCursor = null;
currentCursorDelays = null;

@ -20,16 +20,22 @@ import java.util.regex.Pattern;
*/
public final class APIUtil {
private static final ThreadLocal<APIBuffer> API_BUFFERS = new ThreadLocal<APIBuffer>() {
@Override
protected APIBuffer initialValue() {
return new APIBuffer();
}
};
private static final ThreadLocal<APIBuffer> API_BUFFERS = ThreadLocal.withInitial(APIBuffer::new);
private APIUtil() {
}
/**
* Converts dynamic arguments to object array.
*
* @param arguments the list of arguments.
* @return the object array.
*/
@SafeVarargs
public static <T> T[] toArray(T... arguments) {
return arguments;
}
/**
* Returns a thread-local {@link APIBuffer} that has been reset.
*/

@ -31,449 +31,553 @@
*/
package com.jme3.renderer.lwjgl;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.opengl.GL;
import com.jme3.renderer.opengl.GL2;
import com.jme3.renderer.opengl.GL3;
import com.jme3.renderer.opengl.GL4;
import org.lwjgl.opengl.*;
import java.nio.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
public class LwjglGL implements GL, GL2, GL3, GL4 {
private static void checkLimit(Buffer buffer) {
if (buffer == null) {
return;
}
if (buffer.limit() == 0) {
throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
}
if (buffer.remaining() == 0) {
throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
}
}
/**
* The LWJGL implementation of interfaces {@link GL}, {@link GL2}, {@link GL3}, {@link GL4}.
*/
public class LwjglGL extends LwjglRender implements GL, GL2, GL3, GL4 {
@Override
public void resetStats() {
}
public void glActiveTexture(int param1) {
GL13.glActiveTexture(param1);
@Override
public void glActiveTexture(final int texture) {
GL13.glActiveTexture(texture);
}
public void glAlphaFunc(int param1, float param2) {
GL11.glAlphaFunc(param1, param2);
@Override
public void glAlphaFunc(final int func, final float ref) {
GL11.glAlphaFunc(func, ref);
}
public void glAttachShader(int param1, int param2) {
GL20.glAttachShader(param1, param2);
@Override
public void glAttachShader(final int program, final int shader) {
GL20.glAttachShader(program, shader);
}
@Override
public void glBeginQuery(int target, int query) {
public void glBeginQuery(final int target, final int query) {
GL15.glBeginQuery(target, query);
}
public void glBindBuffer(int param1, int param2) {
GL15.glBindBuffer(param1, param2);
@Override
public void glBindBuffer(final int target, final int buffer) {
GL15.glBindBuffer(target, buffer);
}
public void glBindTexture(int param1, int param2) {
GL11.glBindTexture(param1, param2);
@Override
public void glBindTexture(final int target, final int texture) {
GL11.glBindTexture(target, texture);
}
public void glBlendEquationSeparate(int colorMode, int alphaMode){
GL20.glBlendEquationSeparate(colorMode,alphaMode);
@Override
public void glBlendEquationSeparate(final int colorMode, final int alphaMode) {
GL20.glBlendEquationSeparate(colorMode, alphaMode);
}
public void glBlendFunc(int param1, int param2) {
GL11.glBlendFunc(param1, param2);
@Override
public void glBlendFunc(final int sfactor, final int dfactor) {
GL11.glBlendFunc(sfactor, dfactor);
}
public void glBlendFuncSeparate(int param1, int param2, int param3, int param4) {
GL14.glBlendFuncSeparate(param1, param2, param3, param4);
@Override
public void glBlendFuncSeparate(final int sfactorRGB, final int dfactorRGB, final int sfactorAlpha,
final int dfactorAlpha) {
GL14.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}
public void glBufferData(int param1, long param2, int param3) {
GL15.glBufferData(param1, param2, param3);
@Override
public void glBufferData(final int target, final long dataSize, final int usage) {
GL15.glBufferData(target, dataSize, usage);
}
public void glBufferData(int param1, FloatBuffer param2, int param3) {
checkLimit(param2);
GL15.glBufferData(param1, param2, param3);
@Override
public void glBufferData(final int target, final FloatBuffer data, final int usage) {
checkLimit(data);
GL15.glBufferData(target, data, usage);
}
public void glBufferData(int param1, ShortBuffer param2, int param3) {
checkLimit(param2);
GL15.glBufferData(param1, param2, param3);
@Override
public void glBufferData(final int target, final ShortBuffer data, final int usage) {
checkLimit(data);
GL15.glBufferData(target, data, usage);
}
public void glBufferData(int param1, ByteBuffer param2, int param3) {
checkLimit(param2);
GL15.glBufferData(param1, param2, param3);
@Override
public void glBufferData(final int target, final ByteBuffer data, final int usage) {
checkLimit(data);
GL15.glBufferData(target, data, usage);
}
public void glBufferSubData(int param1, long param2, FloatBuffer param3) {
checkLimit(param3);
GL15.glBufferSubData(param1, param2, param3);
@Override
public void glBufferSubData(final int target, final long offset, final FloatBuffer data) {
checkLimit(data);
GL15.glBufferSubData(target, offset, data);
}
public void glBufferSubData(int param1, long param2, ShortBuffer param3) {
checkLimit(param3);
GL15.glBufferSubData(param1, param2, param3);
@Override
public void glBufferSubData(final int target, final long offset, final ShortBuffer data) {
checkLimit(data);
GL15.glBufferSubData(target, offset, data);
}
public void glBufferSubData(int param1, long param2, ByteBuffer param3) {
checkLimit(param3);
GL15.glBufferSubData(param1, param2, param3);
@Override
public void glBufferSubData(final int target, final long offset, final ByteBuffer data) {
checkLimit(data);
GL15.glBufferSubData(target, offset, data);
}
public void glClear(int param1) {
GL11.glClear(param1);
@Override
public void glClear(final int mask) {
GL11.glClear(mask);
}
public void glClearColor(float param1, float param2, float param3, float param4) {
GL11.glClearColor(param1, param2, param3, param4);
@Override
public void glClearColor(final float red, final float green, final float blue, final float alpha) {
GL11.glClearColor(red, green, blue, alpha);
}
public void glColorMask(boolean param1, boolean param2, boolean param3, boolean param4) {
GL11.glColorMask(param1, param2, param3, param4);
@Override
public void glColorMask(final boolean red, final boolean green, final boolean blue, final boolean alpha) {
GL11.glColorMask(red, green, blue, alpha);
}
public void glCompileShader(int param1) {
GL20.glCompileShader(param1);
@Override
public void glCompileShader(final int shader) {
GL20.glCompileShader(shader);
}
public void glCompressedTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) {
checkLimit(param7);
GL13.glCompressedTexImage2D(param1, param2, param3, param4, param5, param6, param7);
@Override
public void glCompressedTexImage2D(final int target, final int level, final int internalFormat, final int width,
final int height, final int border, final ByteBuffer data) {
checkLimit(data);
GL13.glCompressedTexImage2D(target, level, internalFormat, width, height, border, data);
}
public void glCompressedTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) {
checkLimit(param8);
GL13.glCompressedTexImage3D(param1, param2, param3, param4, param5, param6, param7, param8);
@Override
public void glCompressedTexImage3D(final int target, final int level, final int internalFormat, final int width,
final int height, final int depth, final int border, final ByteBuffer data) {
checkLimit(data);
GL13.glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, data);
}
public void glCompressedTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) {
checkLimit(param8);
GL13.glCompressedTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, param8);
@Override
public void glCompressedTexSubImage2D(final int target, final int level, final int xoffset, final int yoffset,
final int width, final int height, final int format, final ByteBuffer data) {
checkLimit(data);
GL13.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data);
}
public void glCompressedTexSubImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, ByteBuffer param10) {
checkLimit(param10);
GL13.glCompressedTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
@Override
public void glCompressedTexSubImage3D(final int target, final int level, final int xoffset, final int yoffset,
final int zoffset, final int width, final int height, final int depth,
final int format, final ByteBuffer data) {
checkLimit(data);
GL13.glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, data);
}
@Override
public int glCreateProgram() {
return GL20.glCreateProgram();
}
public int glCreateShader(int param1) {
return GL20.glCreateShader(param1);
@Override
public int glCreateShader(final int shaderType) {
return GL20.glCreateShader(shaderType);
}
public void glCullFace(int param1) {
GL11.glCullFace(param1);
@Override
public void glCullFace(final int mode) {
GL11.glCullFace(mode);
}
public void glDeleteBuffers(IntBuffer param1) {
checkLimit(param1);
GL15.glDeleteBuffers(param1);
@Override
public void glDeleteBuffers(final IntBuffer buffers) {
checkLimit(buffers);
GL15.glDeleteBuffers(buffers);
}
public void glDeleteProgram(int param1) {
GL20.glDeleteProgram(param1);
@Override
public void glDeleteProgram(final int program) {
GL20.glDeleteProgram(program);
}
public void glDeleteShader(int param1) {
GL20.glDeleteShader(param1);
@Override
public void glDeleteShader(final int shader) {
GL20.glDeleteShader(shader);
}
public void glDeleteTextures(IntBuffer param1) {
checkLimit(param1);
GL11.glDeleteTextures(param1);
@Override
public void glDeleteTextures(final IntBuffer textures) {
checkLimit(textures);
GL11.glDeleteTextures(textures);
}
public void glDepthFunc(int param1) {
GL11.glDepthFunc(param1);
@Override
public void glDepthFunc(final int func) {
GL11.glDepthFunc(func);
}
public void glDepthMask(boolean param1) {
GL11.glDepthMask(param1);
@Override
public void glDepthMask(final boolean flag) {
GL11.glDepthMask(flag);
}
public void glDepthRange(double param1, double param2) {
GL11.glDepthRange(param1, param2);
@Override
public void glDepthRange(final double nearVal, final double farVal) {
GL11.glDepthRange(nearVal, farVal);
}
public void glDetachShader(int param1, int param2) {
GL20.glDetachShader(param1, param2);
@Override
public void glDetachShader(final int program, final int shader) {
GL20.glDetachShader(program, shader);
}
public void glDisable(int param1) {
GL11.glDisable(param1);
@Override
public void glDisable(final int cap) {
GL11.glDisable(cap);
}
public void glDisableVertexAttribArray(int param1) {
GL20.glDisableVertexAttribArray(param1);
@Override
public void glDisableVertexAttribArray(final int index) {
GL20.glDisableVertexAttribArray(index);
}
public void glDrawArrays(int param1, int param2, int param3) {
GL11.glDrawArrays(param1, param2, param3);
@Override
public void glDrawArrays(final int mode, final int first, final int count) {
GL11.glDrawArrays(mode, first, count);
}
public void glDrawBuffer(int param1) {
GL11.glDrawBuffer(param1);
@Override
public void glDrawBuffer(final int mode) {
GL11.glDrawBuffer(mode);
}
public void glDrawRangeElements(int param1, int param2, int param3, int param4, int param5, long param6) {
GL12.glDrawRangeElements(param1, param2, param3, param4, param5, param6);
@Override
public void glDrawRangeElements(final int mode, final int start, final int end, final int count, final int type,
final long indices) {
GL12.glDrawRangeElements(mode, start, end, count, type, indices);
}
public void glEnable(int param1) {
GL11.glEnable(param1);
@Override
public void glEnable(final int cap) {
GL11.glEnable(cap);
}
public void glEnableVertexAttribArray(int param1) {
GL20.glEnableVertexAttribArray(param1);
@Override
public void glEnableVertexAttribArray(final int index) {
GL20.glEnableVertexAttribArray(index);
}
@Override
public void glEndQuery(int target) {
public void glEndQuery(final int target) {
GL15.glEndQuery(target);
}
public void glGenBuffers(IntBuffer param1) {
checkLimit(param1);
GL15.glGenBuffers(param1);
@Override
public void glGenBuffers(final IntBuffer buffers) {
checkLimit(buffers);
GL15.glGenBuffers(buffers);
}
public void glGenTextures(IntBuffer param1) {
checkLimit(param1);
GL11.glGenTextures(param1);
@Override
public void glGenTextures(final IntBuffer textures) {
checkLimit(textures);
GL11.glGenTextures(textures);
}
@Override
public void glGenQueries(int num, IntBuffer ids) {
public void glGenQueries(final int num, final IntBuffer ids) {
GL15.glGenQueries(ids);
}
public void glGetBoolean(int param1, ByteBuffer param2) {
checkLimit(param2);
GL11.glGetBooleanv(param1, param2);
@Override
public void glGetBoolean(final int pname, final ByteBuffer params) {
checkLimit(params);
GL11.glGetBooleanv(pname, params);
}
public void glGetBufferSubData(int target, long offset, ByteBuffer data) {
@Override
public void glGetBufferSubData(final int target, final long offset, final ByteBuffer data) {
checkLimit(data);
GL15.glGetBufferSubData(target, offset, data);
}
@Override
public int glGetError() {
return GL11.glGetError();
}
public void glGetInteger(int param1, IntBuffer param2) {
checkLimit(param2);
GL11.glGetIntegerv(param1, param2);
@Override
public void glGetInteger(final int pname, final IntBuffer params) {
checkLimit(params);
GL11.glGetIntegerv(pname, params);
}
public void glGetProgram(int param1, int param2, IntBuffer param3) {
checkLimit(param3);
GL20.glGetProgramiv(param1, param2, param3);
@Override
public void glGetProgram(final int program, final int pname, final IntBuffer params) {
checkLimit(params);
GL20.glGetProgramiv(program, pname, params);
}
public void glGetShader(int param1, int param2, IntBuffer param3) {
checkLimit(param3);
GL20.glGetShaderiv(param1, param2, param3);
@Override
public void glGetShader(final int shader, final int pname, final IntBuffer params) {
checkLimit(params);
GL20.glGetShaderiv(shader, pname, params);
}
public String glGetString(int param1) {
return GL11.glGetString(param1);
@Override
public String glGetString(final int name) {
return GL11.glGetString(name);
}
public String glGetString(int param1, int param2) {
return GL30.glGetStringi(param1, param2);
@Override
public String glGetString(final int name, final int index) {
return GL30.glGetStringi(name, index);
}
public boolean glIsEnabled(int param1) {
return GL11.glIsEnabled(param1);
@Override
public boolean glIsEnabled(final int cap) {
return GL11.glIsEnabled(cap);
}
public void glLineWidth(float param1) {
GL11.glLineWidth(param1);
@Override
public void glLineWidth(final float width) {
GL11.glLineWidth(width);
}
public void glLinkProgram(int param1) {
GL20.glLinkProgram(param1);
@Override
public void glLinkProgram(final int program) {
GL20.glLinkProgram(program);
}
public void glPixelStorei(int param1, int param2) {
GL11.glPixelStorei(param1, param2);
@Override
public void glPixelStorei(final int pname, final int param) {
GL11.glPixelStorei(pname, param);
}
public void glPointSize(float param1) {
GL11.glPointSize(param1);
@Override
public void glPointSize(final float size) {
GL11.glPointSize(size);
}
public void glPolygonMode(int param1, int param2) {
GL11.glPolygonMode(param1, param2);
@Override
public void glPolygonMode(final int face, final int mode) {
GL11.glPolygonMode(face, mode);
}
public void glPolygonOffset(float param1, float param2) {
GL11.glPolygonOffset(param1, param2);
@Override
public void glPolygonOffset(final float factor, final float units) {
GL11.glPolygonOffset(factor, units);
}
public void glReadBuffer(int param1) {
GL11.glReadBuffer(param1);
@Override
public void glReadBuffer(final int mode) {
GL11.glReadBuffer(mode);
}
public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) {
checkLimit(param7);
GL11.glReadPixels(param1, param2, param3, param4, param5, param6, param7);
@Override
public void glReadPixels(final int x, final int y, final int width, final int height, final int format,
final int type, final ByteBuffer data) {
checkLimit(data);
GL11.glReadPixels(x, y, width, height, format, type, data);
}
public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, long param7) {
GL11.glReadPixels(param1, param2, param3, param4, param5, param6, param7);
@Override
public void glReadPixels(final int x, final int y, final int width, final int height, final int format,
final int type, final long offset) {
GL11.glReadPixels(x, y, width, height, format, type, offset);
}
public void glScissor(int param1, int param2, int param3, int param4) {
GL11.glScissor(param1, param2, param3, param4);
@Override
public void glScissor(final int x, final int y, final int width, final int height) {
GL11.glScissor(x, y, width, height);
}
public void glStencilFuncSeparate(int param1, int param2, int param3, int param4) {
GL20.glStencilFuncSeparate(param1, param2, param3, param4);
@Override
public void glStencilFuncSeparate(final int face, final int func, final int ref, final int mask) {
GL20.glStencilFuncSeparate(face, func, ref, mask);
}
public void glStencilOpSeparate(int param1, int param2, int param3, int param4) {
GL20.glStencilOpSeparate(param1, param2, param3, param4);
@Override
public void glStencilOpSeparate(final int face, final int sfail, final int dpfail, final int dppass) {
GL20.glStencilOpSeparate(face, sfail, dpfail, dppass);
}
public void glTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) {
checkLimit(param9);
GL11.glTexImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9);
@Override
public void glTexImage2D(final int target, final int level, final int internalFormat, final int width,
final int height, final int border, final int format, final int type,
final ByteBuffer data) {
checkLimit(data);
GL11.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
}
public void glTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, ByteBuffer param10) {
checkLimit(param10);
GL12.glTexImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
@Override
public void glTexImage3D(final int target, final int level, final int internalFormat, final int width,
final int height, final int depth, final int border, final int format, final int type,
final ByteBuffer data) {
checkLimit(data);
GL12.glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
}
public void glTexParameterf(int param1, int param2, float param3) {
GL11.glTexParameterf(param1, param2, param3);
@Override
public void glTexParameterf(final int target, final int pname, final float param) {
GL11.glTexParameterf(target, pname, param);
}
public void glTexParameteri(int param1, int param2, int param3) {
GL11.glTexParameteri(param1, param2, param3);
@Override
public void glTexParameteri(final int target, final int pname, final int param) {
GL11.glTexParameteri(target, pname, param);
}
public void glTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) {
checkLimit(param9);
GL11.glTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9);
@Override
public void glTexSubImage2D(final int target, final int level, final int xoffset, final int yoffset,
final int width, final int height, final int format, final int type,
final ByteBuffer data) {
checkLimit(data);
GL11.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
}
public void glTexSubImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10, ByteBuffer param11) {
checkLimit(param11);
GL12.glTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11);
@Override
public void glTexSubImage3D(final int target, final int level, final int xoffset, final int yoffset,
final int zoffset, final int width, final int height, final int depth, final int format,
final int type, final ByteBuffer data) {
checkLimit(data);
GL12.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
}
public void glUniform1(int param1, FloatBuffer param2) {
checkLimit(param2);
GL20.glUniform1fv(param1, param2);
@Override
public void glUniform1(final int location, final FloatBuffer value) {
checkLimit(value);
GL20.glUniform1fv(location, value);
}
public void glUniform1(int param1, IntBuffer param2) {
checkLimit(param2);
GL20.glUniform1iv(param1, param2);
@Override
public void glUniform1(final int location, final IntBuffer value) {
checkLimit(value);
GL20.glUniform1iv(location, value);
}
public void glUniform1f(int param1, float param2) {
GL20.glUniform1f(param1, param2);
@Override
public void glUniform1f(final int location, final float v0) {
GL20.glUniform1f(location, v0);
}
public void glUniform1i(int param1, int param2) {
GL20.glUniform1i(param1, param2);
@Override
public void glUniform1i(final int location, final int v0) {
GL20.glUniform1i(location, v0);
}
public void glUniform2(int param1, IntBuffer param2) {
checkLimit(param2);
GL20.glUniform2iv(param1, param2);
@Override
public void glUniform2(final int location, final IntBuffer value) {
checkLimit(value);
GL20.glUniform2iv(location, value);
}
public void glUniform2(int param1, FloatBuffer param2) {
checkLimit(param2);
GL20.glUniform2fv(param1, param2);
@Override
public void glUniform2(final int location, final FloatBuffer value) {
checkLimit(value);
GL20.glUniform2fv(location, value);
}
public void glUniform2f(int param1, float param2, float param3) {
GL20.glUniform2f(param1, param2, param3);
@Override
public void glUniform2f(final int location, final float v0, final float v1) {
GL20.glUniform2f(location, v0, v1);
}
public void glUniform3(int param1, IntBuffer param2) {
checkLimit(param2);
GL20.glUniform3iv(param1, param2);
@Override
public void glUniform3(final int location, final IntBuffer value) {
checkLimit(value);
GL20.glUniform3iv(location, value);
}
public void glUniform3(int param1, FloatBuffer param2) {
checkLimit(param2);
GL20.glUniform3fv(param1, param2);
@Override
public void glUniform3(final int location, final FloatBuffer value) {
checkLimit(value);
GL20.glUniform3fv(location, value);
}
public void glUniform3f(int param1, float param2, float param3, float param4) {
GL20.glUniform3f(param1, param2, param3, param4);
@Override
public void glUniform3f(final int location, final float v0, final float v1, final float v2) {
GL20.glUniform3f(location, v0, v1, v2);
}
public void glUniform4(int param1, FloatBuffer param2) {
checkLimit(param2);
GL20.glUniform4fv(param1, param2);
@Override
public void glUniform4(final int location, final FloatBuffer value) {
checkLimit(value);
GL20.glUniform4fv(location, value);
}
public void glUniform4(int param1, IntBuffer param2) {
checkLimit(param2);
GL20.glUniform4iv(param1, param2);
@Override
public void glUniform4(final int location, final IntBuffer value) {
checkLimit(value);
GL20.glUniform4iv(location, value);
}
public void glUniform4f(int param1, float param2, float param3, float param4, float param5) {
GL20.glUniform4f(param1, param2, param3, param4, param5);
@Override
public void glUniform4f(final int location, final float v0, final float v1, final float v2, final float v3) {
GL20.glUniform4f(location, v0, v1, v2, v3);
}
public void glUniformMatrix3(int param1, boolean param2, FloatBuffer param3) {
checkLimit(param3);
GL20.glUniformMatrix3fv(param1, param2, param3);
@Override
public void glUniformMatrix3(final int location, final boolean transpose, final FloatBuffer value) {
checkLimit(value);
GL20.glUniformMatrix3fv(location, transpose, value);
}
public void glUniformMatrix4(int param1, boolean param2, FloatBuffer param3) {
checkLimit(param3);
GL20.glUniformMatrix4fv(param1, param2, param3);
@Override
public void glUniformMatrix4(final int location, final boolean transpose, final FloatBuffer value) {
checkLimit(value);
GL20.glUniformMatrix4fv(location, transpose, value);
}
public void glUseProgram(int param1) {
GL20.glUseProgram(param1);
@Override
public void glUseProgram(final int program) {
GL20.glUseProgram(program);
}
public void glVertexAttribPointer(int param1, int param2, int param3, boolean param4, int param5, long param6) {
GL20.glVertexAttribPointer(param1, param2, param3, param4, param5, param6);
@Override
public void glVertexAttribPointer(final int index, final int size, final int type, final boolean normalized,
final int stride, final long pointer) {
GL20.glVertexAttribPointer(index, size, type, normalized, stride, pointer);
}
public void glViewport(int param1, int param2, int param3, int param4) {
GL11.glViewport(param1, param2, param3, param4);
@Override
public void glViewport(final int x, final int y, final int width, final int height) {
GL11.glViewport(x, y, width, height);
}
public int glGetAttribLocation(int param1, String param2) {
@Override
public int glGetAttribLocation(final int program, final String name) {
// NOTE: LWJGL requires null-terminated strings
return GL20.glGetAttribLocation(param1, param2 + "\0");
return GL20.glGetAttribLocation(program, name + "\0");
}
public int glGetUniformLocation(int param1, String param2) {
@Override
public int glGetUniformLocation(final int program, final String name) {
// NOTE: LWJGL requires null-terminated strings
return GL20.glGetUniformLocation(param1, param2 + "\0");
return GL20.glGetUniformLocation(program, name + "\0");
}
public void glShaderSource(int param1, String[] param2, IntBuffer param3) {
checkLimit(param3);
GL20.glShaderSource(param1, param2);
@Override
public void glShaderSource(final int shader, final String[] strings, final IntBuffer length) {
checkLimit(length);
GL20.glShaderSource(shader, strings);
}
public String glGetProgramInfoLog(int program, int maxSize) {
@Override
public String glGetProgramInfoLog(final int program, final int maxSize) {
return GL20.glGetProgramInfoLog(program, maxSize);
}
@ -492,28 +596,28 @@ public class LwjglGL implements GL, GL2, GL3, GL4 {
}
@Override
public void glBindFragDataLocation(int param1, int param2, String param3) {
GL30.glBindFragDataLocation(param1, param2, param3);
public void glBindFragDataLocation(final int program, final int colorNumber, final String name) {
GL30.glBindFragDataLocation(program, colorNumber, name);
}
@Override
public void glBindVertexArray(int param1) {
GL30.glBindVertexArray(param1);
public void glBindVertexArray(final int array) {
GL30.glBindVertexArray(array);
}
@Override
public void glGenVertexArrays(IntBuffer param1) {
checkLimit(param1);
GL30.glGenVertexArrays(param1);
public void glGenVertexArrays(final IntBuffer arrays) {
checkLimit(arrays);
GL30.glGenVertexArrays(arrays);
}
@Override
public void glPatchParameter(int count) {
GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES,count);
public void glPatchParameter(final int count) {
GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES, count);
}
@Override
public void glDeleteVertexArrays(IntBuffer arrays) {
public void glDeleteVertexArrays(final IntBuffer arrays) {
checkLimit(arrays);
ARBVertexArrayObject.glDeleteVertexArrays(arrays);
}

@ -31,74 +31,65 @@
*/
package com.jme3.renderer.lwjgl;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.opengl.GLExt;
import org.lwjgl.opengl.*;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public class LwjglGLExt implements GLExt {
private static void checkLimit(Buffer buffer) {
if (buffer == null) {
return;
}
if (buffer.limit() == 0) {
throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
}
if (buffer.remaining() == 0) {
throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
}
}
/**
* The LWJGL implementation og {@link GLExt}.
*/
public class LwjglGLExt extends LwjglRender implements GLExt {
@Override
public void glBufferData(int target, IntBuffer data, int usage) {
public void glBufferData(final int target, final IntBuffer data, final int usage) {
checkLimit(data);
GL15.glBufferData(target, data, usage);
}
@Override
public void glBufferSubData(int target, long offset, IntBuffer data) {
public void glBufferSubData(final int target, final long offset, final IntBuffer data) {
checkLimit(data);
GL15.glBufferSubData(target, offset, data);
}
@Override
public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount) {
ARBDrawInstanced.glDrawArraysInstancedARB(mode, first, count, primcount);
public void glDrawArraysInstancedARB(final int mode, final int first, final int count, final int primCount) {
ARBDrawInstanced.glDrawArraysInstancedARB(mode, first, count, primCount);
}
@Override
public void glDrawBuffers(IntBuffer bufs) {
public void glDrawBuffers(final IntBuffer bufs) {
checkLimit(bufs);
GL20.glDrawBuffers(bufs);
}
@Override
public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount) {
ARBDrawInstanced.glDrawElementsInstancedARB(mode, indices_count, type, indices_buffer_offset, primcount);
public void glDrawElementsInstancedARB(final int mode, final int indicesCount, final int type,
final long indicesBufferOffset, final int primCount) {
ARBDrawInstanced.glDrawElementsInstancedARB(mode, indicesCount, type, indicesBufferOffset, primCount);
}
@Override
public void glGetMultisample(int pname, int index, FloatBuffer val) {
public void glGetMultisample(final int pname, final int index, final FloatBuffer val) {
checkLimit(val);
ARBTextureMultisample.glGetMultisamplefv(pname, index, val);
}
@Override
public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations) {
ARBTextureMultisample.glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
public void glTexImage2DMultisample(final int target, final int samples, final int internalFormat, final int width,
final int height, final boolean fixedSampleLocations) {
ARBTextureMultisample.glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
}
@Override
public void glVertexAttribDivisorARB(int index, int divisor) {
public void glVertexAttribDivisorARB(final int index, final int divisor) {
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor);
}
@Override
public Object glFenceSync(int condition, int flags) {
public Object glFenceSync(final int condition, final int flags) {
return ARBSync.glFenceSync(condition, flags);
}

@ -31,106 +31,99 @@
*/
package com.jme3.renderer.lwjgl;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.opengl.GLFbo;
import org.lwjgl.opengl.EXTFramebufferBlit;
import org.lwjgl.opengl.EXTFramebufferMultisample;
import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.EXTTextureArray;
import java.nio.Buffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.EXTTextureArray;
/**
* Implements GLFbo via GL_EXT_framebuffer_object.
*
* @author Kirill Vainer
*/
public class LwjglGLFboEXT implements GLFbo {
private static void checkLimit(Buffer buffer) {
if (buffer == null) {
return;
}
if (buffer.limit() == 0) {
throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
}
if (buffer.remaining() == 0) {
throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
}
}
public class LwjglGLFboEXT extends LwjglRender implements GLFbo {
@Override
public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
public void glBlitFramebufferEXT(final int srcX0, final int srcY0, final int srcX1, final int srcY1,
final int dstX0, final int dstY0, final int dstX1, final int dstY1, final int mask,
final int filter) {
EXTFramebufferBlit.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
@Override
public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
EXTFramebufferMultisample.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
public void glRenderbufferStorageMultisampleEXT(final int target, final int samples, final int internalFormat,
final int width, final int height) {
EXTFramebufferMultisample.glRenderbufferStorageMultisampleEXT(target, samples, internalFormat, width, height);
}
@Override
public void glBindFramebufferEXT(int param1, int param2) {
EXTFramebufferObject.glBindFramebufferEXT(param1, param2);
public void glBindFramebufferEXT(final int target, final int frameBuffer) {
EXTFramebufferObject.glBindFramebufferEXT(target, frameBuffer);
}
@Override
public void glBindRenderbufferEXT(int param1, int param2) {
EXTFramebufferObject.glBindRenderbufferEXT(param1, param2);
public void glBindRenderbufferEXT(final int target, final int renderBuffer) {
EXTFramebufferObject.glBindRenderbufferEXT(target, renderBuffer);
}
@Override
public int glCheckFramebufferStatusEXT(int param1) {
return EXTFramebufferObject.glCheckFramebufferStatusEXT(param1);
public int glCheckFramebufferStatusEXT(final int target) {
return EXTFramebufferObject.glCheckFramebufferStatusEXT(target);
}
@Override
public void glDeleteFramebuffersEXT(IntBuffer param1) {
checkLimit(param1);
EXTFramebufferObject.glDeleteFramebuffersEXT(param1);
public void glDeleteFramebuffersEXT(final IntBuffer frameBuffers) {
checkLimit(frameBuffers);
EXTFramebufferObject.glDeleteFramebuffersEXT(frameBuffers);
}
@Override
public void glDeleteRenderbuffersEXT(IntBuffer param1) {
checkLimit(param1);
EXTFramebufferObject.glDeleteRenderbuffersEXT(param1);
public void glDeleteRenderbuffersEXT(final IntBuffer renderBuffers) {
checkLimit(renderBuffers);
EXTFramebufferObject.glDeleteRenderbuffersEXT(renderBuffers);
}
@Override
public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
EXTFramebufferObject.glFramebufferRenderbufferEXT(param1, param2, param3, param4);
public void glFramebufferRenderbufferEXT(final int target, final int attachment, final int renderBufferTarget,
final int renderBuffer) {
EXTFramebufferObject.glFramebufferRenderbufferEXT(target, attachment, renderBufferTarget, renderBuffer);
}
@Override
public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
EXTFramebufferObject.glFramebufferTexture2DEXT(param1, param2, param3, param4, param5);
public void glFramebufferTexture2DEXT(final int target, final int attachment, final int texTarget,
final int texture, final int level) {
EXTFramebufferObject.glFramebufferTexture2DEXT(target, attachment, texTarget, texture, level);
}
@Override
public void glGenFramebuffersEXT(IntBuffer param1) {
checkLimit(param1);
EXTFramebufferObject.glGenFramebuffersEXT(param1);
public void glGenFramebuffersEXT(final IntBuffer frameBuffers) {
checkLimit(frameBuffers);
EXTFramebufferObject.glGenFramebuffersEXT(frameBuffers);
}
@Override
public void glGenRenderbuffersEXT(IntBuffer param1) {
checkLimit(param1);
EXTFramebufferObject.glGenRenderbuffersEXT(param1);
public void glGenRenderbuffersEXT(final IntBuffer renderBuffers) {
checkLimit(renderBuffers);
EXTFramebufferObject.glGenRenderbuffersEXT(renderBuffers);
}
@Override
public void glGenerateMipmapEXT(int param1) {
EXTFramebufferObject.glGenerateMipmapEXT(param1);
public void glGenerateMipmapEXT(final int target) {
EXTFramebufferObject.glGenerateMipmapEXT(target);
}
@Override
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
EXTFramebufferObject.glRenderbufferStorageEXT(param1, param2, param3, param4);
public void glRenderbufferStorageEXT(final int target, final int internalFormat, final int width,
final int height) {
EXTFramebufferObject.glRenderbufferStorageEXT(target, internalFormat, width, height);
}
@Override
public void glFramebufferTextureLayerEXT(int target, int attachment, int texture, int level, int layer) {
public void glFramebufferTextureLayerEXT(final int target, final int attachment, final int texture, final int level,
final int layer) {
EXTTextureArray.glFramebufferTextureLayerEXT(target, attachment, texture, level, layer);
}
}

@ -31,11 +31,9 @@
*/
package com.jme3.renderer.lwjgl;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.opengl.GLFbo;
import org.lwjgl.opengl.GL30;
import java.nio.Buffer;
import java.nio.IntBuffer;
/**
@ -43,91 +41,86 @@ import java.nio.IntBuffer;
*
* @author Kirill Vainer
*/
public class LwjglGLFboGL3 implements GLFbo {
private static void checkLimit(Buffer buffer) {
if (buffer == null) {
return;
}
if (buffer.limit() == 0) {
throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
}
if (buffer.remaining() == 0) {
throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
}
}
public class LwjglGLFboGL3 extends LwjglRender implements GLFbo {
@Override
public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
public void glBlitFramebufferEXT(final int srcX0, final int srcY0, final int srcX1, final int srcY1,
final int dstX0, final int dstY0, final int dstX1, final int dstY1, final int mask,
final int filter) {
GL30.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
@Override
public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
GL30.glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
public void glRenderbufferStorageMultisampleEXT(final int target, final int samples, final int internalFormat,
final int width, final int height) {
GL30.glRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
}
@Override
public void glBindFramebufferEXT(int param1, int param2) {
GL30.glBindFramebuffer(param1, param2);
public void glBindFramebufferEXT(final int target, final int frameBuffer) {
GL30.glBindFramebuffer(target, frameBuffer);
}
@Override
public void glBindRenderbufferEXT(int param1, int param2) {
GL30.glBindRenderbuffer(param1, param2);
public void glBindRenderbufferEXT(final int target, final int renderBuffer) {
GL30.glBindRenderbuffer(target, renderBuffer);
}
@Override
public int glCheckFramebufferStatusEXT(int param1) {
return GL30.glCheckFramebufferStatus(param1);
public int glCheckFramebufferStatusEXT(final int target) {
return GL30.glCheckFramebufferStatus(target);
}
@Override
public void glDeleteFramebuffersEXT(IntBuffer param1) {
checkLimit(param1);
GL30.glDeleteFramebuffers(param1);
public void glDeleteFramebuffersEXT(final IntBuffer frameBuffers) {
checkLimit(frameBuffers);
GL30.glDeleteFramebuffers(frameBuffers);
}
@Override
public void glDeleteRenderbuffersEXT(IntBuffer param1) {
checkLimit(param1);
GL30.glDeleteRenderbuffers(param1);
public void glDeleteRenderbuffersEXT(final IntBuffer renderBuffers) {
checkLimit(renderBuffers);
GL30.glDeleteRenderbuffers(renderBuffers);
}
@Override
public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
GL30.glFramebufferRenderbuffer(param1, param2, param3, param4);
public void glFramebufferRenderbufferEXT(final int target, final int attachment, final int renderBufferTarget,
final int renderBuffer) {
GL30.glFramebufferRenderbuffer(target, attachment, renderBufferTarget, renderBuffer);
}
@Override
public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
GL30.glFramebufferTexture2D(param1, param2, param3, param4, param5);
public void glFramebufferTexture2DEXT(final int target, final int attachment, final int texTarget,
final int texture, final int level) {
GL30.glFramebufferTexture2D(target, attachment, texTarget, texture, level);
}
@Override
public void glGenFramebuffersEXT(IntBuffer param1) {
checkLimit(param1);
GL30.glGenFramebuffers(param1);
public void glGenFramebuffersEXT(final IntBuffer frameBuffers) {
checkLimit(frameBuffers);
GL30.glGenFramebuffers(frameBuffers);
}
@Override
public void glGenRenderbuffersEXT(IntBuffer param1) {
checkLimit(param1);
GL30.glGenRenderbuffers(param1);
public void glGenRenderbuffersEXT(final IntBuffer renderBuffers) {
checkLimit(renderBuffers);
GL30.glGenRenderbuffers(renderBuffers);
}
@Override
public void glGenerateMipmapEXT(int param1) {
GL30.glGenerateMipmap(param1);
public void glGenerateMipmapEXT(final int target) {
GL30.glGenerateMipmap(target);
}
@Override
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
GL30.glRenderbufferStorage(param1, param2, param3, param4);
public void glRenderbufferStorageEXT(final int target, final int internalFormat, final int width,
final int height) {
GL30.glRenderbufferStorage(target, internalFormat, width, height);
}
@Override
public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) {
GL30.glFramebufferTextureLayer(param1, param2, param3, param4, param5);
public void glFramebufferTextureLayerEXT(final int target, final int attachment, final int texture, final int level,
final int layer) {
GL30.glFramebufferTextureLayer(target, attachment, texture, level, layer);
}
}

@ -0,0 +1,25 @@
package com.jme3.renderer.lwjgl;
import com.jme3.renderer.RendererException;
import java.nio.Buffer;
/**
* The base class of LWJGL implementations.
*
* @author JavaSaBr
*/
public class LwjglRender {
protected static void checkLimit(final Buffer buffer) {
if (buffer == null) {
return;
}
if (buffer.limit() == 0) {
throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
}
if (buffer.remaining() == 0) {
throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
}
}
}

@ -33,12 +33,14 @@
package com.jme3.system.lwjgl;
import static com.jme3.util.LWJGLBufferAllocator.PROPERTY_CONCURRENT_BUFFER_ALLOCATOR;
import static java.util.stream.Collectors.toSet;
import static org.lwjgl.opencl.CL10.CL_CONTEXT_PLATFORM;
import static org.lwjgl.opengl.GL.createCapabilities;
import static org.lwjgl.opengl.GL11.glGetInteger;
import com.jme3.input.lwjgl.GlfwJoystickInput;
import com.jme3.input.lwjgl.GlfwKeyInput;
import com.jme3.input.lwjgl.GlfwMouseInput;
import com.jme3.lwjgl3.utils.APIUtil;
import com.jme3.opencl.Context;
import com.jme3.opencl.DefaultPlatformChooser;
import com.jme3.opencl.Device;
@ -61,6 +63,7 @@ import com.jme3.util.BufferAllocatorFactory;
import com.jme3.util.LWJGLBufferAllocator;
import com.jme3.util.LWJGLBufferAllocator.ConcurrentLWJGLBufferAllocator;
import org.lwjgl.PointerBuffer;
import org.lwjgl.Version;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opencl.APPLEGLSharing;
import org.lwjgl.opencl.CL10;
@ -69,11 +72,11 @@ import org.lwjgl.opengl.ARBDebugOutput;
import org.lwjgl.opengl.ARBFramebufferObject;
import org.lwjgl.opengl.EXTFramebufferMultisample;
import org.lwjgl.opengl.GLCapabilities;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.Platform;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -98,35 +101,48 @@ public abstract class LwjglContext implements JmeContext {
}
}
public static final boolean CL_GL_SHARING_POSSIBLE = true;
private static final Set<String> SUPPORTED_RENDERS = new HashSet<>(Arrays.asList(
AppSettings.LWJGL_OPENGL2,
AppSettings.LWJGL_OPENGL3,
AppSettings.LWJGL_OPENGL33,
AppSettings.LWJGL_OPENGL4,
AppSettings.LWJGL_OPENGL41,
AppSettings.LWJGL_OPENGL42,
AppSettings.LWJGL_OPENGL43,
AppSettings.LWJGL_OPENGL44,
AppSettings.LWJGL_OPENGL45
));
protected static final String THREAD_NAME = "jME3 Main";
public static final boolean CL_GL_SHARING_POSSIBLE = true;
protected AtomicBoolean created = new AtomicBoolean(false);
protected AtomicBoolean renderable = new AtomicBoolean(false);
protected final Object createdLock = new Object();
protected final AtomicBoolean created = new AtomicBoolean(false);
protected final AtomicBoolean renderable = new AtomicBoolean(false);
protected final AppSettings settings = new AppSettings(true);
protected AppSettings settings = new AppSettings(true);
protected Renderer renderer;
protected GlfwKeyInput keyInput;
protected GlfwMouseInput mouseInput;
protected GlfwJoystickInput joyInput;
protected Timer timer;
protected Renderer renderer;
protected SystemListener listener;
protected com.jme3.opencl.lwjgl.LwjglContext clContext;
public void setSystemListener(SystemListener listener) {
@Override
public void setSystemListener(final SystemListener listener) {
this.listener = listener;
}
protected void printContextInitInfo() {
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
+ " * Graphics Adapter: GLFW {2}",
new Object[]{org.lwjgl.Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n * Graphics Adapter: GLFW {2}",
APIUtil.toArray(Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()));
}
protected int determineMaxSamples() {
// If we already have a valid context, determine samples using current context.
if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object")) {
return glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES);
@ -138,19 +154,19 @@ public abstract class LwjglContext implements JmeContext {
}
protected int getNumSamplesToUse() {
int samples = 0;
if (settings.getSamples() > 1) {
samples = settings.getSamples();
final int supportedSamples = determineMaxSamples();
if (supportedSamples < samples) {
logger.log(Level.WARNING,
"Couldn't satisfy antialiasing samples requirement: x{0}. "
+ "Video hardware only supports: x{1}",
new Object[]{samples, supportedSamples});
logger.log(Level.WARNING, "Couldn't satisfy antialiasing samples requirement: x{0}. " +
"Video hardware only supports: x{1}", APIUtil.toArray(samples, supportedSamples));
samples = supportedSamples;
}
}
return samples;
}
@ -161,18 +177,10 @@ public abstract class LwjglContext implements JmeContext {
if (!capabilities.OpenGL20) {
throw new RendererException("OpenGL 2.0 or higher is required for jMonkeyEngine");
} else if (!SUPPORTED_RENDERS.contains(renderer)) {
throw new UnsupportedOperationException("Unsupported renderer: " + renderer);
}
if (renderer.equals(AppSettings.LWJGL_OPENGL2)
|| renderer.equals(AppSettings.LWJGL_OPENGL3)
|| renderer.equals(AppSettings.LWJGL_OPENGL33)
|| renderer.equals(AppSettings.LWJGL_OPENGL4)
|| renderer.equals(AppSettings.LWJGL_OPENGL41)
|| renderer.equals(AppSettings.LWJGL_OPENGL42)
|| renderer.equals(AppSettings.LWJGL_OPENGL43)
|| renderer.equals(AppSettings.LWJGL_OPENGL44)
|| renderer.equals(AppSettings.LWJGL_OPENGL45)) {
GL gl = new LwjglGL();
GLExt glext = new LwjglGLExt();
GLFbo glfbo;
@ -204,9 +212,6 @@ public abstract class LwjglContext implements JmeContext {
this.renderer = new GLRenderer(gl, glext, glfbo);
this.renderer.initialize();
} else {
throw new UnsupportedOperationException("Unsupported renderer: " + renderer);
}
if (capabilities.GL_ARB_debug_output && settings.getBoolean("GraphicsDebug")) {
ARBDebugOutput.glDebugMessageCallbackARB(new LwjglGLDebugOutputHandler(), 0);
@ -227,42 +232,41 @@ public abstract class LwjglContext implements JmeContext {
if (joyInput != null) {
joyInput.initialize();
}
renderable.set(true);
renderable.set(true);
}
/**
* Returns a list of the available platforms, filtered by the specified
* filter.
*
* <p>
* Copied from the old release
*
* @return the available platforms
*/
private static long[] getPlatforms() {
int[] count = new int[1];
int errcode = CL10.clGetPlatformIDs(null, count);
try (MemoryStack stack = MemoryStack.stackPush()) {
final IntBuffer countBuffer = stack.callocInt(1);
int errcode = CL10.clGetPlatformIDs(null, countBuffer);
Utils.checkError(errcode, "clGetDeviceIDs");
int num_platforms = count[0];
if (num_platforms == 0) {
return new long[0];
}
final int count = countBuffer.get();
final PointerBuffer pointer = stack.callocPointer(count);
PointerBuffer platforms = PointerBuffer.allocateDirect(num_platforms);
errcode = CL10.clGetPlatformIDs(platforms, (IntBuffer) null);
errcode = CL10.clGetPlatformIDs(pointer, (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();
final long[] platformIDs = new long[count];
for (int i = 0; i < count; i++) {
platformIDs[i] = pointer.get();
}
return platformIDs;
}
}
protected void initOpenCL(long window) {
protected void initOpenCL(final long window) {
logger.info("Initialize OpenCL with LWJGL3");
// try {
@ -272,16 +276,18 @@ public abstract class LwjglContext implements JmeContext {
// return;
// }
//load platforms and devices
// load platforms and devices
StringBuilder platformInfos = new StringBuilder();
ArrayList<LwjglPlatform> platforms = new ArrayList<>();
for (long p : getPlatforms()) {
platforms.add(new LwjglPlatform(p));
List<LwjglPlatform> platforms = new ArrayList<>();
for (long platformId : getPlatforms()) {
platforms.add(new LwjglPlatform(platformId));
}
platformInfos.append("Available OpenCL platforms:");
for (int i=0; i<platforms.size(); ++i) {
for (int i = 0; i < platforms.size(); ++i) {
LwjglPlatform platform = platforms.get(i);
platformInfos.append("\n * Platform ").append(i+1);
platformInfos.append("\n * Platform ").append(i + 1);
platformInfos.append("\n * Name: ").append(platform.getName());
platformInfos.append("\n * Vendor: ").append(platform.getVendor());
platformInfos.append("\n * Version: ").append(platform.getVersion());
@ -291,7 +297,7 @@ public abstract class LwjglContext implements JmeContext {
platformInfos.append("\n * Available devices:");
for (int j=0; j<devices.size(); ++j) {
LwjglDevice device = devices.get(j);
platformInfos.append("\n * * Device ").append(j+1);
platformInfos.append("\n * * Device ").append(j + 1);
platformInfos.append("\n * * Name: ").append(device.getName());
platformInfos.append("\n * * Vendor: ").append(device.getVendor());
platformInfos.append("\n * * Version: ").append(device.getVersion());
@ -309,6 +315,7 @@ public abstract class LwjglContext implements JmeContext {
platformInfos.append("\n * * Supports interop: ").append(device.hasOpenGLInterop());
}
}
logger.info(platformInfos.toString());
//choose devices
@ -317,40 +324,56 @@ public abstract class LwjglContext implements JmeContext {
try {
chooser = (PlatformChooser) Class.forName(settings.getOpenCLPlatformChooser()).newInstance();
} catch (Exception ex) {
logger.log(Level.WARNING, "unable to instantiate custom PlatformChooser", ex);
logger.log(Level.WARNING, "Unable to instantiate custom PlatformChooser", ex);
}
}
if (chooser == null) {
chooser = new DefaultPlatformChooser();
}
List<? extends Device> choosenDevices = chooser.chooseDevices(platforms);
List<Long> devices = new ArrayList<>(choosenDevices.size());
LwjglPlatform platform = null;
for (Device d : choosenDevices) {
if (!(d instanceof LwjglDevice)) {
logger.log(Level.SEVERE, "attempt to return a custom Device implementation from PlatformChooser: {0}", d);
final List<? extends Device> choosenDevices = chooser.chooseDevices(platforms);
final Optional<? extends Device> unsupportedDevice = choosenDevices.stream()
.filter(dev -> !(dev instanceof LwjglDevice))
.findAny();
if (unsupportedDevice.isPresent()) {
logger.log(Level.SEVERE, "attempt to return a custom Device implementation " +
"from PlatformChooser: {0}", unsupportedDevice.get());
return;
}
LwjglDevice ld = (LwjglDevice) d;
if (platform == null) {
platform = ld.getPlatform();
} else if (platform != ld.getPlatform()) {
final Set<LwjglPlatform> lwjglPlatforms = choosenDevices.stream()
.map(LwjglDevice.class::cast)
.map(LwjglDevice::getPlatform)
.collect(toSet());
if (lwjglPlatforms.size() != 1) {
logger.severe("attempt to use devices from different platforms");
return;
}
devices.add(ld.getDevice());
}
if (devices.isEmpty()) {
final long[] deviceIds = choosenDevices.stream()
.map(LwjglDevice.class::cast)
.mapToLong(LwjglDevice::getDevice)
.toArray();
if (deviceIds.length < 1) {
logger.warning("no devices specified, no OpenCL context created");
return;
}
final LwjglPlatform platform = lwjglPlatforms.stream()
.findFirst()
.orElseThrow(() -> new RuntimeException("not found a platform"));
logger.log(Level.INFO, "chosen platform: {0}", platform.getName());
logger.log(Level.INFO, "chosen devices: {0}", choosenDevices);
//create context
// create context
try {
long c = createContext(platform.getPlatform(), devices, window);
clContext = new com.jme3.opencl.lwjgl.LwjglContext(c, (List<LwjglDevice>) choosenDevices);
long context = createContext(platform.getPlatform(), deviceIds, window);
clContext = new com.jme3.opencl.lwjgl.LwjglContext(context, (List<LwjglDevice>) choosenDevices);
} catch (final Exception ex) {
logger.log(Level.SEVERE, "Unable to create OpenCL context", ex);
return;
@ -358,51 +381,53 @@ public abstract class LwjglContext implements JmeContext {
logger.info("OpenCL context created");
}
private long createContext(final long platform, final List<Long> devices, long window) throws Exception {
final int propertyCount = 2 + 4 + 1;
private long createContext(final long platform, final long[] devices, long window) {
try (MemoryStack stack = MemoryStack.stackPush()) {
final PointerBuffer properties = PointerBuffer.allocateDirect(propertyCount + devices.size());
final int propertyCount = 2 + 4 + 1;
final PointerBuffer properties = stack.callocPointer(propertyCount + devices.length);
//set sharing properties
//https://github.com/glfw/glfw/issues/104
//https://github.com/LWJGL/lwjgl3/blob/master/modules/core/src/test/java/org/lwjgl/demo/opencl/Mandelbrot.java
//TODO: test on Linus and MacOSX
// set sharing properties
// https://github.com/glfw/glfw/issues/104
// https://github.com/LWJGL/lwjgl3/blob/master/modules/core/src/test/java/org/lwjgl/demo/opencl/Mandelbrot.java
// TODO: test on Linux and MacOSX
switch (Platform.get()) {
case WINDOWS:
properties
.put(KHRGLSharing.CL_GL_CONTEXT_KHR)
properties.put(KHRGLSharing.CL_GL_CONTEXT_KHR)
.put(org.lwjgl.glfw.GLFWNativeWGL.glfwGetWGLContext(window))
.put(KHRGLSharing.CL_WGL_HDC_KHR)
.put(org.lwjgl.opengl.WGL.wglGetCurrentDC());
break;
case LINUX:
properties
.put(KHRGLSharing.CL_GL_CONTEXT_KHR)
properties.put(KHRGLSharing.CL_GL_CONTEXT_KHR)
.put(org.lwjgl.glfw.GLFWNativeGLX.glfwGetGLXContext(window))
.put(KHRGLSharing.CL_GLX_DISPLAY_KHR)
.put(org.lwjgl.glfw.GLFWNativeX11.glfwGetX11Display());
break;
case MACOSX:
properties
.put(APPLEGLSharing.CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE)
properties.put(APPLEGLSharing.CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE)
.put(org.lwjgl.opengl.CGL.CGLGetShareGroup(org.lwjgl.opengl.CGL.CGLGetCurrentContext()));
}
properties.put(CL_CONTEXT_PLATFORM).put(platform);
properties.put(0);
properties.flip();
Utils.errorBuffer.rewind();
PointerBuffer deviceBuffer = PointerBuffer.allocateDirect(devices.size());
for (long d : devices) {
deviceBuffer.put(d);
final IntBuffer error = stack.callocInt(1);
final PointerBuffer deviceBuffer = stack.callocPointer(devices.length);
for (final long deviceId : devices) {
deviceBuffer.put(deviceId);
}
deviceBuffer.flip();
long context = CL10.clCreateContext(properties, deviceBuffer, null, 0, Utils.errorBuffer);
Utils.checkError(Utils.errorBuffer, "clCreateContext");
long context = CL10.clCreateContext(properties, deviceBuffer, null, 0, error);
Utils.checkError(error, "clCreateContext");
return context;
}
}
public void internalDestroy() {
renderer = null;
@ -419,7 +444,6 @@ public abstract class LwjglContext implements JmeContext {
created.set(true);
createdLock.notifyAll();
}
initContextFirstTime();
}

@ -75,14 +75,4 @@ 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);
}
}

@ -53,6 +53,9 @@ import org.lwjgl.glfw.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -66,6 +69,48 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
private static final Logger LOGGER = Logger.getLogger(LwjglWindow.class.getName());
private static final EnumSet<JmeContext.Type> SUPPORTED_TYPES = EnumSet.of(
JmeContext.Type.Display,
JmeContext.Type.Canvas,
JmeContext.Type.OffscreenSurface);
private static final Map<String, Runnable> RENDER_CONFIGS = new HashMap<>();
static {
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL3, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL33, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL4, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL41, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL42, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL43, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL44, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
});
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL45, () -> {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
});
}
protected final AtomicBoolean needClose = new AtomicBoolean(false);
protected final AtomicBoolean needRestart = new AtomicBoolean(false);
@ -86,7 +131,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
protected boolean allowSwapBuffers = false;
public LwjglWindow(final JmeContext.Type type) {
if (!JmeContext.Type.Display.equals(type) && !JmeContext.Type.OffscreenSurface.equals(type) && !JmeContext.Type.Canvas.equals(type)) {
if (!SUPPORTED_TYPES.contains(type)) {
throw new IllegalArgumentException("Unsupported type '" + type.name() + "' provided");
}
@ -134,16 +180,6 @@ 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()) {
@ -157,36 +193,12 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
if (renderer.equals(AppSettings.LWJGL_OPENGL3)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL33)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL4)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL41)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL42)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL43)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL44)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
} else if (renderer.equals(AppSettings.LWJGL_OPENGL45)) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
} else {
RENDER_CONFIGS.computeIfAbsent(renderer, s -> () -> {
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
}
}).run();
if (settings.getBoolean("RendererDebug")) {
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
@ -242,16 +254,6 @@ 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() {
@ -264,20 +266,9 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
} else {
listener.loseFocus();
}
wasActive = !wasActive;
}
}
@Override
public void close() {
super.close();
}
@Override
public void callback(long args) {
super.callback(args);
}
});
// Center the window
@ -434,16 +425,13 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
try {
if (!JmeSystem.isLowPermissions()) {
// Enable uncaught exception handler only for current thread
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable thrown) {
Thread.currentThread().setUncaughtExceptionHandler((thread, thrown) -> {
listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown);
if (needClose.get()) {
// listener.handleError() has requested the
// context to close. Satisfy request.
deinitInThread();
}
}
});
}
@ -600,6 +588,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
deinitInThread();
}
@Override
public JoyInput getJoyInput() {
if (joyInput == null) {
joyInput = new GlfwJoystickInput();
@ -607,6 +596,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
return joyInput;
}
@Override
public MouseInput getMouseInput() {
if (mouseInput == null) {
mouseInput = new GlfwMouseInput(this);
@ -614,22 +604,25 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
return mouseInput;
}
@Override
public KeyInput getKeyInput() {
if (keyInput == null) {
keyInput = new GlfwKeyInput(this);
}
return keyInput;
}
@Override
public TouchInput getTouchInput() {
return null;
}
@Override
public void setAutoFlushFrames(boolean enabled) {
this.autoFlush = enabled;
}
@Override
public void destroy(boolean waitFor) {
needClose.set(true);

Loading…
Cancel
Save