Merge pull request #340 from Kendanware/issue314
Added LWJGL 3.x module and implementation in regards to issue #314experimental
commit
ed2c998f39
@ -0,0 +1,18 @@ |
|||||||
|
if (!hasProperty('mainClass')) { |
||||||
|
ext.mainClass = '' |
||||||
|
} |
||||||
|
|
||||||
|
repositories { |
||||||
|
maven { |
||||||
|
url "https://oss.sonatype.org/content/repositories/snapshots" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
dependencies { |
||||||
|
compile project(':jme3-core') |
||||||
|
compile project(':jme3-desktop') |
||||||
|
compile 'org.lwjgl:lwjgl:3.0.0b-SNAPSHOT' |
||||||
|
compile group: 'org.lwjgl', name: 'lwjgl-platform', version: '3.0.0b-SNAPSHOT', classifier: 'natives-windows' |
||||||
|
compile group: 'org.lwjgl', name: 'lwjgl-platform', version: '3.0.0b-SNAPSHOT', classifier: 'natives-linux' |
||||||
|
compile group: 'org.lwjgl', name: 'lwjgl-platform', version: '3.0.0b-SNAPSHOT', classifier: 'natives-osx' |
||||||
|
} |
@ -0,0 +1,140 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/package com.jme3.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; |
||||||
|
|
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.nio.FloatBuffer; |
||||||
|
import java.nio.IntBuffer; |
||||||
|
|
||||||
|
public final class LwjglAL implements AL { |
||||||
|
|
||||||
|
public LwjglAL() { |
||||||
|
} |
||||||
|
|
||||||
|
public String alGetString(int parameter) { |
||||||
|
return AL10.alGetString(parameter); |
||||||
|
} |
||||||
|
|
||||||
|
public int alGenSources() { |
||||||
|
return AL10.alGenSources(); |
||||||
|
} |
||||||
|
|
||||||
|
public int alGetError() { |
||||||
|
return AL10.alGetError(); |
||||||
|
} |
||||||
|
|
||||||
|
public void alDeleteSources(int numSources, 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) { |
||||||
|
if (buffers.position() != 0) throw new AssertionError(); |
||||||
|
if (buffers.limit() != numBuffers) throw new AssertionError(); |
||||||
|
AL10.alGenBuffers(buffers); |
||||||
|
} |
||||||
|
|
||||||
|
public void alDeleteBuffers(int numBuffers, IntBuffer buffers) { |
||||||
|
if (buffers.position() != 0) throw new AssertionError(); |
||||||
|
if (buffers.limit() != numBuffers) throw new AssertionError(); |
||||||
|
AL10.alDeleteBuffers(buffers); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSourceStop(int source) { |
||||||
|
AL10.alSourceStop(source); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSourcei(int source, int param, int value) { |
||||||
|
AL10.alSourcei(source, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alBufferData(int buffer, int format, ByteBuffer data, int size, 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) { |
||||||
|
AL10.alSourcePlay(source); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSourcePause(int source) { |
||||||
|
AL10.alSourcePause(source); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSourcef(int source, int param, float value) { |
||||||
|
AL10.alSourcef(source, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSource3f(int source, int param, float value1, float value2, float value3) { |
||||||
|
AL10.alSource3f(source, param, value1, value2, value3); |
||||||
|
} |
||||||
|
|
||||||
|
public int alGetSourcei(int source, int param) { |
||||||
|
return AL10.alGetSourcei(source, param); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSourceUnqueueBuffers(int source, int numBuffers, 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) { |
||||||
|
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) { |
||||||
|
AL10.alListenerfv(param, data); |
||||||
|
} |
||||||
|
|
||||||
|
public void alListenerf(int param, float value) { |
||||||
|
AL10.alListenerf(param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alListener3f(int param, float value1, float value2, float value3) { |
||||||
|
AL10.alListener3f(param, value1, value2, value3); |
||||||
|
} |
||||||
|
|
||||||
|
public void alSource3i(int source, int param, int value1, int value2, int value3) { |
||||||
|
AL11.alSource3i(source, param, value1, value2, value3); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.audio.lwjgl; |
||||||
|
|
||||||
|
import com.jme3.audio.openal.ALC; |
||||||
|
import org.lwjgl.openal.ALC10; |
||||||
|
import org.lwjgl.openal.ALContext; |
||||||
|
|
||||||
|
import java.nio.IntBuffer; |
||||||
|
|
||||||
|
import static org.lwjgl.openal.ALC10.alcGetContextsDevice; |
||||||
|
import static org.lwjgl.openal.ALC10.alcGetCurrentContext; |
||||||
|
|
||||||
|
public class LwjglALC implements ALC { |
||||||
|
|
||||||
|
private ALContext context; |
||||||
|
|
||||||
|
public void createALC() { |
||||||
|
context = ALContext.create(); |
||||||
|
} |
||||||
|
|
||||||
|
public void destroyALC() { |
||||||
|
if (context != null) { |
||||||
|
context.destroy(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCreated() { |
||||||
|
return context != null; |
||||||
|
} |
||||||
|
|
||||||
|
public String alcGetString(final int parameter) { |
||||||
|
final long context = alcGetCurrentContext(); |
||||||
|
final long device = alcGetContextsDevice(context); |
||||||
|
return ALC10.alcGetString(device, parameter); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean alcIsExtensionPresent(final String extension) { |
||||||
|
final long context = alcGetCurrentContext(); |
||||||
|
final long device = alcGetContextsDevice(context); |
||||||
|
return ALC10.alcIsExtensionPresent(device, extension); |
||||||
|
} |
||||||
|
|
||||||
|
public void alcGetInteger(final int param, final IntBuffer buffer, final int size) { |
||||||
|
if (buffer.position() != 0) throw new AssertionError(); |
||||||
|
if (buffer.limit() != size) throw new AssertionError(); |
||||||
|
|
||||||
|
final long context = alcGetCurrentContext(); |
||||||
|
final long device = alcGetContextsDevice(context); |
||||||
|
final int value = ALC10.alcGetInteger(device, param); |
||||||
|
//buffer.put(value);
|
||||||
|
} |
||||||
|
|
||||||
|
public void alcDevicePauseSOFT() { |
||||||
|
} |
||||||
|
|
||||||
|
public void alcDeviceResumeSOFT() { |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.audio.lwjgl; |
||||||
|
|
||||||
|
import com.jme3.audio.openal.EFX; |
||||||
|
import org.lwjgl.openal.EXTEfx; |
||||||
|
|
||||||
|
import java.nio.IntBuffer; |
||||||
|
|
||||||
|
public class LwjglEFX implements EFX { |
||||||
|
|
||||||
|
public void alGenAuxiliaryEffectSlots(int numSlots, 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) { |
||||||
|
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) { |
||||||
|
EXTEfx.alEffecti(effect, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alAuxiliaryEffectSloti(int effectSlot, int param, int value) { |
||||||
|
EXTEfx.alAuxiliaryEffectSloti(effectSlot, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alDeleteEffects(int numEffects, 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) { |
||||||
|
if (buffers.position() != 0) throw new AssertionError(); |
||||||
|
if (buffers.limit() != numEffectSlots) throw new AssertionError(); |
||||||
|
EXTEfx.alDeleteAuxiliaryEffectSlots(buffers); |
||||||
|
} |
||||||
|
|
||||||
|
public void alGenFilters(int numFilters, 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) { |
||||||
|
EXTEfx.alFilteri(filter, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alFilterf(int filter, int param, float value) { |
||||||
|
EXTEfx.alFilterf(filter, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
public void alDeleteFilters(int numFilters, 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) { |
||||||
|
EXTEfx.alEffectf(effect, param, value); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,211 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.input.lwjgl; |
||||||
|
|
||||||
|
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; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Daniel Johansson (dannyjo) |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
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>(); |
||||||
|
|
||||||
|
public void setJoyRumble(int joyId, float amount) { |
||||||
|
if (joyId >= joysticks.size()) { |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Joystick[] loadJoysticks(final InputManager inputManager) { |
||||||
|
for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) { |
||||||
|
if (glfwJoystickPresent(i) == GL11.GL_TRUE) { |
||||||
|
final String name = glfwGetJoystickName(i); |
||||||
|
final GlfwJoystick joystick = new GlfwJoystick(inputManager, this, i, name); |
||||||
|
joysticks.put(i, joystick); |
||||||
|
|
||||||
|
final FloatBuffer floatBuffer = glfwGetJoystickAxes(i); |
||||||
|
|
||||||
|
int axisIndex = 0; |
||||||
|
while (floatBuffer.hasRemaining()) { |
||||||
|
floatBuffer.get(); |
||||||
|
|
||||||
|
final String logicalId = JoystickCompatibilityMappings.remapComponent(joystick.getName(), convertAxisIndex(axisIndex)); |
||||||
|
final JoystickAxis joystickAxis = new DefaultJoystickAxis(inputManager, joystick, axisIndex, convertAxisIndex(axisIndex), logicalId, true, false, 0.0f); |
||||||
|
joystick.addAxis(axisIndex, joystickAxis); |
||||||
|
axisIndex++; |
||||||
|
} |
||||||
|
|
||||||
|
final ByteBuffer byteBuffer = glfwGetJoystickButtons(i); |
||||||
|
|
||||||
|
int buttonIndex = 0; |
||||||
|
while (byteBuffer.hasRemaining()) { |
||||||
|
byteBuffer.get(); |
||||||
|
final String logicalId = JoystickCompatibilityMappings.remapComponent(joystick.getName(), String.valueOf(buttonIndex)); |
||||||
|
joystick.addButton(new DefaultJoystickButton(inputManager, joystick, buttonIndex, String.valueOf(buttonIndex), logicalId)); |
||||||
|
buttonIndex++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return joysticks.values().toArray(new GlfwJoystick[joysticks.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
private String convertAxisIndex(final int index) { |
||||||
|
if (index == 0) { |
||||||
|
return "pov_x"; |
||||||
|
} else if (index == 1) { |
||||||
|
return "pov_y"; |
||||||
|
} else if (index == 2) { |
||||||
|
return "z"; |
||||||
|
} else if (index == 3) { |
||||||
|
return "rz"; |
||||||
|
} |
||||||
|
|
||||||
|
return String.valueOf(index); |
||||||
|
} |
||||||
|
|
||||||
|
public void initialize() { |
||||||
|
initialized = true; |
||||||
|
} |
||||||
|
|
||||||
|
public void update() { |
||||||
|
for (final Map.Entry<Integer, GlfwJoystick> entry : joysticks.entrySet()) { |
||||||
|
// Axes
|
||||||
|
final FloatBuffer axisValues = glfwGetJoystickAxes(entry.getKey()); |
||||||
|
|
||||||
|
for (final JoystickAxis axis : entry.getValue().getAxes()) { |
||||||
|
final float value = axisValues.get(axis.getAxisId()); |
||||||
|
listener.onJoyAxisEvent(new JoyAxisEvent(axis, value)); |
||||||
|
} |
||||||
|
|
||||||
|
// Buttons
|
||||||
|
final ByteBuffer byteBuffer = glfwGetJoystickButtons(entry.getKey()); |
||||||
|
|
||||||
|
for (final JoystickButton button : entry.getValue().getButtons()) { |
||||||
|
final boolean pressed = byteBuffer.get(button.getButtonId()) == GLFW_PRESS; |
||||||
|
listener.onJoyButtonEvent(new JoyButtonEvent(button, pressed)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void destroy() { |
||||||
|
initialized = false; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isInitialized() { |
||||||
|
return initialized; |
||||||
|
} |
||||||
|
|
||||||
|
public void setInputListener(RawInputListener listener) { |
||||||
|
this.listener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
public long getInputTimeNanos() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
protected class GlfwJoystick extends AbstractJoystick { |
||||||
|
|
||||||
|
private JoystickAxis povAxisX; |
||||||
|
private JoystickAxis povAxisY; |
||||||
|
|
||||||
|
public GlfwJoystick(InputManager inputManager, JoyInput joyInput, int joyId, String name) { |
||||||
|
super(inputManager, joyInput, joyId, name); |
||||||
|
} |
||||||
|
|
||||||
|
public void addAxis(final int index, final JoystickAxis axis) { |
||||||
|
super.addAxis(axis); |
||||||
|
|
||||||
|
if (index == 0) { |
||||||
|
povAxisX = axis; |
||||||
|
} else if (index == 1) { |
||||||
|
povAxisY = axis; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void addButton(JoystickButton button) { |
||||||
|
super.addButton(button); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JoystickAxis getXAxis() { |
||||||
|
return povAxisX; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JoystickAxis getYAxis() { |
||||||
|
return povAxisY; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JoystickAxis getPovXAxis() { |
||||||
|
return povAxisX; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JoystickAxis getPovYAxis() { |
||||||
|
return povAxisY; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getXAxisIndex() { |
||||||
|
return povAxisX.getAxisId(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getYAxisIndex() { |
||||||
|
return povAxisY.getAxisId(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,116 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.jme3.input.lwjgl; |
||||||
|
|
||||||
|
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.GLFWKeyCallback; |
||||||
|
|
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.Queue; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*; |
||||||
|
|
||||||
|
public class GlfwKeyInput implements KeyInput { |
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(GlfwKeyInput.class.getName()); |
||||||
|
|
||||||
|
private LwjglWindow context; |
||||||
|
private RawInputListener listener; |
||||||
|
private boolean initialized; |
||||||
|
private GLFWKeyCallback keyCallback; |
||||||
|
private Queue<KeyInputEvent> keyInputEvents = new LinkedList<KeyInputEvent>(); |
||||||
|
|
||||||
|
public GlfwKeyInput(LwjglWindow context) { |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
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) { |
||||||
|
final KeyInputEvent evt = new KeyInputEvent(scancode, (char) key, GLFW_PRESS == action, GLFW_REPEAT == action); |
||||||
|
evt.setTime(getInputTimeNanos()); |
||||||
|
keyInputEvents.add(evt); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
glfwSetInputMode(context.getWindowHandle(), GLFW_STICKY_KEYS, 1); |
||||||
|
|
||||||
|
initialized = true; |
||||||
|
logger.fine("Keyboard created."); |
||||||
|
} |
||||||
|
|
||||||
|
public int getKeyCount() { |
||||||
|
// This might not be correct
|
||||||
|
return GLFW_KEY_LAST - GLFW_KEY_SPACE; |
||||||
|
} |
||||||
|
|
||||||
|
public void update() { |
||||||
|
if (!context.isRenderable()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
while (!keyInputEvents.isEmpty()) { |
||||||
|
listener.onKeyEvent(keyInputEvents.poll()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void destroy() { |
||||||
|
if (!context.isRenderable()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
keyCallback.release(); |
||||||
|
logger.fine("Keyboard destroyed."); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isInitialized() { |
||||||
|
return initialized; |
||||||
|
} |
||||||
|
|
||||||
|
public void setInputListener(RawInputListener listener) { |
||||||
|
this.listener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
public long getInputTimeNanos() { |
||||||
|
return (long) (glfwGetTime() * 1000000000); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,215 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.jme3.input.lwjgl; |
||||||
|
|
||||||
|
import com.jme3.cursors.plugins.JmeCursor; |
||||||
|
import com.jme3.input.MouseInput; |
||||||
|
import com.jme3.input.RawInputListener; |
||||||
|
import com.jme3.input.event.MouseButtonEvent; |
||||||
|
import com.jme3.input.event.MouseMotionEvent; |
||||||
|
import com.jme3.system.lwjgl.LwjglWindow; |
||||||
|
import org.lwjgl.glfw.GLFWCursorPosCallback; |
||||||
|
import org.lwjgl.glfw.GLFWMouseButtonCallback; |
||||||
|
import org.lwjgl.glfw.GLFWScrollCallback; |
||||||
|
|
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.Queue; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* Captures mouse input using GLFW callbacks. It then temporarily stores these in event queues which are processed in the |
||||||
|
* {@link #update()} method. Due to some of the GLFW button id's there is a conversion method in this class which will |
||||||
|
* convert the GLFW left, middle and right mouse button to JME3 left, middle and right button codes. |
||||||
|
* |
||||||
|
* @author Daniel Johansson (dannyjo) |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class GlfwMouseInput implements MouseInput { |
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(GlfwMouseInput.class.getName()); |
||||||
|
|
||||||
|
private LwjglWindow context; |
||||||
|
private RawInputListener listener; |
||||||
|
private boolean cursorVisible = true; |
||||||
|
private int mouseX; |
||||||
|
private int mouseY; |
||||||
|
private int mouseWheel; |
||||||
|
private boolean initialized; |
||||||
|
private GLFWCursorPosCallback cursorPosCallback; |
||||||
|
private GLFWScrollCallback scrollCallback; |
||||||
|
private GLFWMouseButtonCallback mouseButtonCallback; |
||||||
|
private Queue<MouseMotionEvent> mouseMotionEvents = new LinkedList<MouseMotionEvent>(); |
||||||
|
private Queue<MouseButtonEvent> mouseButtonEvents = new LinkedList<MouseButtonEvent>(); |
||||||
|
|
||||||
|
public GlfwMouseInput(final LwjglWindow context) { |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
public void initialize() { |
||||||
|
glfwSetCursorPosCallback(context.getWindowHandle(), cursorPosCallback = new GLFWCursorPosCallback() { |
||||||
|
@Override |
||||||
|
public void invoke(long window, double xpos, double ypos) { |
||||||
|
int xDelta; |
||||||
|
int yDelta; |
||||||
|
int x = (int) Math.round(xpos); |
||||||
|
int y = context.getSettings().getHeight() - (int) Math.round(ypos); |
||||||
|
|
||||||
|
if (mouseX == 0) { |
||||||
|
mouseX = x; |
||||||
|
} |
||||||
|
|
||||||
|
if (mouseY == 0) { |
||||||
|
mouseY = y; |
||||||
|
} |
||||||
|
|
||||||
|
xDelta = x - mouseX; |
||||||
|
yDelta = y - mouseY; |
||||||
|
mouseX = x; |
||||||
|
mouseY = y; |
||||||
|
|
||||||
|
if (xDelta != 0 || yDelta != 0) { |
||||||
|
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(x, y, xDelta, yDelta, mouseWheel, 0); |
||||||
|
mouseMotionEvent.setTime(getInputTimeNanos()); |
||||||
|
mouseMotionEvents.add(mouseMotionEvent); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() { |
||||||
|
@Override |
||||||
|
public void invoke(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()); |
||||||
|
mouseMotionEvents.add(mouseMotionEvent); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() { |
||||||
|
@Override |
||||||
|
public void invoke(final long window, final int button, final int action, final int mods) { |
||||||
|
final MouseButtonEvent mouseButtonEvent = new MouseButtonEvent(convertButton(button), action == GLFW_PRESS, mouseX, mouseY); |
||||||
|
mouseButtonEvent.setTime(getInputTimeNanos()); |
||||||
|
mouseButtonEvents.add(mouseButtonEvent); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
setCursorVisible(cursorVisible); |
||||||
|
logger.fine("Mouse created."); |
||||||
|
initialized = true; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isInitialized() { |
||||||
|
return initialized; |
||||||
|
} |
||||||
|
|
||||||
|
public int getButtonCount() { |
||||||
|
return GLFW_MOUSE_BUTTON_LAST + 1; |
||||||
|
} |
||||||
|
|
||||||
|
public void update() { |
||||||
|
while (!mouseMotionEvents.isEmpty()) { |
||||||
|
listener.onMouseMotionEvent(mouseMotionEvents.poll()); |
||||||
|
} |
||||||
|
|
||||||
|
while (!mouseButtonEvents.isEmpty()) { |
||||||
|
listener.onMouseButtonEvent(mouseButtonEvents.poll()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void destroy() { |
||||||
|
if (!context.isRenderable()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
cursorPosCallback.release(); |
||||||
|
scrollCallback.release(); |
||||||
|
mouseButtonCallback.release(); |
||||||
|
|
||||||
|
logger.fine("Mouse destroyed."); |
||||||
|
} |
||||||
|
|
||||||
|
public void setCursorVisible(boolean visible) { |
||||||
|
cursorVisible = visible; |
||||||
|
|
||||||
|
if (!context.isRenderable()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (cursorVisible) { |
||||||
|
glfwSetInputMode(context.getWindowHandle(), GLFW_CURSOR, GLFW_CURSOR_NORMAL); |
||||||
|
} else { |
||||||
|
glfwSetInputMode(context.getWindowHandle(), GLFW_CURSOR, GLFW_CURSOR_DISABLED); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setInputListener(RawInputListener listener) { |
||||||
|
this.listener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
public long getInputTimeNanos() { |
||||||
|
return (long) (glfwGetTime() * 1000000000); |
||||||
|
} |
||||||
|
|
||||||
|
public void setNativeCursor(final JmeCursor jmeCursor) { |
||||||
|
if (jmeCursor != null) { |
||||||
|
final ByteBuffer byteBuffer = org.lwjgl.BufferUtils.createByteBuffer(jmeCursor.getImagesData().capacity()); |
||||||
|
byteBuffer.asIntBuffer().put(jmeCursor.getImagesData().array()); |
||||||
|
final long cursor = glfwCreateCursor(byteBuffer, jmeCursor.getXHotSpot(), jmeCursor.getYHotSpot()); |
||||||
|
glfwSetCursor(context.getWindowHandle(), cursor); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Simply converts the GLFW button code to a JME button code. If there is no match it just returns the GLFW button |
||||||
|
* code. Bare in mind GLFW supports 8 different mouse buttons. |
||||||
|
* |
||||||
|
* @param glfwButton the raw GLFW button index. |
||||||
|
* @return the mapped {@link MouseInput} button id. |
||||||
|
*/ |
||||||
|
private int convertButton(final int glfwButton) { |
||||||
|
if (glfwButton == GLFW_MOUSE_BUTTON_LEFT) { |
||||||
|
return MouseInput.BUTTON_LEFT; |
||||||
|
} else if(glfwButton == GLFW_MOUSE_BUTTON_MIDDLE) { |
||||||
|
return MouseInput.BUTTON_MIDDLE; |
||||||
|
} else if(glfwButton == GLFW_MOUSE_BUTTON_RIGHT) { |
||||||
|
return MouseInput.BUTTON_RIGHT; |
||||||
|
} |
||||||
|
|
||||||
|
return glfwButton; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,489 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.renderer.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 com.jme3.system.NativeLibraryLoader; |
||||||
|
import com.jme3.system.Platform; |
||||||
|
import org.lwjgl.opengl.*; |
||||||
|
|
||||||
|
import java.nio.*; |
||||||
|
|
||||||
|
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"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void resetStats() { |
||||||
|
} |
||||||
|
|
||||||
|
public void glActiveTexture(int param1) { |
||||||
|
GL13.glActiveTexture(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glAlphaFunc(int param1, float param2) { |
||||||
|
GL11.glAlphaFunc(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glAttachShader(int param1, int param2) { |
||||||
|
GL20.glAttachShader(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBindBuffer(int param1, int param2) { |
||||||
|
GL15.glBindBuffer(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBindTexture(int param1, int param2) { |
||||||
|
GL11.glBindTexture(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBlendFunc(int param1, int param2) { |
||||||
|
GL11.glBlendFunc(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferData(int param1, long param2, int param3) { |
||||||
|
GL15.glBufferData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferData(int param1, FloatBuffer param2, int param3) { |
||||||
|
checkLimit(param2); |
||||||
|
GL15.glBufferData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferData(int param1, ShortBuffer param2, int param3) { |
||||||
|
checkLimit(param2); |
||||||
|
GL15.glBufferData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferData(int param1, ByteBuffer param2, int param3) { |
||||||
|
checkLimit(param2); |
||||||
|
GL15.glBufferData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferSubData(int param1, long param2, FloatBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL15.glBufferSubData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferSubData(int param1, long param2, ShortBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL15.glBufferSubData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glBufferSubData(int param1, long param2, ByteBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL15.glBufferSubData(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glClear(int param1) { |
||||||
|
GL11.glClear(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glClearColor(float param1, float param2, float param3, float param4) { |
||||||
|
GL11.glClearColor(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
public void glColorMask(boolean param1, boolean param2, boolean param3, boolean param4) { |
||||||
|
GL11.glColorMask(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
public void glCompileShader(int param1) { |
||||||
|
GL20.glCompileShader(param1); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
public int glCreateProgram() { |
||||||
|
return GL20.glCreateProgram(); |
||||||
|
} |
||||||
|
|
||||||
|
public int glCreateShader(int param1) { |
||||||
|
return GL20.glCreateShader(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glCullFace(int param1) { |
||||||
|
GL11.glCullFace(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDeleteBuffers(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL15.glDeleteBuffers(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDeleteProgram(int param1) { |
||||||
|
GL20.glDeleteProgram(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDeleteShader(int param1) { |
||||||
|
GL20.glDeleteShader(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDeleteTextures(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL11.glDeleteTextures(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDepthFunc(int param1) { |
||||||
|
GL11.glDepthFunc(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDepthMask(boolean param1) { |
||||||
|
GL11.glDepthMask(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDepthRange(double param1, double param2) { |
||||||
|
GL11.glDepthRange(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDetachShader(int param1, int param2) { |
||||||
|
GL20.glDetachShader(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDisable(int param1) { |
||||||
|
GL11.glDisable(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDisableVertexAttribArray(int param1) { |
||||||
|
GL20.glDisableVertexAttribArray(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDrawArrays(int param1, int param2, int param3) { |
||||||
|
GL11.glDrawArrays(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDrawBuffer(int param1) { |
||||||
|
GL11.glDrawBuffer(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glDrawRangeElements(int param1, int param2, int param3, int param4, int param5, long param6) { |
||||||
|
GL12.glDrawRangeElements(param1, param2, param3, param4, param5, param6); |
||||||
|
} |
||||||
|
|
||||||
|
public void glEnable(int param1) { |
||||||
|
GL11.glEnable(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glEnableVertexAttribArray(int param1) { |
||||||
|
GL20.glEnableVertexAttribArray(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGenBuffers(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL15.glGenBuffers(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGenTextures(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL11.glGenTextures(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGetBoolean(int param1, ByteBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL11.glGetBooleanv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGetBufferSubData(int target, long offset, ByteBuffer data) { |
||||||
|
checkLimit(data); |
||||||
|
GL15.glGetBufferSubData(target, offset, data); |
||||||
|
} |
||||||
|
|
||||||
|
public int glGetError() { |
||||||
|
return GL11.glGetError(); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGetInteger(int param1, IntBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL11.glGetIntegerv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGetProgram(int param1, int param2, IntBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL20.glGetProgramiv(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glGetShader(int param1, int param2, IntBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL20.glGetShaderiv(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public String glGetString(int param1) { |
||||||
|
return GL11.glGetString(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public String glGetString(int param1, int param2) { |
||||||
|
return GL30.glGetStringi(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean glIsEnabled(int param1) { |
||||||
|
return GL11.glIsEnabled(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glLineWidth(float param1) { |
||||||
|
GL11.glLineWidth(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glLinkProgram(int param1) { |
||||||
|
GL20.glLinkProgram(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glPixelStorei(int param1, int param2) { |
||||||
|
GL11.glPixelStorei(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glPointSize(float param1) { |
||||||
|
GL11.glPointSize(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glPolygonMode(int param1, int param2) { |
||||||
|
GL11.glPolygonMode(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glPolygonOffset(float param1, float param2) { |
||||||
|
GL11.glPolygonOffset(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glReadBuffer(int param1) { |
||||||
|
GL11.glReadBuffer(param1); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
public void glScissor(int param1, int param2, int param3, int param4) { |
||||||
|
GL11.glScissor(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
public void glStencilFuncSeparate(int param1, int param2, int param3, int param4) { |
||||||
|
GL20.glStencilFuncSeparate(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
public void glStencilOpSeparate(int param1, int param2, int param3, int param4) { |
||||||
|
GL20.glStencilOpSeparate(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
public void glTexParameterf(int param1, int param2, float param3) { |
||||||
|
GL11.glTexParameterf(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glTexParameteri(int param1, int param2, int param3) { |
||||||
|
GL11.glTexParameteri(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform1(int param1, FloatBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform1fv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform1(int param1, IntBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform1iv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform1f(int param1, float param2) { |
||||||
|
GL20.glUniform1f(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform1i(int param1, int param2) { |
||||||
|
GL20.glUniform1i(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform2(int param1, IntBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform2iv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform2(int param1, FloatBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform2fv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform2f(int param1, float param2, float param3) { |
||||||
|
GL20.glUniform2f(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform3(int param1, IntBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform3iv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform3(int param1, FloatBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform3fv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform3f(int param1, float param2, float param3, float param4) { |
||||||
|
GL20.glUniform3f(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform4(int param1, FloatBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform4fv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform4(int param1, IntBuffer param2) { |
||||||
|
checkLimit(param2); |
||||||
|
GL20.glUniform4iv(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniform4f(int param1, float param2, float param3, float param4, float param5) { |
||||||
|
GL20.glUniform4f(param1, param2, param3, param4, param5); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniformMatrix3(int param1, boolean param2, FloatBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL20.glUniformMatrix3fv(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUniformMatrix4(int param1, boolean param2, FloatBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL20.glUniformMatrix4fv(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
public void glUseProgram(int param1) { |
||||||
|
GL20.glUseProgram(param1); |
||||||
|
} |
||||||
|
|
||||||
|
public void glVertexAttribPointer(int param1, int param2, int param3, boolean param4, int param5, long param6) { |
||||||
|
GL20.glVertexAttribPointer(param1, param2, param3, param4, param5, param6); |
||||||
|
} |
||||||
|
|
||||||
|
public void glViewport(int param1, int param2, int param3, int param4) { |
||||||
|
GL11.glViewport(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
public int glGetAttribLocation(int param1, String param2) { |
||||||
|
// NOTE: LWJGL requires null-terminated strings
|
||||||
|
return GL20.glGetAttribLocation(param1, param2 + "\0"); |
||||||
|
} |
||||||
|
|
||||||
|
public int glGetUniformLocation(int param1, String param2) { |
||||||
|
// NOTE: LWJGL requires null-terminated strings
|
||||||
|
return GL20.glGetUniformLocation(param1, param2 + "\0"); |
||||||
|
} |
||||||
|
|
||||||
|
public void glShaderSource(int param1, String[] param2, IntBuffer param3) { |
||||||
|
checkLimit(param3); |
||||||
|
GL20.glShaderSource(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
public String glGetProgramInfoLog(int program, int maxSize) { |
||||||
|
return GL20.glGetProgramInfoLog(program, maxSize); |
||||||
|
} |
||||||
|
|
||||||
|
public String glGetShaderInfoLog(int shader, int maxSize) { |
||||||
|
return GL20.glGetShaderInfoLog(shader, maxSize); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBindFragDataLocation(int param1, int param2, String param3) { |
||||||
|
GL30.glBindFragDataLocation(param1, param2, param3); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBindVertexArray(int param1) { |
||||||
|
GL30.glBindVertexArray(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenVertexArrays(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL30.glGenVertexArrays(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glPatchParameter(int count) { |
||||||
|
GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES,count); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDeleteVertexArrays(IntBuffer arrays) { |
||||||
|
checkLimit(arrays); |
||||||
|
ARBVertexArrayObject.glDeleteVertexArrays(arrays); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.renderer.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"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBufferData(int target, IntBuffer data, int usage) { |
||||||
|
checkLimit(data); |
||||||
|
GL15.glBufferData(target, data, usage); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBufferSubData(int target, long offset, 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); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDrawBuffers(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); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGetMultisample(int pname, int index, 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); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glVertexAttribDivisorARB(int index, int divisor) { |
||||||
|
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object glFenceSync(int condition, int flags) { |
||||||
|
return ARBSync.glFenceSync(condition, flags); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int glClientWaitSync(final Object sync, final int flags, final long timeout) { |
||||||
|
return ARBSync.glClientWaitSync((Long) sync, flags, timeout); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDeleteSync(final Object sync) { |
||||||
|
ARBSync.glDeleteSync((Long) sync); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,130 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.renderer.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 java.nio.Buffer; |
||||||
|
import java.nio.IntBuffer; |
||||||
|
|
||||||
|
/** |
||||||
|
* 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"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, 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); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBindFramebufferEXT(int param1, int param2) { |
||||||
|
EXTFramebufferObject.glBindFramebufferEXT(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBindRenderbufferEXT(int param1, int param2) { |
||||||
|
EXTFramebufferObject.glBindRenderbufferEXT(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int glCheckFramebufferStatusEXT(int param1) { |
||||||
|
return EXTFramebufferObject.glCheckFramebufferStatusEXT(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDeleteFramebuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
EXTFramebufferObject.glDeleteFramebuffersEXT(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDeleteRenderbuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
EXTFramebufferObject.glDeleteRenderbuffersEXT(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) { |
||||||
|
EXTFramebufferObject.glFramebufferRenderbufferEXT(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) { |
||||||
|
EXTFramebufferObject.glFramebufferTexture2DEXT(param1, param2, param3, param4, param5); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenFramebuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
EXTFramebufferObject.glGenFramebuffersEXT(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenRenderbuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
EXTFramebufferObject.glGenRenderbuffersEXT(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenerateMipmapEXT(int param1) { |
||||||
|
EXTFramebufferObject.glGenerateMipmapEXT(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) { |
||||||
|
EXTFramebufferObject.glRenderbufferStorageEXT(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.renderer.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; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements GLFbo via OpenGL3+. |
||||||
|
* |
||||||
|
* @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"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, 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); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBindFramebufferEXT(int param1, int param2) { |
||||||
|
GL30.glBindFramebuffer(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glBindRenderbufferEXT(int param1, int param2) { |
||||||
|
GL30.glBindRenderbuffer(param1, param2); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int glCheckFramebufferStatusEXT(int param1) { |
||||||
|
return GL30.glCheckFramebufferStatus(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDeleteFramebuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL30.glDeleteFramebuffers(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glDeleteRenderbuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL30.glDeleteRenderbuffers(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) { |
||||||
|
GL30.glFramebufferRenderbuffer(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) { |
||||||
|
GL30.glFramebufferTexture2D(param1, param2, param3, param4, param5); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenFramebuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL30.glGenFramebuffers(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenRenderbuffersEXT(IntBuffer param1) { |
||||||
|
checkLimit(param1); |
||||||
|
GL30.glGenRenderbuffers(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glGenerateMipmapEXT(int param1) { |
||||||
|
GL30.glGenerateMipmap(param1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) { |
||||||
|
GL30.glRenderbufferStorage(param1, param2, param3, param4); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,263 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.jme3.system.lwjgl; |
||||||
|
|
||||||
|
import com.jme3.input.lwjgl.GlfwJoystickInput; |
||||||
|
import com.jme3.input.lwjgl.GlfwKeyInput; |
||||||
|
import com.jme3.input.lwjgl.GlfwMouseInput; |
||||||
|
import com.jme3.renderer.Renderer; |
||||||
|
import com.jme3.renderer.RendererException; |
||||||
|
import com.jme3.renderer.lwjgl.LwjglGL; |
||||||
|
import com.jme3.renderer.lwjgl.LwjglGLExt; |
||||||
|
import com.jme3.renderer.lwjgl.LwjglGLFboEXT; |
||||||
|
import com.jme3.renderer.lwjgl.LwjglGLFboGL3; |
||||||
|
import com.jme3.renderer.opengl.*; |
||||||
|
import com.jme3.renderer.opengl.GL; |
||||||
|
import com.jme3.system.*; |
||||||
|
import org.lwjgl.Sys; |
||||||
|
import org.lwjgl.glfw.GLFW; |
||||||
|
import org.lwjgl.opengl.*; |
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL.createCapabilities; |
||||||
|
import static org.lwjgl.opengl.GL11.GL_TRUE; |
||||||
|
import static org.lwjgl.opengl.GL11.glGetInteger; |
||||||
|
|
||||||
|
/** |
||||||
|
* A LWJGL implementation of a graphics context. |
||||||
|
*/ |
||||||
|
public abstract class LwjglContext implements JmeContext { |
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(LwjglContext.class.getName()); |
||||||
|
|
||||||
|
protected static final String THREAD_NAME = "jME3 Main"; |
||||||
|
|
||||||
|
protected AtomicBoolean created = new AtomicBoolean(false); |
||||||
|
protected AtomicBoolean renderable = new AtomicBoolean(false); |
||||||
|
protected final Object createdLock = new Object(); |
||||||
|
|
||||||
|
protected AppSettings settings = new AppSettings(true); |
||||||
|
protected Renderer renderer; |
||||||
|
protected GlfwKeyInput keyInput; |
||||||
|
protected GlfwMouseInput mouseInput; |
||||||
|
protected GlfwJoystickInput joyInput; |
||||||
|
protected Timer timer; |
||||||
|
protected SystemListener listener; |
||||||
|
|
||||||
|
public void setSystemListener(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[]{Sys.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") == GL_TRUE) { |
||||||
|
return glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES); |
||||||
|
} else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample") == GL_TRUE) { |
||||||
|
return glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT); |
||||||
|
} |
||||||
|
|
||||||
|
return Integer.MAX_VALUE; |
||||||
|
} |
||||||
|
|
||||||
|
protected void loadNatives() { |
||||||
|
if (JmeSystem.isLowPermissions()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if ("LWJGL".equals(settings.getAudioRenderer())) { |
||||||
|
NativeLibraryLoader.loadNativeLibrary("openal-lwjgl3", true); |
||||||
|
} |
||||||
|
|
||||||
|
if (NativeLibraryLoader.isUsingNativeBullet()) { |
||||||
|
NativeLibraryLoader.loadNativeLibrary("bulletjme", true); |
||||||
|
} |
||||||
|
|
||||||
|
NativeLibraryLoader.loadNativeLibrary("lwjgl3", true); |
||||||
|
} |
||||||
|
|
||||||
|
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}); |
||||||
|
|
||||||
|
samples = supportedSamples; |
||||||
|
} |
||||||
|
} |
||||||
|
return samples; |
||||||
|
} |
||||||
|
|
||||||
|
protected void initContextFirstTime() { |
||||||
|
final GLCapabilities capabilities = createCapabilities(settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)); |
||||||
|
|
||||||
|
if (!capabilities.OpenGL20) { |
||||||
|
throw new RendererException("OpenGL 2.0 or higher is required for jMonkeyEngine"); |
||||||
|
} |
||||||
|
|
||||||
|
if (settings.getRenderer().equals(AppSettings.LWJGL_OPENGL2) |
||||||
|
|| settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)) { |
||||||
|
GL gl = new LwjglGL(); |
||||||
|
GLExt glext = new LwjglGLExt(); |
||||||
|
GLFbo glfbo; |
||||||
|
|
||||||
|
if (capabilities.OpenGL30) { |
||||||
|
glfbo = new LwjglGLFboGL3(); |
||||||
|
} else { |
||||||
|
glfbo = new LwjglGLFboEXT(); |
||||||
|
} |
||||||
|
|
||||||
|
if (settings.getBoolean("GraphicsDebug")) { |
||||||
|
gl = new GLDebugDesktop(gl, glext, glfbo); |
||||||
|
glext = (GLExt) gl; |
||||||
|
glfbo = (GLFbo) gl; |
||||||
|
} |
||||||
|
|
||||||
|
if (settings.getBoolean("GraphicsTiming")) { |
||||||
|
GLTimingState timingState = new GLTimingState(); |
||||||
|
gl = (GL) GLTiming.createGLTiming(gl, timingState, GL.class, GL2.class, GL3.class, GL4.class); |
||||||
|
glext = (GLExt) GLTiming.createGLTiming(glext, timingState, GLExt.class); |
||||||
|
glfbo = (GLFbo) GLTiming.createGLTiming(glfbo, timingState, GLFbo.class); |
||||||
|
} |
||||||
|
|
||||||
|
if (settings.getBoolean("GraphicsTrace")) { |
||||||
|
gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class); |
||||||
|
glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class); |
||||||
|
glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class); |
||||||
|
} |
||||||
|
|
||||||
|
renderer = new GLRenderer(gl, glext, glfbo); |
||||||
|
renderer.initialize(); |
||||||
|
} else { |
||||||
|
throw new UnsupportedOperationException("Unsupported renderer: " + settings.getRenderer()); |
||||||
|
} |
||||||
|
|
||||||
|
if (capabilities.GL_ARB_debug_output && settings.getBoolean("GraphicsDebug")) { |
||||||
|
ARBDebugOutput.glDebugMessageCallbackARB(new LwjglGLDebugOutputHandler(), 0); // User param is zero. Not sure what we could use that for.
|
||||||
|
} |
||||||
|
|
||||||
|
renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); |
||||||
|
renderer.setLinearizeSrgbImages(settings.getGammaCorrection()); |
||||||
|
|
||||||
|
// Init input
|
||||||
|
if (keyInput != null) { |
||||||
|
keyInput.initialize(); |
||||||
|
} |
||||||
|
|
||||||
|
if (mouseInput != null) { |
||||||
|
mouseInput.initialize(); |
||||||
|
} |
||||||
|
|
||||||
|
if (joyInput != null) { |
||||||
|
joyInput.initialize(); |
||||||
|
} |
||||||
|
|
||||||
|
renderable.set(true); |
||||||
|
} |
||||||
|
|
||||||
|
public void internalDestroy() { |
||||||
|
renderer = null; |
||||||
|
timer = null; |
||||||
|
renderable.set(false); |
||||||
|
synchronized (createdLock) { |
||||||
|
created.set(false); |
||||||
|
createdLock.notifyAll(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void internalCreate() { |
||||||
|
synchronized (createdLock) { |
||||||
|
created.set(true); |
||||||
|
createdLock.notifyAll(); |
||||||
|
} |
||||||
|
|
||||||
|
initContextFirstTime(); |
||||||
|
} |
||||||
|
|
||||||
|
public void create() { |
||||||
|
create(false); |
||||||
|
} |
||||||
|
|
||||||
|
public void destroy() { |
||||||
|
destroy(false); |
||||||
|
} |
||||||
|
|
||||||
|
protected void waitFor(boolean createdVal) { |
||||||
|
synchronized (createdLock) { |
||||||
|
while (created.get() != createdVal) { |
||||||
|
try { |
||||||
|
createdLock.wait(); |
||||||
|
} catch (InterruptedException ex) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCreated() { |
||||||
|
return created.get(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isRenderable() { |
||||||
|
return renderable.get(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setSettings(AppSettings settings) { |
||||||
|
this.settings.copyFrom(settings); |
||||||
|
} |
||||||
|
|
||||||
|
public AppSettings getSettings() { |
||||||
|
return settings; |
||||||
|
} |
||||||
|
|
||||||
|
public Renderer getRenderer() { |
||||||
|
return renderer; |
||||||
|
} |
||||||
|
|
||||||
|
public Timer getTimer() { |
||||||
|
return timer; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.system.lwjgl; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Daniel Johansson |
||||||
|
*/ |
||||||
|
public class LwjglDisplay extends LwjglWindow { |
||||||
|
|
||||||
|
public LwjglDisplay() { |
||||||
|
super(Type.Display); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2015 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.system.lwjgl; |
||||||
|
|
||||||
|
import org.lwjgl.opengl.ARBDebugOutput; |
||||||
|
import org.lwjgl.opengl.GLDebugMessageARBCallback; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
|
||||||
|
class LwjglGLDebugOutputHandler extends GLDebugMessageARBCallback { |
||||||
|
|
||||||
|
private static final HashMap<Integer, String> constMap = new HashMap<Integer, String>(); |
||||||
|
private static final String MESSAGE_FORMAT = |
||||||
|
"[JME3] OpenGL debug message\r\n" + |
||||||
|
" ID: %d\r\n" + |
||||||
|
" Source: %s\r\n" + |
||||||
|
" Type: %s\r\n" + |
||||||
|
" Severity: %s\r\n" + |
||||||
|
" Message: %s"; |
||||||
|
|
||||||
|
static { |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SOURCE_API_ARB, "API"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SOURCE_APPLICATION_ARB, "APPLICATION"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SOURCE_OTHER_ARB, "OTHER"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SOURCE_SHADER_COMPILER_ARB, "SHADER_COMPILER"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SOURCE_THIRD_PARTY_ARB, "THIRD_PARTY"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, "WINDOW_SYSTEM"); |
||||||
|
|
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, "DEPRECATED_BEHAVIOR"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_TYPE_ERROR_ARB, "ERROR"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_TYPE_OTHER_ARB, "OTHER"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_TYPE_PERFORMANCE_ARB, "PERFORMANCE"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_TYPE_PORTABILITY_ARB, "PORTABILITY"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, "UNDEFINED_BEHAVIOR"); |
||||||
|
|
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB, "HIGH"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SEVERITY_MEDIUM_ARB, "MEDIUM"); |
||||||
|
constMap.put(ARBDebugOutput.GL_DEBUG_SEVERITY_LOW_ARB, "LOW"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void invoke(int source, int type, int id, int severity, int length, long message, long userParam) { |
||||||
|
String sourceStr = constMap.get(source); |
||||||
|
String typeStr = constMap.get(type); |
||||||
|
String severityStr = constMap.get(severity); |
||||||
|
|
||||||
|
System.err.println(String.format(MESSAGE_FORMAT, id, sourceStr, typeStr, severityStr, message)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.system.lwjgl; |
||||||
|
|
||||||
|
import com.jme3.system.JmeContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Daniel Johansson |
||||||
|
*/ |
||||||
|
public class LwjglOffscreenBuffer extends LwjglWindow { |
||||||
|
|
||||||
|
public LwjglOffscreenBuffer() { |
||||||
|
super(JmeContext.Type.OffscreenSurface); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,509 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.jme3.system.lwjgl; |
||||||
|
|
||||||
|
import com.jme3.input.JoyInput; |
||||||
|
import com.jme3.input.KeyInput; |
||||||
|
import com.jme3.input.MouseInput; |
||||||
|
import com.jme3.input.TouchInput; |
||||||
|
import com.jme3.input.lwjgl.GlfwJoystickInput; |
||||||
|
import com.jme3.input.lwjgl.GlfwKeyInput; |
||||||
|
import com.jme3.input.lwjgl.GlfwMouseInput; |
||||||
|
import com.jme3.system.AppSettings; |
||||||
|
import com.jme3.system.JmeContext; |
||||||
|
import com.jme3.system.JmeSystem; |
||||||
|
import com.jme3.system.NanoTimer; |
||||||
|
import org.lwjgl.Sys; |
||||||
|
import org.lwjgl.glfw.*; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.util.concurrent.atomic.AtomicBoolean; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*; |
||||||
|
import static org.lwjgl.opengl.GL11.GL_FALSE; |
||||||
|
import static org.lwjgl.opengl.GL11.GL_TRUE; |
||||||
|
import static org.lwjgl.system.MemoryUtil.NULL; |
||||||
|
|
||||||
|
/** |
||||||
|
* A wrapper class over the GLFW framework in LWJGL 3. |
||||||
|
* |
||||||
|
* @author Daniel Johansson |
||||||
|
*/ |
||||||
|
public abstract class LwjglWindow extends LwjglContext implements Runnable { |
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(LwjglWindow.class.getName()); |
||||||
|
|
||||||
|
protected AtomicBoolean needClose = new AtomicBoolean(false); |
||||||
|
protected final AtomicBoolean needRestart = new AtomicBoolean(false); |
||||||
|
protected boolean wasActive = false; |
||||||
|
protected boolean autoFlush = true; |
||||||
|
protected boolean allowSwapBuffers = false; |
||||||
|
private long window = -1; |
||||||
|
private final JmeContext.Type type; |
||||||
|
private int frameRateLimit = -1; |
||||||
|
private double frameSleepTime; |
||||||
|
|
||||||
|
private GLFWErrorCallback errorCallback; |
||||||
|
private GLFWWindowSizeCallback windowSizeCallback; |
||||||
|
private GLFWWindowFocusCallback windowFocusCallback; |
||||||
|
|
||||||
|
public LwjglWindow(final JmeContext.Type type) { |
||||||
|
if (!JmeContext.Type.Display.equals(type) && !JmeContext.Type.OffscreenSurface.equals(type) && !JmeContext.Type.Canvas.equals(type)) { |
||||||
|
throw new IllegalArgumentException("Unsupported type '" + type.name() + "' provided"); |
||||||
|
} |
||||||
|
|
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return Type.Display or Type.Canvas |
||||||
|
*/ |
||||||
|
public JmeContext.Type getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the title if its a windowed display |
||||||
|
* |
||||||
|
* @param title |
||||||
|
*/ |
||||||
|
public void setTitle(final String title) { |
||||||
|
if (created.get() && window != -1) { |
||||||
|
glfwSetWindowTitle(window, title); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Restart if its a windowed or full-screen display. |
||||||
|
*/ |
||||||
|
public void restart() { |
||||||
|
if (created.get()) { |
||||||
|
needRestart.set(true); |
||||||
|
} else { |
||||||
|
LOGGER.warning("Display is not created, cannot restart window."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Apply the settings, changing resolution, etc. |
||||||
|
* |
||||||
|
* @param settings |
||||||
|
*/ |
||||||
|
protected void createContext(final AppSettings settings) { |
||||||
|
glfwSetErrorCallback(errorCallback = new GLFWErrorCallback() { |
||||||
|
@Override |
||||||
|
public void invoke(int error, long description) { |
||||||
|
final String message = Callbacks.errorCallbackDescriptionString(description); |
||||||
|
listener.handleError(message, new Exception(message)); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
if (glfwInit() != GL_TRUE) { |
||||||
|
throw new IllegalStateException("Unable to initialize GLFW"); |
||||||
|
} |
||||||
|
|
||||||
|
glfwDefaultWindowHints(); |
||||||
|
glfwWindowHint(GLFW_VISIBLE, GL_FALSE); |
||||||
|
|
||||||
|
// TODO: Add support for monitor selection
|
||||||
|
long monitor = NULL; |
||||||
|
|
||||||
|
if (settings.isFullscreen()) { |
||||||
|
monitor = glfwGetPrimaryMonitor(); |
||||||
|
} |
||||||
|
|
||||||
|
final ByteBuffer videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); |
||||||
|
|
||||||
|
if (settings.getWidth() <= 0 || settings.getHeight() <= 0) { |
||||||
|
settings.setResolution(GLFWvidmode.width(videoMode), GLFWvidmode.height(videoMode)); |
||||||
|
} |
||||||
|
|
||||||
|
window = glfwCreateWindow(settings.getWidth(), settings.getHeight(), settings.getTitle(), monitor, NULL); |
||||||
|
|
||||||
|
if (window == NULL) { |
||||||
|
throw new RuntimeException("Failed to create the GLFW window"); |
||||||
|
} |
||||||
|
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GL_TRUE : GL_FALSE); |
||||||
|
glfwWindowHint(GLFW_DEPTH_BITS, settings.getDepthBits()); |
||||||
|
glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits()); |
||||||
|
glfwWindowHint(GLFW_SAMPLES, settings.getSamples()); |
||||||
|
glfwWindowHint(GLFW_STEREO, settings.useStereo3D() ? GL_TRUE : GL_FALSE); |
||||||
|
glfwWindowHint(GLFW_REFRESH_RATE, settings.getFrequency()); |
||||||
|
|
||||||
|
// Not sure how else to support bits per pixel
|
||||||
|
if (settings.getBitsPerPixel() == 24) { |
||||||
|
glfwWindowHint(GLFW_RED_BITS, 8); |
||||||
|
glfwWindowHint(GLFW_GREEN_BITS, 8); |
||||||
|
glfwWindowHint(GLFW_BLUE_BITS, 8); |
||||||
|
} else if (settings.getBitsPerPixel() == 16) { |
||||||
|
glfwWindowHint(GLFW_RED_BITS, 5); |
||||||
|
glfwWindowHint(GLFW_GREEN_BITS, 6); |
||||||
|
glfwWindowHint(GLFW_BLUE_BITS, 5); |
||||||
|
} |
||||||
|
|
||||||
|
glfwWindowHint(GLFW_ALPHA_BITS, settings.getAlphaBits()); |
||||||
|
|
||||||
|
glfwSetWindowFocusCallback(window, windowFocusCallback = new GLFWWindowFocusCallback() { |
||||||
|
@Override |
||||||
|
public void invoke(final long window, final int focused) { |
||||||
|
final boolean focus = (focused == GL_TRUE); |
||||||
|
|
||||||
|
if (wasActive != focus) { |
||||||
|
if (!wasActive) { |
||||||
|
listener.gainFocus(); |
||||||
|
timer.reset(); |
||||||
|
} else { |
||||||
|
listener.loseFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
wasActive = !wasActive; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Center the window
|
||||||
|
if (!settings.isFullscreen() && Type.Display.equals(type)) { |
||||||
|
glfwSetWindowPos(window, (GLFWvidmode.width(videoMode) - settings.getWidth()) / 2, (GLFWvidmode.height(videoMode) - settings.getHeight()) / 2); |
||||||
|
} |
||||||
|
|
||||||
|
// Make the OpenGL context current
|
||||||
|
glfwMakeContextCurrent(window); |
||||||
|
|
||||||
|
// Enable vsync
|
||||||
|
if (settings.isVSync()) { |
||||||
|
glfwSwapInterval(1); |
||||||
|
} else { |
||||||
|
glfwSwapInterval(0); |
||||||
|
} |
||||||
|
|
||||||
|
// Make the window visible
|
||||||
|
if (Type.Display.equals(type)) { |
||||||
|
glfwShowWindow(window); |
||||||
|
} |
||||||
|
|
||||||
|
// Add a resize callback which delegates to the listener
|
||||||
|
glfwSetWindowSizeCallback(window, windowSizeCallback = new GLFWWindowSizeCallback() { |
||||||
|
@Override |
||||||
|
public void invoke(final long window, final int width, final int height) { |
||||||
|
settings.setResolution(width, height); |
||||||
|
listener.reshape(width, height); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
allowSwapBuffers = settings.isSwapBuffers(); |
||||||
|
|
||||||
|
// TODO: When GLFW 3.2 is released and included in LWJGL 3.x then we should hopefully be able to set the window icon.
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Destroy the context. |
||||||
|
*/ |
||||||
|
protected void destroyContext() { |
||||||
|
try { |
||||||
|
if (renderer != null) { |
||||||
|
renderer.cleanup(); |
||||||
|
} |
||||||
|
|
||||||
|
errorCallback.release(); |
||||||
|
windowSizeCallback.release(); |
||||||
|
windowFocusCallback.release(); |
||||||
|
|
||||||
|
if (window != 0) { |
||||||
|
glfwDestroyWindow(window); |
||||||
|
} |
||||||
|
} catch (Exception ex) { |
||||||
|
listener.handleError("Failed to destroy context", ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void create(boolean waitFor) { |
||||||
|
if (created.get()) { |
||||||
|
LOGGER.warning("create() called when display is already created!"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
new Thread(this, THREAD_NAME).start(); |
||||||
|
|
||||||
|
if (waitFor) { |
||||||
|
waitFor(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Does LWJGL display initialization in the OpenGL thread |
||||||
|
*/ |
||||||
|
protected boolean initInThread() { |
||||||
|
try { |
||||||
|
if (!JmeSystem.isLowPermissions()) { |
||||||
|
// Enable uncaught exception handler only for current thread
|
||||||
|
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { |
||||||
|
public void uncaughtException(Thread thread, Throwable thrown) { |
||||||
|
listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown); |
||||||
|
if (needClose.get()) { |
||||||
|
// listener.handleError() has requested the
|
||||||
|
// context to close. Satisfy request.
|
||||||
|
deinitInThread(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
timer = new NanoTimer(); |
||||||
|
|
||||||
|
// For canvas, this will create a pbuffer,
|
||||||
|
// allowing us to query information.
|
||||||
|
// When the canvas context becomes available, it will
|
||||||
|
// be replaced seamlessly.
|
||||||
|
createContext(settings); |
||||||
|
printContextInitInfo(); |
||||||
|
|
||||||
|
created.set(true); |
||||||
|
super.internalCreate(); |
||||||
|
} catch (Exception ex) { |
||||||
|
try { |
||||||
|
if (window != -1) { |
||||||
|
glfwDestroyWindow(window); |
||||||
|
} |
||||||
|
} catch (Exception ex2) { |
||||||
|
LOGGER.log(Level.WARNING, null, ex2); |
||||||
|
} |
||||||
|
|
||||||
|
listener.handleError("Failed to create display", ex); |
||||||
|
return false; // if we failed to create display, do not continue
|
||||||
|
} |
||||||
|
|
||||||
|
listener.initialize(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* execute one iteration of the render loop in the OpenGL thread |
||||||
|
*/ |
||||||
|
protected void runLoop() { |
||||||
|
// If a restart is required, lets recreate the context.
|
||||||
|
if (needRestart.getAndSet(false)) { |
||||||
|
try { |
||||||
|
createContext(settings); |
||||||
|
} catch (Exception ex) { |
||||||
|
LOGGER.log(Level.SEVERE, "Failed to set display settings!", ex); |
||||||
|
} |
||||||
|
|
||||||
|
LOGGER.fine("Display restarted."); |
||||||
|
} |
||||||
|
|
||||||
|
if (!created.get()) { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
|
||||||
|
listener.update(); |
||||||
|
|
||||||
|
// All this does is call swap buffers
|
||||||
|
// If the canvas is not active, there's no need to waste time
|
||||||
|
// doing that ..
|
||||||
|
if (renderable.get()) { |
||||||
|
// calls swap buffers, etc.
|
||||||
|
try { |
||||||
|
if (allowSwapBuffers && autoFlush) { |
||||||
|
glfwSwapBuffers(window); |
||||||
|
} |
||||||
|
} catch (Throwable ex) { |
||||||
|
listener.handleError("Error while swapping buffers", ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
glfwPollEvents(); |
||||||
|
|
||||||
|
// Subclasses just call GLObjectManager clean up objects here
|
||||||
|
// it is safe .. for now.
|
||||||
|
if (renderer != null) { |
||||||
|
renderer.postFrame(); |
||||||
|
} |
||||||
|
|
||||||
|
if (autoFlush) { |
||||||
|
if (frameRateLimit != getSettings().getFrameRate()) { |
||||||
|
setFrameRateLimit(getSettings().getFrameRate()); |
||||||
|
} |
||||||
|
} else if (frameRateLimit != 20) { |
||||||
|
setFrameRateLimit(20); |
||||||
|
} |
||||||
|
|
||||||
|
// If software frame rate limiting has been asked for, lets calculate sleep time based on a base value calculated
|
||||||
|
// from 1000 / frameRateLimit in milliseconds subtracting the time it has taken to render last frame.
|
||||||
|
// This gives an approximate limit within 3 fps of the given frame rate limit.
|
||||||
|
if (frameRateLimit > 0) { |
||||||
|
final double sleep = frameSleepTime - (timer.getTimePerFrame() / 1000.0); |
||||||
|
final long sleepMillis = (long) sleep; |
||||||
|
final int additionalNanos = (int) ((sleep - sleepMillis) * 1000000.0); |
||||||
|
|
||||||
|
if (sleepMillis >= 0 && additionalNanos >= 0) { |
||||||
|
try { |
||||||
|
Thread.sleep(sleepMillis, additionalNanos); |
||||||
|
} catch (InterruptedException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void setFrameRateLimit(int frameRateLimit) { |
||||||
|
this.frameRateLimit = frameRateLimit; |
||||||
|
frameSleepTime = 1000.0 / this.frameRateLimit; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* De-initialize in the OpenGL thread. |
||||||
|
*/ |
||||||
|
|
||||||
|
protected void deinitInThread() { |
||||||
|
destroyContext(); |
||||||
|
|
||||||
|
listener.destroy(); |
||||||
|
LOGGER.fine("Display destroyed."); |
||||||
|
super.internalDestroy(); |
||||||
|
} |
||||||
|
|
||||||
|
public void run() { |
||||||
|
if (listener == null) { |
||||||
|
throw new IllegalStateException("SystemListener is not set on context!" |
||||||
|
+ "Must set with JmeContext.setSystemListener()."); |
||||||
|
} |
||||||
|
|
||||||
|
loadNatives(); |
||||||
|
LOGGER.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion()); |
||||||
|
|
||||||
|
if (!initInThread()) { |
||||||
|
LOGGER.log(Level.SEVERE, "Display initialization failed. Cannot continue."); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
while (true) { |
||||||
|
if (glfwWindowShouldClose(window) == GL_TRUE) { |
||||||
|
listener.requestClose(false); |
||||||
|
} |
||||||
|
|
||||||
|
runLoop(); |
||||||
|
|
||||||
|
if (needClose.get()) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
deinitInThread(); |
||||||
|
} |
||||||
|
|
||||||
|
public JoyInput getJoyInput() { |
||||||
|
if (joyInput == null) { |
||||||
|
joyInput = new GlfwJoystickInput(); |
||||||
|
} |
||||||
|
return joyInput; |
||||||
|
} |
||||||
|
|
||||||
|
public MouseInput getMouseInput() { |
||||||
|
if (mouseInput == null) { |
||||||
|
mouseInput = new GlfwMouseInput(this); |
||||||
|
} |
||||||
|
return mouseInput; |
||||||
|
} |
||||||
|
|
||||||
|
public KeyInput getKeyInput() { |
||||||
|
if (keyInput == null) { |
||||||
|
keyInput = new GlfwKeyInput(this); |
||||||
|
} |
||||||
|
|
||||||
|
return keyInput; |
||||||
|
} |
||||||
|
|
||||||
|
public TouchInput getTouchInput() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAutoFlushFrames(boolean enabled) { |
||||||
|
this.autoFlush = enabled; |
||||||
|
} |
||||||
|
|
||||||
|
public void destroy(boolean waitFor) { |
||||||
|
needClose.set(true); |
||||||
|
|
||||||
|
if (waitFor) { |
||||||
|
waitFor(false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public long getWindowHandle() { |
||||||
|
return window; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// TODO: Implement support for window icon when GLFW supports it.
|
||||||
|
|
||||||
|
private ByteBuffer[] imagesToByteBuffers(Object[] images) { |
||||||
|
ByteBuffer[] out = new ByteBuffer[images.length]; |
||||||
|
for (int i = 0; i < images.length; i++) { |
||||||
|
BufferedImage image = (BufferedImage) images[i]; |
||||||
|
out[i] = imageToByteBuffer(image); |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
private ByteBuffer imageToByteBuffer(BufferedImage image) { |
||||||
|
if (image.getType() != BufferedImage.TYPE_INT_ARGB_PRE) { |
||||||
|
BufferedImage convertedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); |
||||||
|
Graphics2D g = convertedImage.createGraphics(); |
||||||
|
double width = image.getWidth() * (double) 1; |
||||||
|
double height = image.getHeight() * (double) 1; |
||||||
|
g.drawImage(image, (int) ((convertedImage.getWidth() - width) / 2), |
||||||
|
(int) ((convertedImage.getHeight() - height) / 2), |
||||||
|
(int) (width), (int) (height), null); |
||||||
|
g.dispose(); |
||||||
|
image = convertedImage; |
||||||
|
} |
||||||
|
|
||||||
|
byte[] imageBuffer = new byte[image.getWidth() * image.getHeight() * 4]; |
||||||
|
int counter = 0; |
||||||
|
for (int i = 0; i < image.getHeight(); i++) { |
||||||
|
for (int j = 0; j < image.getWidth(); j++) { |
||||||
|
int colorSpace = image.getRGB(j, i); |
||||||
|
imageBuffer[counter + 0] = (byte) ((colorSpace << 8) >> 24); |
||||||
|
imageBuffer[counter + 1] = (byte) ((colorSpace << 16) >> 24); |
||||||
|
imageBuffer[counter + 2] = (byte) ((colorSpace << 24) >> 24); |
||||||
|
imageBuffer[counter + 3] = (byte) (colorSpace >> 24); |
||||||
|
counter += 4; |
||||||
|
} |
||||||
|
} |
||||||
|
return ByteBuffer.wrap(imageBuffer); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue