Remove jogl (#1339)
* Remove JOGL * Update build.gradle * Update AppSettings.java * Update settings.gradle * Update TestMultipleApplications.java * Update build.gradle * Update JmeDesktopSystem.java * Update AppSettings.java * Update package-info.java * Update TestApplet.java * Update HelloOpenCL.java * Update TestContextSwitching.java * Update TestOpenCLLibraries.java * Update TestVertexBufferSharing.java * Update TestWriteToTexture.java * Update TestMultiPostWater.java Co-authored-by: Mike Burnett <mikejme4@gmail.com>master
parent
89df7909d3
commit
6c5611d3e2
@ -1,12 +0,0 @@ |
|||||||
if (!hasProperty('mainClass')) { |
|
||||||
ext.mainClass = '' |
|
||||||
} |
|
||||||
|
|
||||||
dependencies { |
|
||||||
compile project(':jme3-core') |
|
||||||
compile project(':jme3-desktop') |
|
||||||
compile 'org.jogamp.gluegen:gluegen-rt-main:2.3.2' |
|
||||||
compile 'org.jogamp.jogl:jogl-all-main:2.3.2' |
|
||||||
compile 'org.jogamp.joal:joal-main:2.3.2' |
|
||||||
compile 'org.jogamp.jocl:jocl-main:2.3.2' |
|
||||||
} |
|
@ -1,158 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.audio.joal; |
|
||||||
|
|
||||||
import com.jme3.util.BufferUtils; |
|
||||||
import com.jogamp.openal.AL; |
|
||||||
import com.jogamp.openal.ALFactory; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.nio.FloatBuffer; |
|
||||||
import java.nio.IntBuffer; |
|
||||||
|
|
||||||
/** |
|
||||||
* Exposes OpenAL functions via JOAL. |
|
||||||
* |
|
||||||
* @author Kirill Vainer |
|
||||||
*/ |
|
||||||
public final class JoalAL implements com.jme3.audio.openal.AL { |
|
||||||
|
|
||||||
private final AL joalAl; |
|
||||||
|
|
||||||
public JoalAL() { |
|
||||||
this.joalAl = ALFactory.getAL(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String alGetString(int parameter) { |
|
||||||
return joalAl.alGetString(parameter); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int alGenSources() { |
|
||||||
IntBuffer ib = BufferUtils.createIntBuffer(1); |
|
||||||
joalAl.alGenSources(1, ib); |
|
||||||
return ib.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int alGetError() { |
|
||||||
return joalAl.alGetError(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alDeleteSources(int numSources, IntBuffer sources) { |
|
||||||
joalAl.alDeleteSources(numSources, sources); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alGenBuffers(int numBuffers, IntBuffer buffers) { |
|
||||||
joalAl.alGenBuffers(numBuffers, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alDeleteBuffers(int numBuffers, IntBuffer buffers) { |
|
||||||
joalAl.alDeleteBuffers(numBuffers, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourceStop(int source) { |
|
||||||
joalAl.alSourceStop(source); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourcei(int source, int param, int value) { |
|
||||||
joalAl.alSourcei(source, param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alBufferData(int buffer, int format, ByteBuffer data, int size, int frequency) { |
|
||||||
joalAl.alBufferData(buffer, format, data, size, frequency); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourcePlay(int source) { |
|
||||||
joalAl.alSourcePlay(source); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourcePause(int source) { |
|
||||||
joalAl.alSourcePause(source); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourcef(int source, int param, float value) { |
|
||||||
joalAl.alSourcef(source, param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSource3f(int source, int param, float value1, float value2, float value3) { |
|
||||||
joalAl.alSource3f(source, param, value1, value2, value3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int alGetSourcei(int source, int param) { |
|
||||||
IntBuffer ib = BufferUtils.createIntBuffer(1); |
|
||||||
joalAl.alGetSourcei(source, param, ib); |
|
||||||
return ib.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourceUnqueueBuffers(int source, int numBuffers, IntBuffer buffers) { |
|
||||||
joalAl.alSourceUnqueueBuffers(source, numBuffers, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSourceQueueBuffers(int source, int numBuffers, IntBuffer buffers) { |
|
||||||
joalAl.alSourceQueueBuffers(source, numBuffers, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alListener(int param, FloatBuffer data) { |
|
||||||
joalAl.alListenerfv(param, data); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alListenerf(int param, float value) { |
|
||||||
joalAl.alListenerf(param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alListener3f(int param, float value1, float value2, float value3) { |
|
||||||
joalAl.alListener3f(param, value1, value2, value3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alSource3i(int source, int param, int value1, int value2, int value3) { |
|
||||||
joalAl.alSource3i(source, param, value1, value2, value3); |
|
||||||
} |
|
||||||
} |
|
@ -1,152 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.audio.joal; |
|
||||||
|
|
||||||
import com.jogamp.openal.ALCcontext; |
|
||||||
import com.jogamp.openal.ALCdevice; |
|
||||||
import com.jogamp.openal.ALFactory; |
|
||||||
import com.jogamp.openal.util.ALut; |
|
||||||
import java.nio.IntBuffer; |
|
||||||
|
|
||||||
/** |
|
||||||
* Exposes ALC functions via JOAL. |
|
||||||
* |
|
||||||
* @author Kirill Vainer |
|
||||||
*/ |
|
||||||
public final class JoalALC implements com.jme3.audio.openal.ALC { |
|
||||||
|
|
||||||
private final com.jogamp.openal.ALC joalAlc; |
|
||||||
|
|
||||||
public JoalALC() { |
|
||||||
joalAlc = ALFactory.getALC(); |
|
||||||
} |
|
||||||
|
|
||||||
private ALCdevice getALCDevice() { |
|
||||||
ALCcontext ctx = joalAlc.alcGetCurrentContext(); |
|
||||||
|
|
||||||
if (ctx == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
ALCdevice device = joalAlc.alcGetContextsDevice(ctx); |
|
||||||
|
|
||||||
if (device == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
return device; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void createALC() { |
|
||||||
ALut.alutInit(); |
|
||||||
|
|
||||||
/* |
|
||||||
// Get handle to default device.
|
|
||||||
ALCdevice device = joalAlc.alcOpenDevice(null); |
|
||||||
if (device == null) { |
|
||||||
throw new ALException("Error opening default OpenAL device"); |
|
||||||
} |
|
||||||
|
|
||||||
// Create audio context.
|
|
||||||
ALCcontext context = joalAlc.alcCreateContext(device, null); |
|
||||||
if (context == null) { |
|
||||||
throw new ALException("Error creating OpenAL context"); |
|
||||||
} |
|
||||||
|
|
||||||
// Set active context.
|
|
||||||
if (!joalAlc.alcMakeContextCurrent(context)) { |
|
||||||
throw new ALException("Failed to make OpenAL context current"); |
|
||||||
} |
|
||||||
|
|
||||||
// Check for an error.
|
|
||||||
if (joalAlc.alcGetError(device) != com.jogamp.openal.ALC.ALC_NO_ERROR) { |
|
||||||
throw new ALException("Error making OpenAL context current"); |
|
||||||
} |
|
||||||
*/ |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroyALC() { |
|
||||||
/* |
|
||||||
ALCcontext ctx = joalAlc.alcGetCurrentContext(); |
|
||||||
|
|
||||||
if (ctx == null) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
ALCdevice device = joalAlc.alcGetContextsDevice(ctx); |
|
||||||
|
|
||||||
if (device == null) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (!joalAlc.alcMakeContextCurrent(null)) { |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
joalAlc.alcDestroyContext(ctx); |
|
||||||
joalAlc.alcCloseDevice(device); |
|
||||||
*/ |
|
||||||
|
|
||||||
ALut.alutExit(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isCreated() { |
|
||||||
return getALCDevice() != null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String alcGetString(int parameter) { |
|
||||||
return joalAlc.alcGetString(getALCDevice(), parameter); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean alcIsExtensionPresent(String extension) { |
|
||||||
return joalAlc.alcIsExtensionPresent(getALCDevice(), extension); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alcGetInteger(int param, IntBuffer buffer, int size) { |
|
||||||
joalAlc.alcGetIntegerv(getALCDevice(), param, size, buffer); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alcDevicePauseSOFT() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alcDeviceResumeSOFT() { |
|
||||||
} |
|
||||||
} |
|
@ -1,107 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.audio.joal; |
|
||||||
|
|
||||||
import com.jme3.audio.openal.EFX; |
|
||||||
import com.jogamp.openal.ALExt; |
|
||||||
import com.jogamp.openal.ALFactory; |
|
||||||
import java.nio.IntBuffer; |
|
||||||
|
|
||||||
/** |
|
||||||
* Exposes EFX extension for JOAL. |
|
||||||
* |
|
||||||
* @author Kirill Vainer |
|
||||||
*/ |
|
||||||
public final class JoalEFX implements EFX { |
|
||||||
|
|
||||||
private final ALExt joalAlext; |
|
||||||
|
|
||||||
public JoalEFX() { |
|
||||||
joalAlext = ALFactory.getALExt(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alGenAuxiliaryEffectSlots(int numSlots, IntBuffer buffers) { |
|
||||||
joalAlext.alGenAuxiliaryEffectSlots(numSlots, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alGenEffects(int numEffects, IntBuffer buffers) { |
|
||||||
joalAlext.alGenEffects(numEffects, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alEffecti(int effect, int param, int value) { |
|
||||||
joalAlext.alEffecti(effect, param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alAuxiliaryEffectSloti(int effectSlot, int param, int value) { |
|
||||||
joalAlext.alAuxiliaryEffectSloti(effectSlot, param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alDeleteEffects(int numEffects, IntBuffer buffers) { |
|
||||||
joalAlext.alDeleteEffects(numEffects, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alDeleteAuxiliaryEffectSlots(int numEffectSlots, IntBuffer buffers) { |
|
||||||
joalAlext.alDeleteAuxiliaryEffectSlots(numEffectSlots, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alGenFilters(int numFilters, IntBuffer buffers) { |
|
||||||
joalAlext.alGenFilters(numFilters, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alFilteri(int filter, int param, int value) { |
|
||||||
joalAlext.alFilteri(filter, param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alFilterf(int filter, int param, float value) { |
|
||||||
joalAlext.alFilterf(filter, param, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alDeleteFilters(int numFilters, IntBuffer buffers) { |
|
||||||
joalAlext.alDeleteFilters(numFilters, buffers); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void alEffectf(int effect, int param, float value) { |
|
||||||
joalAlext.alEffectf(effect, param, value); |
|
||||||
} |
|
||||||
} |
|
@ -1,597 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.input.jogl; |
|
||||||
|
|
||||||
import com.jme3.input.KeyInput; |
|
||||||
import com.jme3.input.RawInputListener; |
|
||||||
import com.jme3.input.event.KeyInputEvent; |
|
||||||
import com.jogamp.newt.event.KeyEvent; |
|
||||||
import com.jogamp.newt.event.KeyListener; |
|
||||||
import com.jogamp.newt.opengl.GLWindow; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
public class NewtKeyInput implements KeyInput, KeyListener { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(NewtKeyInput.class.getName()); |
|
||||||
|
|
||||||
private final ArrayList<KeyInputEvent> eventQueue = new ArrayList<KeyInputEvent>(); |
|
||||||
private RawInputListener listener; |
|
||||||
private GLWindow component; |
|
||||||
|
|
||||||
public NewtKeyInput() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void initialize() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy() { |
|
||||||
} |
|
||||||
|
|
||||||
public void setInputSource(GLWindow comp){ |
|
||||||
synchronized (eventQueue){ |
|
||||||
if (component != null){ |
|
||||||
component.removeKeyListener(this); |
|
||||||
eventQueue.clear(); |
|
||||||
} |
|
||||||
component = comp; |
|
||||||
component.addKeyListener(this); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getInputTimeNanos() { |
|
||||||
return System.nanoTime(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void update() { |
|
||||||
synchronized (eventQueue){ |
|
||||||
// flush events to listener
|
|
||||||
for (int i = 0; i < eventQueue.size(); i++){ |
|
||||||
listener.onKeyEvent(eventQueue.get(i)); |
|
||||||
} |
|
||||||
eventQueue.clear(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isInitialized() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setInputListener(RawInputListener listener) { |
|
||||||
this.listener = listener; |
|
||||||
} |
|
||||||
|
|
||||||
public void keyTyped(KeyEvent evt) { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void keyPressed(KeyEvent evt) { |
|
||||||
int code = convertNewtKey(evt.getKeySymbol()); |
|
||||||
KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), true, evt.isAutoRepeat()); |
|
||||||
keyEvent.setTime(evt.getWhen()); |
|
||||||
synchronized (eventQueue){ |
|
||||||
eventQueue.add(keyEvent); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void keyReleased(KeyEvent evt) { |
|
||||||
int code = convertNewtKey(evt.getKeySymbol()); |
|
||||||
KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, evt.isAutoRepeat()); |
|
||||||
keyEvent.setTime(evt.getWhen()); |
|
||||||
synchronized (eventQueue) { |
|
||||||
eventQueue.add(keyEvent); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* <code>convertJmeCode</code> converts KeyInput key codes to AWT key codes. |
|
||||||
* |
|
||||||
* @param key jme KeyInput key code |
|
||||||
* @return awt KeyEvent key code |
|
||||||
*/ |
|
||||||
public static int convertJmeCode( int key ) { |
|
||||||
switch ( key ) { |
|
||||||
case KEY_ESCAPE: |
|
||||||
return KeyEvent.VK_ESCAPE; |
|
||||||
case KEY_1: |
|
||||||
return KeyEvent.VK_1; |
|
||||||
case KEY_2: |
|
||||||
return KeyEvent.VK_2; |
|
||||||
case KEY_3: |
|
||||||
return KeyEvent.VK_3; |
|
||||||
case KEY_4: |
|
||||||
return KeyEvent.VK_4; |
|
||||||
case KEY_5: |
|
||||||
return KeyEvent.VK_5; |
|
||||||
case KEY_6: |
|
||||||
return KeyEvent.VK_6; |
|
||||||
case KEY_7: |
|
||||||
return KeyEvent.VK_7; |
|
||||||
case KEY_8: |
|
||||||
return KeyEvent.VK_8; |
|
||||||
case KEY_9: |
|
||||||
return KeyEvent.VK_9; |
|
||||||
case KEY_0: |
|
||||||
return KeyEvent.VK_0; |
|
||||||
case KEY_MINUS: |
|
||||||
return KeyEvent.VK_MINUS; |
|
||||||
case KEY_EQUALS: |
|
||||||
return KeyEvent.VK_EQUALS; |
|
||||||
case KEY_BACK: |
|
||||||
return KeyEvent.VK_BACK_SPACE; |
|
||||||
case KEY_TAB: |
|
||||||
return KeyEvent.VK_TAB; |
|
||||||
case KEY_Q: |
|
||||||
return KeyEvent.VK_Q; |
|
||||||
case KEY_W: |
|
||||||
return KeyEvent.VK_W; |
|
||||||
case KEY_E: |
|
||||||
return KeyEvent.VK_E; |
|
||||||
case KEY_R: |
|
||||||
return KeyEvent.VK_R; |
|
||||||
case KEY_T: |
|
||||||
return KeyEvent.VK_T; |
|
||||||
case KEY_Y: |
|
||||||
return KeyEvent.VK_Y; |
|
||||||
case KEY_U: |
|
||||||
return KeyEvent.VK_U; |
|
||||||
case KEY_I: |
|
||||||
return KeyEvent.VK_I; |
|
||||||
case KEY_O: |
|
||||||
return KeyEvent.VK_O; |
|
||||||
case KEY_P: |
|
||||||
return KeyEvent.VK_P; |
|
||||||
case KEY_LBRACKET: |
|
||||||
return KeyEvent.VK_OPEN_BRACKET; |
|
||||||
case KEY_RBRACKET: |
|
||||||
return KeyEvent.VK_CLOSE_BRACKET; |
|
||||||
case KEY_RETURN: |
|
||||||
return KeyEvent.VK_ENTER; |
|
||||||
case KEY_LCONTROL: |
|
||||||
return KeyEvent.VK_CONTROL; |
|
||||||
case KEY_A: |
|
||||||
return KeyEvent.VK_A; |
|
||||||
case KEY_S: |
|
||||||
return KeyEvent.VK_S; |
|
||||||
case KEY_D: |
|
||||||
return KeyEvent.VK_D; |
|
||||||
case KEY_F: |
|
||||||
return KeyEvent.VK_F; |
|
||||||
case KEY_G: |
|
||||||
return KeyEvent.VK_G; |
|
||||||
case KEY_H: |
|
||||||
return KeyEvent.VK_H; |
|
||||||
case KEY_J: |
|
||||||
return KeyEvent.VK_J; |
|
||||||
case KEY_K: |
|
||||||
return KeyEvent.VK_K; |
|
||||||
case KEY_L: |
|
||||||
return KeyEvent.VK_L; |
|
||||||
case KEY_SEMICOLON: |
|
||||||
return KeyEvent.VK_SEMICOLON; |
|
||||||
case KEY_APOSTROPHE: |
|
||||||
return KeyEvent.VK_QUOTE; |
|
||||||
//case KEY_GRAVE:
|
|
||||||
// return KeyEvent.VK_DEAD_GRAVE;
|
|
||||||
case KEY_LSHIFT: |
|
||||||
return KeyEvent.VK_SHIFT; |
|
||||||
case KEY_BACKSLASH: |
|
||||||
return KeyEvent.VK_BACK_SLASH; |
|
||||||
case KEY_Z: |
|
||||||
return KeyEvent.VK_Z; |
|
||||||
case KEY_X: |
|
||||||
return KeyEvent.VK_X; |
|
||||||
case KEY_C: |
|
||||||
return KeyEvent.VK_C; |
|
||||||
case KEY_V: |
|
||||||
return KeyEvent.VK_V; |
|
||||||
case KEY_B: |
|
||||||
return KeyEvent.VK_B; |
|
||||||
case KEY_N: |
|
||||||
return KeyEvent.VK_N; |
|
||||||
case KEY_M: |
|
||||||
return KeyEvent.VK_M; |
|
||||||
case KEY_COMMA: |
|
||||||
return KeyEvent.VK_COMMA; |
|
||||||
case KEY_PERIOD: |
|
||||||
return KeyEvent.VK_PERIOD; |
|
||||||
case KEY_SLASH: |
|
||||||
return KeyEvent.VK_SLASH; |
|
||||||
case KEY_RSHIFT: |
|
||||||
return KeyEvent.VK_SHIFT; |
|
||||||
case KEY_MULTIPLY: |
|
||||||
return KeyEvent.VK_MULTIPLY; |
|
||||||
case KEY_SPACE: |
|
||||||
return KeyEvent.VK_SPACE; |
|
||||||
case KEY_CAPITAL: |
|
||||||
return KeyEvent.VK_CAPS_LOCK; |
|
||||||
case KEY_F1: |
|
||||||
return KeyEvent.VK_F1; |
|
||||||
case KEY_F2: |
|
||||||
return KeyEvent.VK_F2; |
|
||||||
case KEY_F3: |
|
||||||
return KeyEvent.VK_F3; |
|
||||||
case KEY_F4: |
|
||||||
return KeyEvent.VK_F4; |
|
||||||
case KEY_F5: |
|
||||||
return KeyEvent.VK_F5; |
|
||||||
case KEY_F6: |
|
||||||
return KeyEvent.VK_F6; |
|
||||||
case KEY_F7: |
|
||||||
return KeyEvent.VK_F7; |
|
||||||
case KEY_F8: |
|
||||||
return KeyEvent.VK_F8; |
|
||||||
case KEY_F9: |
|
||||||
return KeyEvent.VK_F9; |
|
||||||
case KEY_F10: |
|
||||||
return KeyEvent.VK_F10; |
|
||||||
case KEY_NUMLOCK: |
|
||||||
return KeyEvent.VK_NUM_LOCK; |
|
||||||
case KEY_SCROLL: |
|
||||||
return KeyEvent.VK_SCROLL_LOCK; |
|
||||||
case KEY_NUMPAD7: |
|
||||||
return KeyEvent.VK_NUMPAD7; |
|
||||||
case KEY_NUMPAD8: |
|
||||||
return KeyEvent.VK_NUMPAD8; |
|
||||||
case KEY_NUMPAD9: |
|
||||||
return KeyEvent.VK_NUMPAD9; |
|
||||||
case KEY_SUBTRACT: |
|
||||||
return KeyEvent.VK_SUBTRACT; |
|
||||||
case KEY_NUMPAD4: |
|
||||||
return KeyEvent.VK_NUMPAD4; |
|
||||||
case KEY_NUMPAD5: |
|
||||||
return KeyEvent.VK_NUMPAD5; |
|
||||||
case KEY_NUMPAD6: |
|
||||||
return KeyEvent.VK_NUMPAD6; |
|
||||||
case KEY_ADD: |
|
||||||
return KeyEvent.VK_ADD; |
|
||||||
case KEY_NUMPAD1: |
|
||||||
return KeyEvent.VK_NUMPAD1; |
|
||||||
case KEY_NUMPAD2: |
|
||||||
return KeyEvent.VK_NUMPAD2; |
|
||||||
case KEY_NUMPAD3: |
|
||||||
return KeyEvent.VK_NUMPAD3; |
|
||||||
case KEY_NUMPAD0: |
|
||||||
return KeyEvent.VK_NUMPAD0; |
|
||||||
case KEY_DECIMAL: |
|
||||||
return KeyEvent.VK_DECIMAL; |
|
||||||
case KEY_F11: |
|
||||||
return KeyEvent.VK_F11; |
|
||||||
case KEY_F12: |
|
||||||
return KeyEvent.VK_F12; |
|
||||||
case KEY_F13: |
|
||||||
return KeyEvent.VK_F13; |
|
||||||
case KEY_F14: |
|
||||||
return KeyEvent.VK_F14; |
|
||||||
case KEY_F15: |
|
||||||
return KeyEvent.VK_F15; |
|
||||||
//case KEY_KANA:
|
|
||||||
// return KeyEvent.VK_KANA;
|
|
||||||
case KEY_CONVERT: |
|
||||||
return KeyEvent.VK_CONVERT; |
|
||||||
case KEY_NOCONVERT: |
|
||||||
return KeyEvent.VK_NONCONVERT; |
|
||||||
case KEY_NUMPADEQUALS: |
|
||||||
return KeyEvent.VK_EQUALS; |
|
||||||
case KEY_CIRCUMFLEX: |
|
||||||
return KeyEvent.VK_CIRCUMFLEX; |
|
||||||
case KEY_AT: |
|
||||||
return KeyEvent.VK_AT; |
|
||||||
case KEY_COLON: |
|
||||||
return KeyEvent.VK_COLON; |
|
||||||
case KEY_UNDERLINE: |
|
||||||
return KeyEvent.VK_UNDERSCORE; |
|
||||||
case KEY_STOP: |
|
||||||
return KeyEvent.VK_STOP; |
|
||||||
case KEY_NUMPADENTER: |
|
||||||
return KeyEvent.VK_ENTER; |
|
||||||
case KEY_RCONTROL: |
|
||||||
return KeyEvent.VK_CONTROL; |
|
||||||
case KEY_NUMPADCOMMA: |
|
||||||
return KeyEvent.VK_COMMA; |
|
||||||
case KEY_DIVIDE: |
|
||||||
return KeyEvent.VK_DIVIDE; |
|
||||||
case KEY_PAUSE: |
|
||||||
return KeyEvent.VK_PAUSE; |
|
||||||
case KEY_HOME: |
|
||||||
return KeyEvent.VK_HOME; |
|
||||||
case KEY_UP: |
|
||||||
return KeyEvent.VK_UP; |
|
||||||
case KEY_PRIOR: |
|
||||||
return KeyEvent.VK_PAGE_UP; |
|
||||||
case KEY_LEFT: |
|
||||||
return KeyEvent.VK_LEFT; |
|
||||||
case KEY_RIGHT: |
|
||||||
return KeyEvent.VK_RIGHT; |
|
||||||
case KEY_END: |
|
||||||
return KeyEvent.VK_END; |
|
||||||
case KEY_DOWN: |
|
||||||
return KeyEvent.VK_DOWN; |
|
||||||
case KEY_NEXT: |
|
||||||
return KeyEvent.VK_PAGE_DOWN; |
|
||||||
case KEY_INSERT: |
|
||||||
return KeyEvent.VK_INSERT; |
|
||||||
case KEY_DELETE: |
|
||||||
return KeyEvent.VK_DELETE; |
|
||||||
case KEY_LMENU: |
|
||||||
return KeyEvent.VK_ALT; //todo: location left
|
|
||||||
case KEY_RMENU: |
|
||||||
return KeyEvent.VK_ALT; //todo: location right
|
|
||||||
} |
|
||||||
logger.log(Level.WARNING, "unsupported key:{0}", key); |
|
||||||
return 0x10000 + key; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* <code>convertAwtKey</code> converts AWT key codes to KeyInput key codes. |
|
||||||
* |
|
||||||
* @param key awt KeyEvent key code |
|
||||||
* @return jme KeyInput key code |
|
||||||
*/ |
|
||||||
public static int convertNewtKey(short key) { |
|
||||||
switch ( key ) { |
|
||||||
case KeyEvent.VK_ESCAPE: |
|
||||||
return KEY_ESCAPE; |
|
||||||
case KeyEvent.VK_1: |
|
||||||
return KEY_1; |
|
||||||
case KeyEvent.VK_2: |
|
||||||
return KEY_2; |
|
||||||
case KeyEvent.VK_3: |
|
||||||
return KEY_3; |
|
||||||
case KeyEvent.VK_4: |
|
||||||
return KEY_4; |
|
||||||
case KeyEvent.VK_5: |
|
||||||
return KEY_5; |
|
||||||
case KeyEvent.VK_6: |
|
||||||
return KEY_6; |
|
||||||
case KeyEvent.VK_7: |
|
||||||
return KEY_7; |
|
||||||
case KeyEvent.VK_8: |
|
||||||
return KEY_8; |
|
||||||
case KeyEvent.VK_9: |
|
||||||
return KEY_9; |
|
||||||
case KeyEvent.VK_0: |
|
||||||
return KEY_0; |
|
||||||
case KeyEvent.VK_MINUS: |
|
||||||
return KEY_MINUS; |
|
||||||
case KeyEvent.VK_EQUALS: |
|
||||||
return KEY_EQUALS; |
|
||||||
case KeyEvent.VK_BACK_SPACE: |
|
||||||
return KEY_BACK; |
|
||||||
case KeyEvent.VK_TAB: |
|
||||||
return KEY_TAB; |
|
||||||
case KeyEvent.VK_Q: |
|
||||||
return KEY_Q; |
|
||||||
case KeyEvent.VK_W: |
|
||||||
return KEY_W; |
|
||||||
case KeyEvent.VK_E: |
|
||||||
return KEY_E; |
|
||||||
case KeyEvent.VK_R: |
|
||||||
return KEY_R; |
|
||||||
case KeyEvent.VK_T: |
|
||||||
return KEY_T; |
|
||||||
case KeyEvent.VK_Y: |
|
||||||
return KEY_Y; |
|
||||||
case KeyEvent.VK_U: |
|
||||||
return KEY_U; |
|
||||||
case KeyEvent.VK_I: |
|
||||||
return KEY_I; |
|
||||||
case KeyEvent.VK_O: |
|
||||||
return KEY_O; |
|
||||||
case KeyEvent.VK_P: |
|
||||||
return KEY_P; |
|
||||||
case KeyEvent.VK_OPEN_BRACKET: |
|
||||||
return KEY_LBRACKET; |
|
||||||
case KeyEvent.VK_CLOSE_BRACKET: |
|
||||||
return KEY_RBRACKET; |
|
||||||
case KeyEvent.VK_ENTER: |
|
||||||
return KEY_RETURN; |
|
||||||
case KeyEvent.VK_CONTROL: |
|
||||||
return KEY_LCONTROL; |
|
||||||
case KeyEvent.VK_A: |
|
||||||
return KEY_A; |
|
||||||
case KeyEvent.VK_S: |
|
||||||
return KEY_S; |
|
||||||
case KeyEvent.VK_D: |
|
||||||
return KEY_D; |
|
||||||
case KeyEvent.VK_F: |
|
||||||
return KEY_F; |
|
||||||
case KeyEvent.VK_G: |
|
||||||
return KEY_G; |
|
||||||
case KeyEvent.VK_H: |
|
||||||
return KEY_H; |
|
||||||
case KeyEvent.VK_J: |
|
||||||
return KEY_J; |
|
||||||
case KeyEvent.VK_K: |
|
||||||
return KEY_K; |
|
||||||
case KeyEvent.VK_L: |
|
||||||
return KEY_L; |
|
||||||
case KeyEvent.VK_SEMICOLON: |
|
||||||
return KEY_SEMICOLON; |
|
||||||
case KeyEvent.VK_QUOTE: |
|
||||||
return KEY_APOSTROPHE; |
|
||||||
//case KeyEvent.VK_DEAD_GRAVE:
|
|
||||||
// return KEY_GRAVE;
|
|
||||||
case KeyEvent.VK_SHIFT: |
|
||||||
return KEY_LSHIFT; |
|
||||||
case KeyEvent.VK_BACK_SLASH: |
|
||||||
return KEY_BACKSLASH; |
|
||||||
case KeyEvent.VK_Z: |
|
||||||
return KEY_Z; |
|
||||||
case KeyEvent.VK_X: |
|
||||||
return KEY_X; |
|
||||||
case KeyEvent.VK_C: |
|
||||||
return KEY_C; |
|
||||||
case KeyEvent.VK_V: |
|
||||||
return KEY_V; |
|
||||||
case KeyEvent.VK_B: |
|
||||||
return KEY_B; |
|
||||||
case KeyEvent.VK_N: |
|
||||||
return KEY_N; |
|
||||||
case KeyEvent.VK_M: |
|
||||||
return KEY_M; |
|
||||||
case KeyEvent.VK_COMMA: |
|
||||||
return KEY_COMMA; |
|
||||||
case KeyEvent.VK_PERIOD: |
|
||||||
return KEY_PERIOD; |
|
||||||
case KeyEvent.VK_SLASH: |
|
||||||
return KEY_SLASH; |
|
||||||
case KeyEvent.VK_MULTIPLY: |
|
||||||
return KEY_MULTIPLY; |
|
||||||
case KeyEvent.VK_SPACE: |
|
||||||
return KEY_SPACE; |
|
||||||
case KeyEvent.VK_CAPS_LOCK: |
|
||||||
return KEY_CAPITAL; |
|
||||||
case KeyEvent.VK_F1: |
|
||||||
return KEY_F1; |
|
||||||
case KeyEvent.VK_F2: |
|
||||||
return KEY_F2; |
|
||||||
case KeyEvent.VK_F3: |
|
||||||
return KEY_F3; |
|
||||||
case KeyEvent.VK_F4: |
|
||||||
return KEY_F4; |
|
||||||
case KeyEvent.VK_F5: |
|
||||||
return KEY_F5; |
|
||||||
case KeyEvent.VK_F6: |
|
||||||
return KEY_F6; |
|
||||||
case KeyEvent.VK_F7: |
|
||||||
return KEY_F7; |
|
||||||
case KeyEvent.VK_F8: |
|
||||||
return KEY_F8; |
|
||||||
case KeyEvent.VK_F9: |
|
||||||
return KEY_F9; |
|
||||||
case KeyEvent.VK_F10: |
|
||||||
return KEY_F10; |
|
||||||
case KeyEvent.VK_NUM_LOCK: |
|
||||||
return KEY_NUMLOCK; |
|
||||||
case KeyEvent.VK_SCROLL_LOCK: |
|
||||||
return KEY_SCROLL; |
|
||||||
case KeyEvent.VK_NUMPAD7: |
|
||||||
return KEY_NUMPAD7; |
|
||||||
case KeyEvent.VK_NUMPAD8: |
|
||||||
return KEY_NUMPAD8; |
|
||||||
case KeyEvent.VK_NUMPAD9: |
|
||||||
return KEY_NUMPAD9; |
|
||||||
case KeyEvent.VK_SUBTRACT: |
|
||||||
return KEY_SUBTRACT; |
|
||||||
case KeyEvent.VK_NUMPAD4: |
|
||||||
return KEY_NUMPAD4; |
|
||||||
case KeyEvent.VK_NUMPAD5: |
|
||||||
return KEY_NUMPAD5; |
|
||||||
case KeyEvent.VK_NUMPAD6: |
|
||||||
return KEY_NUMPAD6; |
|
||||||
case KeyEvent.VK_ADD: |
|
||||||
return KEY_ADD; |
|
||||||
case KeyEvent.VK_NUMPAD1: |
|
||||||
return KEY_NUMPAD1; |
|
||||||
case KeyEvent.VK_NUMPAD2: |
|
||||||
return KEY_NUMPAD2; |
|
||||||
case KeyEvent.VK_NUMPAD3: |
|
||||||
return KEY_NUMPAD3; |
|
||||||
case KeyEvent.VK_NUMPAD0: |
|
||||||
return KEY_NUMPAD0; |
|
||||||
case KeyEvent.VK_DECIMAL: |
|
||||||
return KEY_DECIMAL; |
|
||||||
case KeyEvent.VK_F11: |
|
||||||
return KEY_F11; |
|
||||||
case KeyEvent.VK_F12: |
|
||||||
return KEY_F12; |
|
||||||
case KeyEvent.VK_F13: |
|
||||||
return KEY_F13; |
|
||||||
case KeyEvent.VK_F14: |
|
||||||
return KEY_F14; |
|
||||||
case KeyEvent.VK_F15: |
|
||||||
return KEY_F15; |
|
||||||
//case KeyEvent.VK_KANA:
|
|
||||||
// return KEY_KANA;
|
|
||||||
case KeyEvent.VK_CONVERT: |
|
||||||
return KEY_CONVERT; |
|
||||||
case KeyEvent.VK_NONCONVERT: |
|
||||||
return KEY_NOCONVERT; |
|
||||||
case KeyEvent.VK_CIRCUMFLEX: |
|
||||||
return KEY_CIRCUMFLEX; |
|
||||||
case KeyEvent.VK_AT: |
|
||||||
return KEY_AT; |
|
||||||
case KeyEvent.VK_COLON: |
|
||||||
return KEY_COLON; |
|
||||||
case KeyEvent.VK_UNDERSCORE: |
|
||||||
return KEY_UNDERLINE; |
|
||||||
case KeyEvent.VK_STOP: |
|
||||||
return KEY_STOP; |
|
||||||
case KeyEvent.VK_DIVIDE: |
|
||||||
return KEY_DIVIDE; |
|
||||||
case KeyEvent.VK_PAUSE: |
|
||||||
return KEY_PAUSE; |
|
||||||
case KeyEvent.VK_HOME: |
|
||||||
return KEY_HOME; |
|
||||||
case KeyEvent.VK_UP: |
|
||||||
return KEY_UP; |
|
||||||
case KeyEvent.VK_PAGE_UP: |
|
||||||
return KEY_PRIOR; |
|
||||||
case KeyEvent.VK_LEFT: |
|
||||||
return KEY_LEFT; |
|
||||||
case KeyEvent.VK_RIGHT: |
|
||||||
return KEY_RIGHT; |
|
||||||
case KeyEvent.VK_END: |
|
||||||
return KEY_END; |
|
||||||
case KeyEvent.VK_DOWN: |
|
||||||
return KEY_DOWN; |
|
||||||
case KeyEvent.VK_PAGE_DOWN: |
|
||||||
return KEY_NEXT; |
|
||||||
case KeyEvent.VK_INSERT: |
|
||||||
return KEY_INSERT; |
|
||||||
case KeyEvent.VK_DELETE: |
|
||||||
return KEY_DELETE; |
|
||||||
case KeyEvent.VK_ALT: |
|
||||||
return KEY_LMENU; //Left vs. Right need to improve
|
|
||||||
case KeyEvent.VK_META: |
|
||||||
return KEY_RCONTROL; |
|
||||||
|
|
||||||
} |
|
||||||
logger.log( Level.WARNING, "unsupported key:{0}", key); |
|
||||||
if ( key >= 0x10000 ) { |
|
||||||
return key - 0x10000; |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,327 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.jogl; |
|
||||||
|
|
||||||
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.jogamp.common.nio.Buffers; |
|
||||||
import com.jogamp.newt.Display.PointerIcon; |
|
||||||
import com.jogamp.newt.event.MouseEvent; |
|
||||||
import com.jogamp.newt.event.MouseListener; |
|
||||||
import com.jogamp.newt.opengl.GLWindow; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.logging.Logger; |
|
||||||
import com.jogamp.nativewindow.util.Dimension; |
|
||||||
import com.jogamp.nativewindow.util.DimensionImmutable; |
|
||||||
import com.jogamp.nativewindow.util.PixelFormat; |
|
||||||
import com.jogamp.nativewindow.util.PixelRectangle; |
|
||||||
import com.jogamp.nativewindow.util.Point; |
|
||||||
import com.jogamp.newt.event.WindowAdapter; |
|
||||||
import com.jogamp.newt.event.WindowEvent; |
|
||||||
|
|
||||||
public class NewtMouseInput implements MouseInput, MouseListener { |
|
||||||
|
|
||||||
public static int WHEEL_AMP = 40; // arbitrary... Java's mouse wheel seems to report something a lot lower than lwjgl's
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(NewtMouseInput.class.getName()); |
|
||||||
|
|
||||||
private boolean visible = true; |
|
||||||
|
|
||||||
private RawInputListener listener; |
|
||||||
|
|
||||||
private GLWindow component; |
|
||||||
|
|
||||||
private final ArrayList<MouseButtonEvent> eventQueue = new ArrayList<MouseButtonEvent>(); |
|
||||||
private final ArrayList<MouseButtonEvent> eventQueueCopy = new ArrayList<MouseButtonEvent>(); |
|
||||||
|
|
||||||
private int lastEventX; |
|
||||||
private int lastEventY; |
|
||||||
private int lastEventWheel; |
|
||||||
|
|
||||||
private int wheelPos; |
|
||||||
private Point location; |
|
||||||
private Point centerLocation; |
|
||||||
private Point lastKnownLocation; |
|
||||||
private Point lockPosition; |
|
||||||
private boolean isRecentering; |
|
||||||
private boolean cursorMoved; |
|
||||||
private int eventsSinceRecenter; |
|
||||||
private volatile int mousePressedX; |
|
||||||
private volatile int mousePressedY; |
|
||||||
|
|
||||||
public NewtMouseInput() { |
|
||||||
location = new Point(); |
|
||||||
centerLocation = new Point(); |
|
||||||
lastKnownLocation = new Point(); |
|
||||||
lockPosition = new Point(); |
|
||||||
} |
|
||||||
|
|
||||||
public void setInputSource(GLWindow comp) { |
|
||||||
if (component != null) { |
|
||||||
component.removeMouseListener(this); |
|
||||||
|
|
||||||
eventQueue.clear(); |
|
||||||
|
|
||||||
wheelPos = 0; |
|
||||||
isRecentering = false; |
|
||||||
eventsSinceRecenter = 0; |
|
||||||
lastEventX = 0; |
|
||||||
lastEventY = 0; |
|
||||||
lastEventWheel = 0; |
|
||||||
location = new Point(); |
|
||||||
centerLocation = new Point(); |
|
||||||
lastKnownLocation = new Point(); |
|
||||||
lockPosition = new Point(); |
|
||||||
} |
|
||||||
|
|
||||||
component = comp; |
|
||||||
component.addMouseListener(this); |
|
||||||
component.addWindowListener(new WindowAdapter(){ |
|
||||||
|
|
||||||
@Override |
|
||||||
public void windowGainedFocus(WindowEvent e) { |
|
||||||
setCursorVisible(visible); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void windowLostFocus(WindowEvent e) { |
|
||||||
//without those lines,
|
|
||||||
//on Linux (OpenBox) the mouse is not restored if invisible (eg via Alt-Tab)
|
|
||||||
component.setPointerVisible(true); |
|
||||||
component.confinePointer(false); |
|
||||||
} |
|
||||||
|
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void initialize() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isInitialized() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setInputListener(RawInputListener listener) { |
|
||||||
this.listener = listener; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getInputTimeNanos() { |
|
||||||
return System.nanoTime(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setCursorVisible(boolean visible) { |
|
||||||
this.visible = visible; |
|
||||||
component.setPointerVisible(visible); |
|
||||||
lockPosition.set(lastKnownLocation.getX(), lastKnownLocation.getY()); |
|
||||||
hack_confinePointer(); |
|
||||||
} |
|
||||||
|
|
||||||
private void hack_confinePointer() { |
|
||||||
if (component.hasFocus() && !component.isPointerVisible()) { |
|
||||||
recenterMouse(component); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void update() { |
|
||||||
if (!component.hasFocus()) return; |
|
||||||
if (cursorMoved) { |
|
||||||
int newX = location.getX(); |
|
||||||
int newY = location.getY(); |
|
||||||
int newWheel = wheelPos; |
|
||||||
|
|
||||||
// invert DY
|
|
||||||
int actualX = lastKnownLocation.getX(); |
|
||||||
int actualY = component.getSurfaceHeight() - lastKnownLocation.getY(); |
|
||||||
MouseMotionEvent evt = new MouseMotionEvent(actualX, actualY, |
|
||||||
newX - lastEventX, |
|
||||||
lastEventY - newY, |
|
||||||
wheelPos, lastEventWheel - wheelPos); |
|
||||||
listener.onMouseMotionEvent(evt); |
|
||||||
|
|
||||||
lastEventX = newX; |
|
||||||
lastEventY = newY; |
|
||||||
lastEventWheel = newWheel; |
|
||||||
|
|
||||||
cursorMoved = false; |
|
||||||
} |
|
||||||
|
|
||||||
synchronized (eventQueue) { |
|
||||||
eventQueueCopy.clear(); |
|
||||||
eventQueueCopy.addAll(eventQueue); |
|
||||||
eventQueue.clear(); |
|
||||||
} |
|
||||||
|
|
||||||
int size = eventQueueCopy.size(); |
|
||||||
for (int i = 0; i < size; i++) { |
|
||||||
listener.onMouseButtonEvent(eventQueueCopy.get(i)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getButtonCount() { |
|
||||||
return 3; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseClicked(MouseEvent awtEvt) { |
|
||||||
// MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(arg0), false);
|
|
||||||
// listener.onMouseButtonEvent(evt);
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mousePressed(MouseEvent newtEvt) { |
|
||||||
mousePressedX = newtEvt.getX(); |
|
||||||
mousePressedY = component.getSurfaceHeight() - newtEvt.getY(); |
|
||||||
MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(newtEvt), true, mousePressedX, mousePressedY); |
|
||||||
evt.setTime(newtEvt.getWhen()); |
|
||||||
synchronized (eventQueue) { |
|
||||||
eventQueue.add(evt); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseReleased(MouseEvent awtEvt) { |
|
||||||
MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(awtEvt), false, awtEvt.getX(), component.getSurfaceHeight() - awtEvt.getY()); |
|
||||||
evt.setTime(awtEvt.getWhen()); |
|
||||||
synchronized (eventQueue) { |
|
||||||
eventQueue.add(evt); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseEntered(MouseEvent awtEvt) { |
|
||||||
hack_confinePointer(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseExited(MouseEvent awtEvt) { |
|
||||||
hack_confinePointer(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseWheelMoved(MouseEvent awtEvt) { |
|
||||||
//FIXME not sure this is the right way to handle this case
|
|
||||||
// [0] should be used when the shift key is down
|
|
||||||
float dwheel = awtEvt.getRotation()[1]; |
|
||||||
wheelPos += dwheel * WHEEL_AMP; |
|
||||||
cursorMoved = true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseDragged(MouseEvent awtEvt) { |
|
||||||
mouseMoved(awtEvt); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseMoved(MouseEvent awtEvt) { |
|
||||||
if (isRecentering) { |
|
||||||
// MHenze (cylab) Fix Issue 35:
|
|
||||||
// As long as the MouseInput is in recentering mode, nothing is done until the mouse is entered in the component
|
|
||||||
// by the events generated by the robot. If this happens, the last known location is resetted.
|
|
||||||
if ((lockPosition.getX() == awtEvt.getX() && lockPosition.getY() == awtEvt.getY()) || eventsSinceRecenter++ == 5) { |
|
||||||
lastKnownLocation.setX(awtEvt.getX()); |
|
||||||
lastKnownLocation.setY(awtEvt.getY()); |
|
||||||
isRecentering = false; |
|
||||||
} |
|
||||||
} else { |
|
||||||
// MHenze (cylab) Fix Issue 35:
|
|
||||||
// Compute the delta and absolute coordinates and recenter the mouse if necessary
|
|
||||||
int dx = awtEvt.getX() - lastKnownLocation.getX(); |
|
||||||
int dy = awtEvt.getY() - lastKnownLocation.getY(); |
|
||||||
location.setX(location.getX() + dx); |
|
||||||
location.setY(location.getY() + dy); |
|
||||||
hack_confinePointer(); |
|
||||||
lastKnownLocation.setX(awtEvt.getX()); |
|
||||||
lastKnownLocation.setY(awtEvt.getY()); |
|
||||||
|
|
||||||
cursorMoved = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// MHenze (cylab) Fix Issue 35: A method to generate recenter the mouse to allow the InputSystem to "grab" the mouse
|
|
||||||
private void recenterMouse(final GLWindow component) { |
|
||||||
eventsSinceRecenter = 0; |
|
||||||
isRecentering = true; |
|
||||||
component.warpPointer(lockPosition.getX(), lockPosition.getY()); |
|
||||||
} |
|
||||||
|
|
||||||
private int getJMEButtonIndex(MouseEvent awtEvt) { |
|
||||||
int index; |
|
||||||
switch (awtEvt.getButton()) { |
|
||||||
default: |
|
||||||
case MouseEvent.BUTTON1: //left
|
|
||||||
index = MouseInput.BUTTON_LEFT; |
|
||||||
break; |
|
||||||
case MouseEvent.BUTTON2: //middle
|
|
||||||
index = MouseInput.BUTTON_MIDDLE; |
|
||||||
break; |
|
||||||
case MouseEvent.BUTTON3: //right
|
|
||||||
index = MouseInput.BUTTON_RIGHT; |
|
||||||
break; |
|
||||||
case MouseEvent.BUTTON4: |
|
||||||
case MouseEvent.BUTTON5: |
|
||||||
case MouseEvent.BUTTON6: |
|
||||||
case MouseEvent.BUTTON7: |
|
||||||
case MouseEvent.BUTTON8: |
|
||||||
case MouseEvent.BUTTON9: |
|
||||||
//FIXME
|
|
||||||
index = 0; |
|
||||||
break; |
|
||||||
} |
|
||||||
return index; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setNativeCursor(JmeCursor cursor) { |
|
||||||
final ByteBuffer pixels = Buffers.copyIntBufferAsByteBuffer(cursor.getImagesData()); |
|
||||||
final DimensionImmutable size = new Dimension(cursor.getWidth(), cursor.getHeight()); |
|
||||||
final PixelFormat pixFormat = PixelFormat.RGBA8888; |
|
||||||
final PixelRectangle.GenericPixelRect rec = new PixelRectangle.GenericPixelRect(pixFormat, size, 0, true, pixels); |
|
||||||
final PointerIcon joglCursor = component.getScreen().getDisplay().createPointerIcon(rec, cursor.getXHotSpot(), cursor.getHeight() - cursor.getYHotSpot()); |
|
||||||
component.setPointerIcon(joglCursor); |
|
||||||
} |
|
||||||
} |
|
@ -1,235 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.*; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import com.jogamp.opencl.*; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import com.jogamp.opencl.llb.gl.CLGL; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclBuffer extends Buffer { |
|
||||||
|
|
||||||
final long id; |
|
||||||
final CL cl; |
|
||||||
|
|
||||||
public JoclBuffer(long id) { |
|
||||||
super(new ReleaserImpl(id)); |
|
||||||
this.id = id; |
|
||||||
this.cl = CLPlatform.getLowLevelCLInterface(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getSize() { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
int ret = cl.clGetMemObjectInfo(id, CL.CL_MEM_SIZE, Utils.pointers[0].elementSize(), Utils.pointers[0].getBuffer(), null); |
|
||||||
Utils.checkError(ret, "clGetMemObjectInfo"); |
|
||||||
return Utils.pointers[0].get(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public MemoryAccess getMemoryAccessFlags() { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
int ret = cl.clGetMemObjectInfo(id, CL.CL_MEM_TYPE, Utils.pointers[0].elementSize(), Utils.pointers[0].getBuffer(), null); |
|
||||||
Utils.checkError(ret, "clGetMemObjectInfo"); |
|
||||||
long flags = Utils.pointers[0].get(); |
|
||||||
return Utils.getMemoryAccessFromFlag(flags); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void read(CommandQueue queue, ByteBuffer dest, long size, long offset) { |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueReadBuffer(q, id, CL.CL_TRUE, offset, size, dest, 0, null, null); |
|
||||||
Utils.checkError(ret, "clEnqueueReadBuffer"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event readAsync(CommandQueue queue, ByteBuffer dest, long size, long offset) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueReadBuffer(q, id, CL.CL_FALSE, offset, size, dest, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueReadBuffer"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void write(CommandQueue queue, ByteBuffer src, long size, long offset) { |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
int ret = cl.clEnqueueWriteBuffer(q, id, CL.CL_TRUE, offset, size, src, 0, null, null); |
|
||||||
Utils.checkError(ret, "clEnqueueWriteBuffer"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event writeAsync(CommandQueue queue, ByteBuffer src, long size, long offset) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
int ret = cl.clEnqueueWriteBuffer(q, id, CL.CL_FALSE, offset, size, src, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueWriteBuffer"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void copyTo(CommandQueue queue, Buffer dest, long size, long srcOffset, long destOffset) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
long did = ((JoclBuffer) dest).id; |
|
||||||
int ret = cl.clEnqueueCopyBuffer(q, id, did, srcOffset, destOffset, size, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueCopyBuffer"); |
|
||||||
ret = cl.clWaitForEvents(1, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clWaitForEvents"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event copyToAsync(CommandQueue queue, Buffer dest, long size, long srcOffset, long destOffset) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
long did = ((JoclBuffer) dest).id; |
|
||||||
int ret = cl.clEnqueueCopyBuffer(q, id, did, srcOffset, destOffset, size, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueCopyBuffer"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ByteBuffer map(CommandQueue queue, long size, long offset, MappingAccess access) { |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
long flags = Utils.getMappingAccessFlags(access); |
|
||||||
ByteBuffer b = cl.clEnqueueMapBuffer(q, id, CL.CL_TRUE, flags, offset, size, 0, null, null, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); |
|
||||||
return b; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void unmap(CommandQueue queue, ByteBuffer ptr) { |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
ptr.position(0); |
|
||||||
int ret = cl.clEnqueueUnmapMemObject(q, id, ptr, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueUnmapMemObject"); |
|
||||||
ret = cl.clWaitForEvents(1, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clWaitForEvents"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public com.jme3.opencl.Buffer.AsyncMapping mapAsync(CommandQueue queue, long size, long offset, MappingAccess access) { |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
long flags = Utils.getMappingAccessFlags(access); |
|
||||||
ByteBuffer b = cl.clEnqueueMapBuffer(q, id, CL.CL_FALSE, flags, offset, size, 0, null, Utils.pointers[0], Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new com.jme3.opencl.Buffer.AsyncMapping(new JoclEvent(event), b); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event fillAsync(CommandQueue queue, ByteBuffer pattern, long size, long offset) { |
|
||||||
throw new UnsupportedOperationException("Not supported by Jocl!"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event copyToImageAsync(CommandQueue queue, Image dest, long srcOffset, long[] destOrigin, long[] destRegion) { |
|
||||||
if (destOrigin.length!=3 || destRegion.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[1].put(destOrigin[0]).put(destOrigin[1]).put(destOrigin[2]).position(0); |
|
||||||
Utils.pointers[2].put(destRegion[0]).put(destRegion[1]).put(destRegion[2]).position(0); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
long i = ((JoclImage) dest).id; |
|
||||||
int ret = cl.clEnqueueCopyBufferToImage(q, id, i, srcOffset, Utils.pointers[1], Utils.pointers[2], 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueCopyBufferToImage"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event acquireBufferForSharingAsync(CommandQueue queue) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueAcquireGLObjects(q, 1, Utils.pointers[1], 0, null, Utils.pointers[0]); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void acquireBufferForSharingNoEvent(CommandQueue queue) { |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueAcquireGLObjects(q, 1, Utils.pointers[1], 0, null, null); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event releaseBufferForSharingAsync(CommandQueue queue) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueReleaseGLObjects(q, 1, Utils.pointers[1], 0, null, Utils.pointers[0]); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void releaseBufferForSharingNoEvent(CommandQueue queue) { |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueReleaseGLObjects(q, 1, Utils.pointers[1], 0, null, null); |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long mem; |
|
||||||
private ReleaserImpl(long mem) { |
|
||||||
this.mem = mem; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (mem != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseMemObject(mem); |
|
||||||
mem = 0; |
|
||||||
Utils.reportError(ret, "clReleaseMemObject"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,82 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.CommandQueue; |
|
||||||
import com.jme3.opencl.Device; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclCommandQueue extends CommandQueue { |
|
||||||
|
|
||||||
final CL cl; |
|
||||||
final long id; |
|
||||||
|
|
||||||
public JoclCommandQueue(long id, Device device) { |
|
||||||
super(new ReleaserImpl(id), device); |
|
||||||
this.id = id; |
|
||||||
this.cl = CLPlatform.getLowLevelCLInterface(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void flush() { |
|
||||||
int ret = cl.clFlush(id); |
|
||||||
Utils.checkError(ret, "clFlush"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void finish() { |
|
||||||
int ret = cl.clFinish(id); |
|
||||||
Utils.checkError(ret, "clFinish"); |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long id; |
|
||||||
|
|
||||||
private ReleaserImpl(long id) { |
|
||||||
this.id = id; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (id != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseCommandQueue(id); |
|
||||||
id = 0; |
|
||||||
Utils.reportError(ret, "clReleaseCommandQueue"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,262 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.*; |
|
||||||
import com.jme3.opencl.Context; |
|
||||||
import com.jme3.opencl.Image.ImageDescriptor; |
|
||||||
import com.jme3.opencl.Image.ImageFormat; |
|
||||||
import com.jme3.scene.VertexBuffer; |
|
||||||
import com.jme3.texture.FrameBuffer; |
|
||||||
import com.jme3.texture.Texture; |
|
||||||
import com.jogamp.opencl.CLContext; |
|
||||||
import com.jogamp.opencl.CLImageFormat; |
|
||||||
import com.jogamp.opencl.CLMemory.Mem; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import com.jogamp.opencl.llb.gl.CLGL; |
|
||||||
import com.jogamp.opencl.llb.impl.CLImageFormatImpl; |
|
||||||
import com.jogamp.opengl.GL; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.util.List; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclContext extends Context { |
|
||||||
private static final Logger LOG = Logger.getLogger(JoclContext.class.getName()); |
|
||||||
|
|
||||||
final CLContext context; |
|
||||||
final long id; |
|
||||||
final CL cl; |
|
||||||
private final List<JoclDevice> devices; |
|
||||||
|
|
||||||
public JoclContext(CLContext context, List<JoclDevice> devices) { |
|
||||||
super(new ReleaserImpl(context.ID, devices)); |
|
||||||
this.context = context; |
|
||||||
this.id = context.ID; |
|
||||||
this.cl = context.getCL(); |
|
||||||
this.devices = devices; |
|
||||||
} |
|
||||||
|
|
||||||
public CLContext getContext() { |
|
||||||
return context; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public List<JoclDevice> getDevices() { |
|
||||||
return devices; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
@SuppressWarnings("element-type-mismatch") |
|
||||||
public CommandQueue createQueue(Device device) { |
|
||||||
assert (devices.contains(device)); //this also ensures that device is a JoclDevice
|
|
||||||
long d = ((JoclDevice) device).id; |
|
||||||
long properties = 0; |
|
||||||
long q = cl.clCreateCommandQueue(id, d, properties, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateCommandQueue"); |
|
||||||
return new JoclCommandQueue(q, device); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Buffer createBuffer(long size, MemoryAccess access) { |
|
||||||
long flags = Utils.getMemoryAccessFlags(access); |
|
||||||
long mem = cl.clCreateBuffer(id, flags, size, null, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateBuffer"); |
|
||||||
return new JoclBuffer(mem); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Buffer createBufferFromHost(ByteBuffer data, MemoryAccess access) { |
|
||||||
long flags = Utils.getMemoryAccessFlags(access); |
|
||||||
flags |= CL.CL_MEM_USE_HOST_PTR; |
|
||||||
long mem = cl.clCreateBuffer(id, flags, data.capacity(), data, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateBuffer"); |
|
||||||
return new JoclBuffer(mem); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Image createImage(MemoryAccess access, ImageFormat format, ImageDescriptor descr) { |
|
||||||
if (descr.type != Image.ImageType.IMAGE_2D && descr.type != Image.ImageType.IMAGE_3D) { |
|
||||||
throw new UnsupportedOperationException("Jocl only supports 2D and 3D images"); |
|
||||||
} |
|
||||||
long memFlags = Utils.getMemoryAccessFlags(access); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
//fill image format
|
|
||||||
CLImageFormatImpl f = CLImageFormatImpl.create(); |
|
||||||
f.setImageChannelOrder(JoclImage.decodeImageChannelOrder(format.channelOrder)); |
|
||||||
f.setImageChannelDataType(JoclImage.decodeImageChannelType(format.channelType)); |
|
||||||
//create image
|
|
||||||
long mem; |
|
||||||
if (descr.type == Image.ImageType.IMAGE_2D) { |
|
||||||
mem = cl.clCreateImage2D(id, memFlags, f, descr.width, descr.height, |
|
||||||
descr.hostPtr==null ? 0 : descr.rowPitch, descr.hostPtr, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateImage2D"); |
|
||||||
} else { |
|
||||||
mem = cl.clCreateImage3D(id, memFlags, f, descr.width, descr.height, descr.depth, |
|
||||||
descr.hostPtr==null ? 0 : descr.rowPitch, descr.hostPtr==null ? 0 : descr.slicePitch, |
|
||||||
descr.hostPtr, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateImage3D"); |
|
||||||
} |
|
||||||
return new JoclImage(mem); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ImageFormat[] querySupportedFormats(MemoryAccess access, Image.ImageType type) { |
|
||||||
if (type != Image.ImageType.IMAGE_2D && type != Image.ImageType.IMAGE_3D) { |
|
||||||
throw new UnsupportedOperationException("Jocl only supports 2D and 3D images"); |
|
||||||
} |
|
||||||
long memFlags = Utils.getMemoryAccessFlags(access); |
|
||||||
CLImageFormat[] fx; |
|
||||||
if (type == Image.ImageType.IMAGE_2D) { |
|
||||||
fx = context.getSupportedImage2dFormats(Mem.valueOf((int) memFlags)); |
|
||||||
} else { |
|
||||||
fx = context.getSupportedImage3dFormats(Mem.valueOf((int) memFlags)); |
|
||||||
} |
|
||||||
//convert formats
|
|
||||||
ImageFormat[] formats = new ImageFormat[fx.length]; |
|
||||||
for (int i=0; i<fx.length; ++i) { |
|
||||||
Image.ImageChannelOrder channelOrder = JoclImage.encodeImageChannelOrder(fx[i].getFormatImpl().getImageChannelOrder()); |
|
||||||
Image.ImageChannelType channelType = JoclImage.encodeImageChannelType(fx[i].getFormatImpl().getImageChannelDataType()); |
|
||||||
formats[i] = new ImageFormat(channelOrder, channelType); |
|
||||||
} |
|
||||||
return formats; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Buffer bindVertexBuffer(VertexBuffer vb, MemoryAccess access) { |
|
||||||
int vbId = vb.getId(); |
|
||||||
if (vbId == -1) { |
|
||||||
throw new IllegalArgumentException("vertex buffer was not yet uploaded to the GPU or is CPU only"); |
|
||||||
} |
|
||||||
long flags = Utils.getMemoryAccessFlags(access); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
long mem = ((CLGL) cl).clCreateFromGLBuffer(id, flags, vbId, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateFromGLBuffer"); |
|
||||||
return new JoclBuffer(mem); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Image bindImage(com.jme3.texture.Image image, Texture.Type textureType, int miplevel, MemoryAccess access) { |
|
||||||
int imageID = image.getId(); |
|
||||||
if (imageID == -1) { |
|
||||||
throw new IllegalArgumentException("image was not yet uploaded to the GPU"); |
|
||||||
} |
|
||||||
long memFlags = Utils.getMemoryAccessFlags(access); |
|
||||||
int textureTarget = convertTextureType(textureType); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
long mem; |
|
||||||
if (textureType == Texture.Type.TwoDimensional) { |
|
||||||
mem = ((CLGL) cl).clCreateFromGLTexture2D(id, memFlags, textureTarget, miplevel, imageID, Utils.errorBuffer); |
|
||||||
} else if (textureType == Texture.Type.ThreeDimensional) { |
|
||||||
mem = ((CLGL) cl).clCreateFromGLTexture3D(id, memFlags, textureTarget, miplevel, imageID, Utils.errorBuffer); |
|
||||||
} else { |
|
||||||
throw new UnsupportedOperationException("Jocl only supports 2D and 3D images"); |
|
||||||
} |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateFromGLTexture"); |
|
||||||
return new JoclImage(mem); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected Image bindPureRenderBuffer(FrameBuffer.RenderBuffer buffer, MemoryAccess access) { |
|
||||||
int renderbuffer = buffer.getId(); |
|
||||||
if (renderbuffer == -1) { |
|
||||||
throw new IllegalArgumentException("renderbuffer was not yet uploaded to the GPU"); |
|
||||||
} |
|
||||||
long memFlags = Utils.getMemoryAccessFlags(access); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
long mem = ((CLGL) cl).clCreateFromGLRenderbuffer(id, memFlags, renderbuffer, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateFromGLRenderbuffer"); |
|
||||||
return new JoclImage(mem); |
|
||||||
} |
|
||||||
|
|
||||||
private int convertTextureType(Texture.Type textureType) { |
|
||||||
switch (textureType) { |
|
||||||
case TwoDimensional: return GL.GL_TEXTURE_2D; |
|
||||||
case CubeMap: return GL.GL_TEXTURE_CUBE_MAP; |
|
||||||
default: throw new IllegalArgumentException("unknown or unsupported texture type "+textureType); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Program createProgramFromSourceCode(String sourceCode) { |
|
||||||
LOG.log(Level.FINE, "Create program from source:\n{0}", sourceCode); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[0].put(0, sourceCode.length()); |
|
||||||
long p = cl.clCreateProgramWithSource(id, 1, new String[]{sourceCode}, Utils.pointers[0], Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateProgramWithSource"); |
|
||||||
return new JoclProgram(p, this); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Program createProgramFromBinary(ByteBuffer binaries, Device device) { |
|
||||||
binaries.rewind(); |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
Utils.tempBuffers[0].b16i.rewind(); |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[0].put(0, ((JoclDevice) device).id); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, binaries.remaining()); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[2].referenceBuffer(0, binaries); |
|
||||||
long p = cl.clCreateProgramWithBinary(id, 1, Utils.pointers[0], |
|
||||||
Utils.pointers[1], Utils.pointers[2], Utils.tempBuffers[0].b16i, |
|
||||||
Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateProgramWithBinary"); |
|
||||||
Utils.checkError(Utils.tempBuffers[0].b16i, "clCreateProgramWithBinary"); |
|
||||||
return new JoclProgram(p, this); |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long id; |
|
||||||
private final List<JoclDevice> devices; |
|
||||||
private ReleaserImpl(long id, List<JoclDevice> devices) { |
|
||||||
this.id = id; |
|
||||||
this.devices = devices; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (id != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseContext(id); |
|
||||||
id = 0; |
|
||||||
devices.clear(); |
|
||||||
Utils.reportError(ret, "clReleaseContext"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,300 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.Device; |
|
||||||
import com.jogamp.opencl.CLDevice; |
|
||||||
import java.util.Collection; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public final class JoclDevice implements Device { |
|
||||||
|
|
||||||
final long id; |
|
||||||
final CLDevice device; |
|
||||||
final JoclPlatform platform; |
|
||||||
|
|
||||||
public JoclDevice(CLDevice device, JoclPlatform platform) { |
|
||||||
this.id = device.ID; |
|
||||||
this.device = device; |
|
||||||
this.platform = platform; |
|
||||||
} |
|
||||||
|
|
||||||
public long getId() { |
|
||||||
return id; |
|
||||||
} |
|
||||||
|
|
||||||
public CLDevice getDevice() { |
|
||||||
return device; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public JoclPlatform getPlatform() { |
|
||||||
return platform; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public DeviceType getDeviceType() { |
|
||||||
CLDevice.Type type = device.getType(); |
|
||||||
switch (type) { |
|
||||||
case ACCELERATOR: return DeviceType.ACCELEARTOR; |
|
||||||
case CPU: return DeviceType.CPU; |
|
||||||
case GPU: return DeviceType.GPU; |
|
||||||
default: return DeviceType.DEFAULT; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getVendorId() { |
|
||||||
return (int) device.getVendorID(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isAvailable() { |
|
||||||
return device.isAvailable(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasCompiler() { |
|
||||||
return device.isCompilerAvailable(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasDouble() { |
|
||||||
return hasExtension("cl_khr_fp64"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasHalfFloat() { |
|
||||||
return hasExtension("cl_khr_fp16"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasErrorCorrectingMemory() { |
|
||||||
return device.isErrorCorrectionSupported(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasUnifiedMemory() { |
|
||||||
return device.isMemoryUnified(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasImageSupport() { |
|
||||||
return device.isImageSupportAvailable(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasWritableImage3D() { |
|
||||||
return hasExtension("cl_khr_3d_image_writes"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasOpenGLInterop() { |
|
||||||
return hasExtension("cl_khr_gl_sharing"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasExtension(String extension) { |
|
||||||
return getExtensions().contains(extension); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Collection<? extends String> getExtensions() { |
|
||||||
return device.getExtensions(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getComputeUnits() { |
|
||||||
return device.getMaxComputeUnits(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getClockFrequency() { |
|
||||||
return device.getMaxClockFrequency(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getAddressBits() { |
|
||||||
return device.getAddressBits(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isLittleEndian() { |
|
||||||
return device.isLittleEndian(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getMaximumWorkItemDimensions() { |
|
||||||
return device.getMaxWorkItemDimensions(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long[] getMaximumWorkItemSizes() { |
|
||||||
int[] sizes = device.getMaxWorkItemSizes(); |
|
||||||
long[] s = new long[sizes.length]; |
|
||||||
for (int i=0; i<sizes.length; ++i) { |
|
||||||
s[i] = sizes[i]; |
|
||||||
} |
|
||||||
return s; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getMaxiumWorkItemsPerGroup() { |
|
||||||
return device.getMaxWorkGroupSize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getMaximumSamplers() { |
|
||||||
return device.getMaxSamplers(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getMaximumReadImages() { |
|
||||||
return device.getMaxReadImageArgs(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getMaximumWriteImages() { |
|
||||||
return device.getMaxWriteImageArgs(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long[] getMaximumImage2DSize() { |
|
||||||
return new long[] { |
|
||||||
device.getMaxImage2dWidth(), |
|
||||||
device.getMaxImage2dHeight() |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long[] getMaximumImage3DSize() { |
|
||||||
return new long[] { |
|
||||||
device.getMaxImage3dWidth(), |
|
||||||
device.getMaxImage3dHeight(), |
|
||||||
device.getMaxImage3dDepth() |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getMaximumAllocationSize() { |
|
||||||
return device.getMaxMemAllocSize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getGlobalMemorySize() { |
|
||||||
return device.getGlobalMemSize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getLocalMemorySize() { |
|
||||||
return device.getLocalMemSize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getMaximumConstantBufferSize() { |
|
||||||
return device.getMaxConstantBufferSize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getMaximumConstantArguments() { |
|
||||||
return (int) device.getMaxConstantArgs(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getProfile() { |
|
||||||
return device.getProfile(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getVersion() { |
|
||||||
return device.getVersion().toString(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getVersionMajor() { |
|
||||||
return Utils.getMajorVersion(getVersion(), "OpenCL "); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getVersionMinor() { |
|
||||||
return Utils.getMinorVersion(getVersion(), "OpenCL "); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getCompilerVersion() { |
|
||||||
return "OpenCL C 1.1"; //at most OpenCL 1.1 is supported at all
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getCompilerVersionMajor() { |
|
||||||
return Utils.getMajorVersion(getCompilerVersion(), "OpenCL C "); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getCompilerVersionMinor() { |
|
||||||
return Utils.getMinorVersion(getCompilerVersion(), "OpenCL C "); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getDriverVersion() { |
|
||||||
return device.getDriverVersion(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getDriverVersionMajor() { |
|
||||||
return Utils.getMajorVersion(getDriverVersion(), ""); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getDriverVersionMinor() { |
|
||||||
return Utils.getMinorVersion(getDriverVersion(), ""); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getName() { |
|
||||||
return device.getName(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getVendor() { |
|
||||||
return device.getVendor(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String toString() { |
|
||||||
return getName(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,99 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.Event; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclEvent extends Event { |
|
||||||
private static final Logger LOG = Logger.getLogger(JoclEvent.class.getName()); |
|
||||||
|
|
||||||
final long id; |
|
||||||
final CL cl; |
|
||||||
|
|
||||||
public JoclEvent(long id) { |
|
||||||
super(new ReleaserImpl(id)); |
|
||||||
this.id = id; |
|
||||||
this.cl = CLPlatform.getLowLevelCLInterface(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void waitForFinished() { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[0].put(0, id); |
|
||||||
int ret = cl.clWaitForEvents(1, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clWaitForEvents"); |
|
||||||
release(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isCompleted() { |
|
||||||
Utils.tempBuffers[0].b16.rewind(); |
|
||||||
int err = cl.clGetEventInfo(id, CL.CL_EVENT_COMMAND_EXECUTION_STATUS, 4, Utils.tempBuffers[0].b16, null); |
|
||||||
Utils.checkError(err, "clGetEventInfo"); |
|
||||||
int status = Utils.tempBuffers[0].b16i.get(0); |
|
||||||
if (status == CL.CL_SUCCESS) { |
|
||||||
release(); |
|
||||||
return true; |
|
||||||
} else if (status < 0) { |
|
||||||
Utils.checkError(status, "EventStatus"); |
|
||||||
return false; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long event; |
|
||||||
|
|
||||||
private ReleaserImpl(long event) { |
|
||||||
this.event = event; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (event != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseEvent(event); |
|
||||||
event = 0; |
|
||||||
Utils.reportError(ret, "clReleaseEvent"); |
|
||||||
LOG.finer("Event deleted"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,544 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.math.ColorRGBA; |
|
||||||
import com.jme3.opencl.*; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import com.jogamp.opencl.llb.gl.CLGL; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclImage extends Image { |
|
||||||
private static final Logger LOG = Logger.getLogger(JoclImage.class.getName()); |
|
||||||
|
|
||||||
final long id; |
|
||||||
final CL cl; |
|
||||||
|
|
||||||
public JoclImage(long image) { |
|
||||||
super(new ReleaserImpl(image)); |
|
||||||
this.id = image; |
|
||||||
this.cl = CLPlatform.getLowLevelCLInterface(); |
|
||||||
} |
|
||||||
|
|
||||||
public static int decodeImageChannelOrder(ImageChannelOrder order) { |
|
||||||
switch (order) { |
|
||||||
case A: |
|
||||||
return CL.CL_A; |
|
||||||
case ARGB: |
|
||||||
return CL.CL_ARGB; |
|
||||||
case BGRA: |
|
||||||
return CL.CL_BGRA; |
|
||||||
case INTENSITY: |
|
||||||
return CL.CL_INTENSITY; |
|
||||||
case LUMINANCE: |
|
||||||
return CL.CL_LUMINANCE; |
|
||||||
case R: |
|
||||||
return CL.CL_R; |
|
||||||
case RA: |
|
||||||
return CL.CL_RA; |
|
||||||
case RG: |
|
||||||
return CL.CL_RG; |
|
||||||
case RGB: |
|
||||||
return CL.CL_RGB; |
|
||||||
case RGBA: |
|
||||||
return CL.CL_RGBA; |
|
||||||
case RGBx: |
|
||||||
return CL.CL_RGBx; |
|
||||||
case RGx: |
|
||||||
return CL.CL_RGx; |
|
||||||
case Rx: |
|
||||||
return CL.CL_Rx; |
|
||||||
default: |
|
||||||
throw new IllegalArgumentException("unknown image channel order: " + order); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static ImageChannelOrder encodeImageChannelOrder(int order) { |
|
||||||
switch (order) { |
|
||||||
case CL.CL_A: |
|
||||||
return ImageChannelOrder.A; |
|
||||||
case CL.CL_ARGB: |
|
||||||
return ImageChannelOrder.ARGB; |
|
||||||
case CL.CL_BGRA: |
|
||||||
return ImageChannelOrder.BGRA; |
|
||||||
case CL.CL_INTENSITY: |
|
||||||
return ImageChannelOrder.INTENSITY; |
|
||||||
case CL.CL_LUMINANCE: |
|
||||||
return ImageChannelOrder.LUMINANCE; |
|
||||||
case CL.CL_R: |
|
||||||
return ImageChannelOrder.R; |
|
||||||
case CL.CL_RA: |
|
||||||
return ImageChannelOrder.RA; |
|
||||||
case CL.CL_RG: |
|
||||||
return ImageChannelOrder.RG; |
|
||||||
case CL.CL_RGB: |
|
||||||
return ImageChannelOrder.RGB; |
|
||||||
case CL.CL_RGBA: |
|
||||||
return ImageChannelOrder.RGBA; |
|
||||||
case CL.CL_RGBx: |
|
||||||
return ImageChannelOrder.RGBx; |
|
||||||
case CL.CL_RGx: |
|
||||||
return ImageChannelOrder.RGx; |
|
||||||
case CL.CL_Rx: |
|
||||||
return ImageChannelOrder.Rx; |
|
||||||
default: |
|
||||||
//throw new com.jme3.opencl.OpenCLException("unknown image channel order id: " + order);
|
|
||||||
LOG.log(Level.WARNING, "Unknown image channel order id: {0}", order); |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static int decodeImageChannelType(ImageChannelType type) { |
|
||||||
switch (type) { |
|
||||||
case FLOAT: |
|
||||||
return CL.CL_FLOAT; |
|
||||||
case HALF_FLOAT: |
|
||||||
return CL.CL_HALF_FLOAT; |
|
||||||
case SIGNED_INT16: |
|
||||||
return CL.CL_SIGNED_INT16; |
|
||||||
case SIGNED_INT32: |
|
||||||
return CL.CL_SIGNED_INT32; |
|
||||||
case SIGNED_INT8: |
|
||||||
return CL.CL_SIGNED_INT8; |
|
||||||
case SNORM_INT16: |
|
||||||
return CL.CL_SNORM_INT16; |
|
||||||
case SNORM_INT8: |
|
||||||
return CL.CL_SNORM_INT8; |
|
||||||
case UNORM_INT8: |
|
||||||
return CL.CL_UNORM_INT8; |
|
||||||
case UNORM_INT_101010: |
|
||||||
return CL.CL_UNORM_INT_101010; |
|
||||||
case UNORM_INT16: |
|
||||||
return CL.CL_UNORM_INT16; |
|
||||||
case UNORM_SHORT_565: |
|
||||||
return CL.CL_UNORM_SHORT_565; |
|
||||||
case UNORM_SHORT_555: |
|
||||||
return CL.CL_UNORM_SHORT_555; |
|
||||||
case UNSIGNED_INT16: |
|
||||||
return CL.CL_UNSIGNED_INT16; |
|
||||||
case UNSIGNED_INT32: |
|
||||||
return CL.CL_UNSIGNED_INT32; |
|
||||||
case UNSIGNED_INT8: |
|
||||||
return CL.CL_UNSIGNED_INT8; |
|
||||||
default: |
|
||||||
throw new IllegalArgumentException("Unknown image channel type: " + type); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static ImageChannelType encodeImageChannelType(int type) { |
|
||||||
switch (type) { |
|
||||||
case CL.CL_FLOAT: |
|
||||||
return ImageChannelType.FLOAT; |
|
||||||
case CL.CL_HALF_FLOAT: |
|
||||||
return ImageChannelType.HALF_FLOAT; |
|
||||||
case CL.CL_SIGNED_INT16: |
|
||||||
return ImageChannelType.SIGNED_INT16; |
|
||||||
case CL.CL_SIGNED_INT32: |
|
||||||
return ImageChannelType.SIGNED_INT32; |
|
||||||
case CL.CL_SIGNED_INT8: |
|
||||||
return ImageChannelType.SIGNED_INT8; |
|
||||||
case CL.CL_SNORM_INT16: |
|
||||||
return ImageChannelType.SNORM_INT16; |
|
||||||
case CL.CL_SNORM_INT8: |
|
||||||
return ImageChannelType.SNORM_INT8; |
|
||||||
case CL.CL_UNORM_INT8: |
|
||||||
return ImageChannelType.UNORM_INT8; |
|
||||||
case CL.CL_UNORM_INT16: |
|
||||||
return ImageChannelType.UNORM_INT16; |
|
||||||
case CL.CL_UNORM_INT_101010: |
|
||||||
return ImageChannelType.UNORM_INT_101010; |
|
||||||
case CL.CL_UNORM_SHORT_555: |
|
||||||
return ImageChannelType.UNORM_SHORT_555; |
|
||||||
case CL.CL_UNORM_SHORT_565: |
|
||||||
return ImageChannelType.UNORM_SHORT_565; |
|
||||||
case CL.CL_UNSIGNED_INT16: |
|
||||||
return ImageChannelType.UNSIGNED_INT16; |
|
||||||
case CL.CL_UNSIGNED_INT32: |
|
||||||
return ImageChannelType.UNSIGNED_INT32; |
|
||||||
case CL.CL_UNSIGNED_INT8: |
|
||||||
return ImageChannelType.UNSIGNED_INT8; |
|
||||||
default: |
|
||||||
//throw new com.jme3.opencl.OpenCLException("unknown image channel type id: " + type);
|
|
||||||
LOG.log(Level.WARNING, "Unknown image channel type id: {0}", type); |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static int decodeImageType(ImageType type) { |
|
||||||
switch (type) { |
|
||||||
// case IMAGE_1D:
|
|
||||||
// return CL.CL_MEM_OBJECT_IMAGE1D;
|
|
||||||
// case IMAGE_1D_ARRAY:
|
|
||||||
// return CL.CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
|
||||||
// case IMAGE_1D_BUFFER:
|
|
||||||
// return CL.CL_MEM_OBJECT_IMAGE1D_BUFFER;
|
|
||||||
case IMAGE_2D: |
|
||||||
return CL.CL_MEM_OBJECT_IMAGE2D; |
|
||||||
// case IMAGE_2D_ARRAY:
|
|
||||||
// return CL.CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
|
||||||
case IMAGE_3D: |
|
||||||
return CL.CL_MEM_OBJECT_IMAGE3D; |
|
||||||
default: |
|
||||||
throw new IllegalArgumentException("Unknown or unsupported image type: " + type); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static ImageType encodeImageType(int type) { |
|
||||||
switch (type) { |
|
||||||
// case CL12.CL_MEM_OBJECT_IMAGE1D:
|
|
||||||
// return ImageType.IMAGE_1D;
|
|
||||||
// case CL12.CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
||||||
// return ImageType.IMAGE_1D_ARRAY;
|
|
||||||
// case CL12.CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
||||||
// return ImageType.IMAGE_1D_BUFFER;
|
|
||||||
case CL.CL_MEM_OBJECT_IMAGE2D: |
|
||||||
return ImageType.IMAGE_2D; |
|
||||||
// case CL12.CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
||||||
// return ImageType.IMAGE_2D_ARRAY;
|
|
||||||
case CL.CL_MEM_OBJECT_IMAGE3D: |
|
||||||
return ImageType.IMAGE_3D; |
|
||||||
default: |
|
||||||
//throw new com.jme3.opencl.OpenCLException("Unknown image type id: " + type);
|
|
||||||
LOG.log(Level.WARNING, "Unknown or unsupported image type with id: {0}", type); |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private long getInfoSize(int param) { |
|
||||||
Utils.tempBuffers[0].b16l.rewind(); |
|
||||||
int ret = cl.clGetImageInfo(id, param, 8, Utils.tempBuffers[0].b16l, null); |
|
||||||
Utils.checkError(ret, "clGetImageInfo"); |
|
||||||
return Utils.tempBuffers[0].b16l.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getWidth() { |
|
||||||
return getInfoSize(CL.CL_IMAGE_WIDTH); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getHeight() { |
|
||||||
return getInfoSize(CL.CL_IMAGE_HEIGHT); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getDepth() { |
|
||||||
return getInfoSize(CL.CL_IMAGE_DEPTH); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getRowPitch() { |
|
||||||
return getInfoSize(CL.CL_IMAGE_ROW_PITCH); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getSlicePitch() { |
|
||||||
return getInfoSize(CL.CL_IMAGE_SLICE_PITCH); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getArraySize() { |
|
||||||
//return getInfoSize(CL12.CL_IMAGE_ARRAY_SIZE);
|
|
||||||
throw new UnsupportedOperationException("Not supported in Jocl"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ImageFormat getImageFormat() { |
|
||||||
Utils.tempBuffers[0].b16i.rewind(); |
|
||||||
int ret = cl.clGetImageInfo(id, CL.CL_IMAGE_FORMAT, 8, Utils.tempBuffers[0].b16i, null); |
|
||||||
Utils.checkError(ret, "clGetImageInfo"); |
|
||||||
int channelOrder = Utils.tempBuffers[0].b16i.get(0); |
|
||||||
int channelType = Utils.tempBuffers[0].b16i.get(1); |
|
||||||
return new ImageFormat(encodeImageChannelOrder(channelOrder), encodeImageChannelType(channelType)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ImageType getImageType() { |
|
||||||
Utils.tempBuffers[0].b16i.rewind(); |
|
||||||
int ret = cl.clGetMemObjectInfo(id, CL.CL_IMAGE_FORMAT, 5, Utils.tempBuffers[0].b16i, null); |
|
||||||
int type = Utils.tempBuffers[0].b16i.get(0); |
|
||||||
return encodeImageType(type); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getElementSize() { |
|
||||||
return (int) getInfoSize(CL.CL_IMAGE_ELEMENT_SIZE); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[1].put(origin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueReadImage(q, id, CL.CL_TRUE, Utils.pointers[1], Utils.pointers[2], rowPitch, slicePitch, dest, 0, null, null); |
|
||||||
Utils.checkError(ret, "clEnqueueReadImage"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[1].put(origin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueReadImage(q, id, CL.CL_FALSE, Utils.pointers[1], Utils.pointers[2], rowPitch, slicePitch, dest, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueReadImage"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void writeImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[1].put(origin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueWriteImage(q, id, CL.CL_TRUE, Utils.pointers[1], Utils.pointers[2], rowPitch, slicePitch, dest, 0, null, null); |
|
||||||
Utils.checkError(ret, "clEnqueueWriteImage"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event writeImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[1].put(origin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueWriteImage(q, id, CL.CL_FALSE, Utils.pointers[1], Utils.pointers[2], rowPitch, slicePitch, dest, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueWriteImage"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region) { |
|
||||||
if (srcOrigin.length!=3 || destOrigin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[3].rewind(); |
|
||||||
Utils.pointers[1].put(srcOrigin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(destOrigin, 0, 3).position(0); |
|
||||||
Utils.pointers[3].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueCopyImage(q, id, ((JoclImage) dest).id, Utils.pointers[1], Utils.pointers[2], Utils.pointers[3], 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueCopyImage"); |
|
||||||
ret = cl.clWaitForEvents(1, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clWaitForEvents"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region) { |
|
||||||
if (srcOrigin.length!=3 || destOrigin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[3].rewind(); |
|
||||||
Utils.pointers[1].put(srcOrigin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(destOrigin, 0, 3).position(0); |
|
||||||
Utils.pointers[3].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueCopyImage(q, id, ((JoclImage) dest).id, Utils.pointers[1], Utils.pointers[2], Utils.pointers[3], 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueCopyImage"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[3].rewind(); |
|
||||||
Utils.pointers[4].rewind(); |
|
||||||
Utils.pointers[1].put(origin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
long flags = Utils.getMappingAccessFlags(access); |
|
||||||
ByteBuffer buf = cl.clEnqueueMapImage(q, id, CL.CL_TRUE, flags, Utils.pointers[1], Utils.pointers[2], |
|
||||||
Utils.pointers[3], Utils.pointers[4], 0, null, null, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); |
|
||||||
return new ImageMapping(buf, Utils.pointers[3].get(0), Utils.pointers[4].get(0)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[3].rewind(); |
|
||||||
Utils.pointers[4].rewind(); |
|
||||||
Utils.pointers[1].put(origin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(region, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
long flags = Utils.getMappingAccessFlags(access); |
|
||||||
ByteBuffer buf = cl.clEnqueueMapImage(q, id, CL.CL_FALSE, flags, Utils.pointers[1], Utils.pointers[2], |
|
||||||
Utils.pointers[3], Utils.pointers[4], 0, null, Utils.pointers[0], Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clEnqueueMapBuffer"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new ImageMapping(buf, Utils.pointers[3].get(0), Utils.pointers[4].get(0), |
|
||||||
new JoclEvent(event)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void unmap(CommandQueue queue, ImageMapping mapping) { |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
mapping.buffer.position(0); |
|
||||||
int ret = cl.clEnqueueUnmapMemObject(q, id, mapping.buffer, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueUnmapMemObject"); |
|
||||||
ret = cl.clWaitForEvents(1, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clWaitForEvents"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event fillAsync(CommandQueue queue, long[] origin, long[] region, ColorRGBA color) { |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
throw new UnsupportedOperationException("Not supported by Jocl!"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color) { |
|
||||||
if (color.length != 4) { |
|
||||||
throw new IllegalArgumentException("the passed color array must have length 4"); |
|
||||||
} |
|
||||||
if (origin.length!=3 || region.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
throw new UnsupportedOperationException("Not supported by Jocl!"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset) { |
|
||||||
if (srcOrigin.length!=3 || srcRegion.length!=3) { |
|
||||||
throw new IllegalArgumentException("origin and region must both be arrays of length 3"); |
|
||||||
} |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[2].rewind(); |
|
||||||
Utils.pointers[1].put(srcOrigin, 0, 3).position(0); |
|
||||||
Utils.pointers[2].put(srcRegion, 0, 3).position(0); |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueCopyImageToBuffer(q, id, ((JoclBuffer) dest).id, |
|
||||||
Utils.pointers[1], Utils.pointers[2], destOffset, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueCopyImageToBuffer"); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event acquireImageForSharingAsync(CommandQueue queue) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueAcquireGLObjects(q, 1, Utils.pointers[1], 0, null, Utils.pointers[0]); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void acquireImageForSharingNoEvent(CommandQueue queue) { |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueAcquireGLObjects(q, 1, Utils.pointers[1], 0, null, null); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public Event releaseImageForSharingAsync(CommandQueue queue) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueReleaseGLObjects(q, 1, Utils.pointers[1], 0, null, Utils.pointers[0]); |
|
||||||
long event = Utils.pointers[0].get(0); |
|
||||||
return new JoclEvent(event); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void releaseImageForSharingNoEvent(CommandQueue queue) { |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(0, id); |
|
||||||
long q = ((JoclCommandQueue)queue).id; |
|
||||||
((CLGL) cl).clEnqueueReleaseGLObjects(q, 1, Utils.pointers[1], 0, null, null); |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long mem; |
|
||||||
private ReleaserImpl(long mem) { |
|
||||||
this.mem = mem; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (mem != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseMemObject(mem); |
|
||||||
mem = 0; |
|
||||||
Utils.reportError(ret, "clReleaseMemObject"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,290 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.math.Matrix4f; |
|
||||||
import com.jme3.math.Quaternion; |
|
||||||
import com.jme3.math.Vector2f; |
|
||||||
import com.jme3.math.Vector4f; |
|
||||||
import com.jme3.opencl.*; |
|
||||||
import com.jme3.opencl.Buffer; |
|
||||||
import com.jogamp.common.nio.PointerBuffer; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import java.nio.*; |
|
||||||
import java.nio.charset.Charset; |
|
||||||
|
|
||||||
import static com.jogamp.common.os.Platform.is32Bit; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclKernel extends Kernel { |
|
||||||
|
|
||||||
final long kernel; |
|
||||||
final CL cl; |
|
||||||
|
|
||||||
public JoclKernel(long kernel) { |
|
||||||
super(new ReleaserImpl(kernel)); |
|
||||||
this.kernel = kernel; |
|
||||||
this.cl = CLPlatform.getLowLevelCLInterface(); |
|
||||||
OpenCLObjectManager.getInstance().registerObject(this); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getName() { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
int ret = cl.clGetKernelInfo(kernel, CL.CL_KERNEL_FUNCTION_NAME, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clGetKernelInfo"); |
|
||||||
int count = (int) Utils.pointers[0].get(0); |
|
||||||
ByteBuffer buf = ByteBuffer.allocateDirect(count); |
|
||||||
ret = cl.clGetKernelInfo(kernel, CL.CL_KERNEL_FUNCTION_NAME, count, buf, null); |
|
||||||
Utils.checkError(ret, "clGetKernelInfo"); |
|
||||||
byte[] data = new byte[count]; |
|
||||||
buf.get(data); |
|
||||||
return new String(data, Charset.forName("ASCII")); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getArgCount() { |
|
||||||
Utils.tempBuffers[0].b16i.rewind(); |
|
||||||
int ret = cl.clGetKernelInfo(kernel, CL.CL_KERNEL_NUM_ARGS, 4, Utils.tempBuffers[0].b16i, null); |
|
||||||
Utils.checkError(ret, "clGetKernelInfo"); |
|
||||||
return Utils.tempBuffers[0].b16i.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long getMaxWorkGroupSize(Device device) { |
|
||||||
long d = ((JoclDevice) device).id; |
|
||||||
Utils.tempBuffers[0].b16l.rewind(); |
|
||||||
int ret = cl.clGetKernelWorkGroupInfo(kernel, d, CL.CL_KERNEL_WORK_GROUP_SIZE, 8, Utils.tempBuffers[0].b16l, null); |
|
||||||
Utils.checkError(ret, "clGetKernelWorkGroupInfo"); |
|
||||||
return Utils.tempBuffers[0].b16l.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, LocalMemPerElement t) { |
|
||||||
int ret = cl.clSetKernelArg (kernel, index, t.getSize() * workGroupSize.getSizes()[0] * workGroupSize.getSizes()[1] * workGroupSize.getSizes()[2], null); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, LocalMem t) { |
|
||||||
int ret = cl.clSetKernelArg (kernel, index, t.getSize(), null); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, Buffer t) { |
|
||||||
Utils.tempBuffers[0].b16l.rewind(); |
|
||||||
Utils.tempBuffers[0].b16l.put(0, ((JoclBuffer) t).id); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, is32Bit()?4:8, Utils.tempBuffers[0].b16l); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, Image i) { |
|
||||||
Utils.tempBuffers[0].b16l.rewind(); |
|
||||||
Utils.tempBuffers[0].b16l.put(0, ((JoclImage) i).id); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, is32Bit()?4:8, Utils.tempBuffers[0].b16l); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, byte b) { |
|
||||||
ByteBuffer buf = Utils.tempBuffers[0].b16; |
|
||||||
buf.position(0); |
|
||||||
buf.put(0, b); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 1, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, short s) { |
|
||||||
ShortBuffer buf = Utils.tempBuffers[0].b16s; |
|
||||||
buf.position(0); |
|
||||||
buf.put(0, s); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 2, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, int i) { |
|
||||||
IntBuffer buf = Utils.tempBuffers[0].b16i; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(1); |
|
||||||
buf.put(0, i); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 4, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, long l) { |
|
||||||
LongBuffer buf = Utils.tempBuffers[0].b16l; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(1); |
|
||||||
buf.put(0, l); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 8, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, float f) { |
|
||||||
FloatBuffer buf = Utils.tempBuffers[0].b16f; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(1); |
|
||||||
buf.put(0, f); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 4, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, double d) { |
|
||||||
DoubleBuffer buf = Utils.tempBuffers[0].b16d; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(1); |
|
||||||
buf.put(0, d); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 8, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, Vector2f v) { |
|
||||||
FloatBuffer buf = Utils.tempBuffers[0].b16f; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(2); |
|
||||||
buf.put(0, v.x); |
|
||||||
buf.put(1, v.y); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 8, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, Vector4f v) { |
|
||||||
FloatBuffer buf = Utils.tempBuffers[0].b16f; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(4); |
|
||||||
buf.put(0, v.x); |
|
||||||
buf.put(1, v.y); |
|
||||||
buf.put(2, v.z); |
|
||||||
buf.put(3, v.w); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 16, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, Quaternion q) { |
|
||||||
FloatBuffer buf = Utils.tempBuffers[0].b16f; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(4); |
|
||||||
buf.put(0, q.getX()); |
|
||||||
buf.put(1, q.getY()); |
|
||||||
buf.put(2, q.getZ()); |
|
||||||
buf.put(3, q.getW()); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 16, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, Matrix4f m) { |
|
||||||
FloatBuffer buf = Utils.b80f; |
|
||||||
buf.position(0); |
|
||||||
buf.limit(16); |
|
||||||
buf.put(m.m00).put(m.m01).put(m.m02).put(m.m03); |
|
||||||
buf.put(m.m10).put(m.m11).put(m.m12).put(m.m13); |
|
||||||
buf.put(m.m20).put(m.m21).put(m.m22).put(m.m23); |
|
||||||
buf.put(m.m30).put(m.m31).put(m.m32).put(m.m33); |
|
||||||
buf.position(0); |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, 16*4, buf); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setArg(int index, ByteBuffer buffer, long size) { |
|
||||||
int ret = cl.clSetKernelArg(kernel, index, size, buffer); |
|
||||||
Utils.checkError(ret, "clSetKernelArg"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Event Run(CommandQueue queue) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(globalWorkSize.getSizes(), 0, globalWorkSize.getSizes().length); |
|
||||||
Utils.pointers[1].position(0); |
|
||||||
PointerBuffer p2 = null; |
|
||||||
if (workGroupSize.getSizes()[0] > 0) { |
|
||||||
p2 = Utils.pointers[2].rewind(); |
|
||||||
p2.put(workGroupSize.getSizes(), 0, workGroupSize.getSizes().length); |
|
||||||
p2.position(0); |
|
||||||
} |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueNDRangeKernel(q, kernel, |
|
||||||
globalWorkSize.getDimension(), null, Utils.pointers[1], |
|
||||||
p2, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clEnqueueNDRangeKernel"); |
|
||||||
return new JoclEvent(Utils.pointers[0].get(0)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void RunNoEvent(CommandQueue queue) { |
|
||||||
Utils.pointers[1].rewind(); |
|
||||||
Utils.pointers[1].put(globalWorkSize.getSizes(), 0, globalWorkSize.getSizes().length); |
|
||||||
Utils.pointers[1].position(0); |
|
||||||
PointerBuffer p2 = null; |
|
||||||
if (workGroupSize.getSizes()[0] > 0) { |
|
||||||
p2 = Utils.pointers[2].rewind(); |
|
||||||
p2.put(workGroupSize.getSizes(), 0, workGroupSize.getSizes().length); |
|
||||||
p2.position(0); |
|
||||||
} |
|
||||||
long q = ((JoclCommandQueue) queue).id; |
|
||||||
int ret = cl.clEnqueueNDRangeKernel(q, kernel, |
|
||||||
globalWorkSize.getDimension(), null, Utils.pointers[1], |
|
||||||
p2, 0, null, null); |
|
||||||
Utils.checkError(ret, "clEnqueueNDRangeKernel"); |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long kernel; |
|
||||||
private ReleaserImpl(long kernel) { |
|
||||||
this.kernel = kernel; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (kernel != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseKernel(kernel); |
|
||||||
kernel = 0; |
|
||||||
Utils.reportError(ret, "clReleaseKernel"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,129 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.Platform; |
|
||||||
import com.jogamp.opencl.CLDevice; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collection; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public final class JoclPlatform implements Platform { |
|
||||||
|
|
||||||
final CLPlatform platform; |
|
||||||
List<JoclDevice> devices; |
|
||||||
|
|
||||||
public JoclPlatform(CLPlatform platform) { |
|
||||||
this.platform = platform; |
|
||||||
} |
|
||||||
|
|
||||||
public CLPlatform getPlatform() { |
|
||||||
return platform; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public List<JoclDevice> getDevices() { |
|
||||||
if (devices == null) { |
|
||||||
devices = new ArrayList<>(); |
|
||||||
for (CLDevice d : platform.listCLDevices()) { |
|
||||||
devices.add(new JoclDevice(d, this)); |
|
||||||
} |
|
||||||
} |
|
||||||
return devices; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getProfile() { |
|
||||||
return platform.getProfile(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isFullProfile() { |
|
||||||
return getProfile().contains("FULL_PROFILE"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isEmbeddedProfile() { |
|
||||||
return getProfile().contains("EMBEDDED_PROFILE"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getVersion() { |
|
||||||
return platform.getVendor(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getVersionMajor() { |
|
||||||
return Utils.getMajorVersion(getVersion(), "OpenCL "); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int getVersionMinor() { |
|
||||||
return Utils.getMinorVersion(getVersion(), "OpenCL "); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getName() { |
|
||||||
return platform.getName(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getVendor() { |
|
||||||
return platform.getVendor(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasExtension(String extension) { |
|
||||||
return getExtensions().contains(extension); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasOpenGLInterop() { |
|
||||||
return hasExtension("cl_khr_gl_sharing"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Collection<? extends String> getExtensions() { |
|
||||||
return platform.getExtensions(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String toString() { |
|
||||||
return getName(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,193 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.*; |
|
||||||
import com.jogamp.common.nio.Buffers; |
|
||||||
import com.jogamp.common.nio.PointerBuffer; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import com.jogamp.opencl.util.CLUtil; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import static com.jogamp.common.nio.Buffers.newDirectByteBuffer; |
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class JoclProgram extends Program { |
|
||||||
private static final Logger LOG = Logger.getLogger(JoclProgram.class.getName()); |
|
||||||
|
|
||||||
final long program; |
|
||||||
final CL cl; |
|
||||||
private final JoclContext context; |
|
||||||
|
|
||||||
public JoclProgram(long program, JoclContext context) { |
|
||||||
super(new ReleaserImpl(program)); |
|
||||||
this.program = program; |
|
||||||
this.context = context; |
|
||||||
this.cl = CLPlatform.getLowLevelCLInterface(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void build(String args, Device... devices) throws KernelCompilationException { |
|
||||||
PointerBuffer deviceList = null; |
|
||||||
int deviceCount = 0; |
|
||||||
if (devices != null) { |
|
||||||
deviceList = PointerBuffer.allocateDirect(devices.length); |
|
||||||
for (Device d : devices) { |
|
||||||
deviceList.put(((JoclDevice) d).id); |
|
||||||
} |
|
||||||
deviceCount = devices.length; |
|
||||||
deviceList.rewind(); |
|
||||||
} |
|
||||||
int ret = cl.clBuildProgram(program, deviceCount, deviceList, args, null); |
|
||||||
if (ret != CL.CL_SUCCESS) { |
|
||||||
String log = Log(); |
|
||||||
LOG.log(Level.WARNING, "Unable to compile program:\n{0}", log); |
|
||||||
if (ret == CL.CL_BUILD_PROGRAM_FAILURE) { |
|
||||||
throw new KernelCompilationException("Failed to build program", ret, log); |
|
||||||
} else { |
|
||||||
Utils.checkError(ret, "clBuildProgram"); |
|
||||||
} |
|
||||||
} else { |
|
||||||
LOG.log(Level.INFO, "Program compiled:\n{0}", Log()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private String Log(long device) { |
|
||||||
Utils.pointers[0].rewind(); |
|
||||||
int ret = cl.clGetProgramBuildInfo(program, device, CL.CL_PROGRAM_BUILD_LOG, 0, null, Utils.pointers[0]); |
|
||||||
Utils.checkError(ret, "clGetProgramBuildInfo"); |
|
||||||
int count = (int) Utils.pointers[0].get(0); |
|
||||||
final ByteBuffer buffer = newDirectByteBuffer(count); |
|
||||||
ret = cl.clGetProgramBuildInfo(program, device, CL.CL_PROGRAM_BUILD_LOG, buffer.capacity(), buffer, null); |
|
||||||
Utils.checkError(ret, "clGetProgramBuildInfo"); |
|
||||||
return CLUtil.clString2JavaString(buffer, count); |
|
||||||
} |
|
||||||
|
|
||||||
private String Log() { |
|
||||||
StringBuilder str = new StringBuilder(); |
|
||||||
for (JoclDevice device : context.getDevices()) { |
|
||||||
long d = device.id; |
|
||||||
str.append(device.getName()).append(":\n"); |
|
||||||
str.append(Log(d)); |
|
||||||
str.append('\n'); |
|
||||||
} |
|
||||||
return str.toString(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Kernel createKernel(String name) { |
|
||||||
Utils.errorBuffer.rewind(); |
|
||||||
long kernel = cl.clCreateKernel(program, name, Utils.errorBuffer); |
|
||||||
Utils.checkError(Utils.errorBuffer, "clCreateKernel"); |
|
||||||
return new JoclKernel(kernel); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Kernel[] createAllKernels() { |
|
||||||
Utils.tempBuffers[0].b16i.rewind(); |
|
||||||
int ret = cl.clCreateKernelsInProgram(program, 0, null, Utils.tempBuffers[0].b16i); |
|
||||||
Utils.checkError(ret, "clCreateKernelsInProgram"); |
|
||||||
int count = Utils.tempBuffers[0].b16i.get(0); |
|
||||||
PointerBuffer buf = PointerBuffer.allocateDirect(count); |
|
||||||
ret = cl.clCreateKernelsInProgram(program, count, buf, null); |
|
||||||
Utils.checkError(ret, "clCreateKernelsInProgram"); |
|
||||||
Kernel[] kx = new Kernel[count]; |
|
||||||
for (int i=0; i<count; ++i) { |
|
||||||
kx[i] = new JoclKernel(buf.get()); |
|
||||||
} |
|
||||||
return kx; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ByteBuffer getBinary(Device d) { |
|
||||||
|
|
||||||
JoclDevice device = (JoclDevice) d; |
|
||||||
|
|
||||||
Utils.tempBuffers[0].b16i.rewind(); |
|
||||||
int ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_NUM_DEVICES, 4, Utils.tempBuffers[0].b16i, null); |
|
||||||
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_NUM_DEVICES"); |
|
||||||
int numDevices = Utils.tempBuffers[0].b16i.get(0); |
|
||||||
|
|
||||||
PointerBuffer devices = PointerBuffer.allocateDirect(numDevices); |
|
||||||
ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_DEVICES, numDevices * PointerBuffer.ELEMENT_SIZE, devices.getBuffer(), null); |
|
||||||
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_DEVICES"); |
|
||||||
int index = -1; |
|
||||||
for (int i=0; i<numDevices; ++i) { |
|
||||||
if (devices.get(i) == device.id) { |
|
||||||
index = i; |
|
||||||
} |
|
||||||
} |
|
||||||
if (index == -1) { |
|
||||||
throw new com.jme3.opencl.OpenCLException("Program was not built against the specified device "+device); |
|
||||||
} |
|
||||||
|
|
||||||
final PointerBuffer sizes = PointerBuffer.allocateDirect(numDevices); |
|
||||||
ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_BINARY_SIZES, numDevices * PointerBuffer.ELEMENT_SIZE, sizes.getBuffer(), null); |
|
||||||
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_BINARY_SIZES"); |
|
||||||
|
|
||||||
final ByteBuffer binaries = Buffers.newDirectByteBuffer((int) sizes.get(index)); |
|
||||||
final PointerBuffer addresses = PointerBuffer.allocateDirect(numDevices); |
|
||||||
for (int i=0; i<numDevices; ++i) { |
|
||||||
if (index == i) { |
|
||||||
addresses.referenceBuffer(binaries); |
|
||||||
} else { |
|
||||||
addresses.put(0); |
|
||||||
} |
|
||||||
} |
|
||||||
addresses.rewind(); |
|
||||||
|
|
||||||
ret = cl.clGetProgramInfo(program, CL.CL_PROGRAM_BINARIES, numDevices * PointerBuffer.ELEMENT_SIZE, addresses.getBuffer(), null); |
|
||||||
Utils.checkError(ret, "clGetProgramInfo: CL_PROGRAM_BINARIES"); |
|
||||||
|
|
||||||
return binaries; |
|
||||||
} |
|
||||||
|
|
||||||
private static class ReleaserImpl implements ObjectReleaser { |
|
||||||
private long program; |
|
||||||
private ReleaserImpl(long program) { |
|
||||||
this.program = program; |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void release() { |
|
||||||
if (program != 0) { |
|
||||||
int ret = CLPlatform.getLowLevelCLInterface().clReleaseProgram(program); |
|
||||||
program = 0; |
|
||||||
Utils.reportError(ret, "clReleaseProgram"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,156 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2016 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.opencl.jocl; |
|
||||||
|
|
||||||
import com.jme3.opencl.MappingAccess; |
|
||||||
import com.jme3.opencl.MemoryAccess; |
|
||||||
import com.jme3.opencl.OpenCLException; |
|
||||||
import com.jme3.util.BufferUtils; |
|
||||||
import com.jogamp.common.nio.PointerBuffer; |
|
||||||
import com.jogamp.opencl.CLException; |
|
||||||
import com.jogamp.opencl.llb.CL; |
|
||||||
import java.nio.*; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author shaman |
|
||||||
*/ |
|
||||||
public class Utils { |
|
||||||
private static final Logger LOG = Logger.getLogger(Utils.class.getName()); |
|
||||||
private Utils() {} |
|
||||||
|
|
||||||
public static int getMajorVersion(String version, String prefix) { |
|
||||||
String s = version.substring(prefix.length()); |
|
||||||
return Integer.parseInt(s); |
|
||||||
} |
|
||||||
|
|
||||||
public static int getMinorVersion(String version, String prefix) { |
|
||||||
String s = version.substring(prefix.length()); |
|
||||||
int major = Integer.parseInt(s); |
|
||||||
s = s.substring((int) (Math.log10(major) + 2)); |
|
||||||
return Integer.parseInt(s); |
|
||||||
} |
|
||||||
|
|
||||||
public static final class TempBuffer { |
|
||||||
public final ByteBuffer b16; |
|
||||||
public final ShortBuffer b16s; |
|
||||||
public final IntBuffer b16i; |
|
||||||
public final LongBuffer b16l; |
|
||||||
public final FloatBuffer b16f; |
|
||||||
public final DoubleBuffer b16d; |
|
||||||
public TempBuffer() { |
|
||||||
b16 = BufferUtils.createByteBuffer(16); |
|
||||||
b16s = b16.asShortBuffer(); |
|
||||||
b16i = b16.asIntBuffer(); |
|
||||||
b16l = b16.asLongBuffer(); |
|
||||||
b16f = b16.asFloatBuffer(); |
|
||||||
b16d = b16.asDoubleBuffer(); |
|
||||||
} |
|
||||||
} |
|
||||||
public static final ByteBuffer b80; //needed for ImageDescriptor
|
|
||||||
public static final LongBuffer b80l; |
|
||||||
public static final FloatBuffer b80f; |
|
||||||
public static final TempBuffer[] tempBuffers = new TempBuffer[8]; |
|
||||||
public static final PointerBuffer[] pointers = new PointerBuffer[8]; |
|
||||||
static { |
|
||||||
for (int i=0; i<8; ++i) { |
|
||||||
tempBuffers[i] = new TempBuffer(); |
|
||||||
pointers[i] = PointerBuffer.allocateDirect(4); |
|
||||||
} |
|
||||||
errorBuffer = BufferUtils.createIntBuffer(1); |
|
||||||
b80 = BufferUtils.createByteBuffer(80); |
|
||||||
b80l = b80.asLongBuffer(); |
|
||||||
b80f = b80.asFloatBuffer(); |
|
||||||
} |
|
||||||
|
|
||||||
public static IntBuffer errorBuffer; |
|
||||||
public static void checkError(IntBuffer errorBuffer, String callName) { |
|
||||||
checkError(errorBuffer.get(0), callName); |
|
||||||
} |
|
||||||
public static void checkError(int error, String callName) { |
|
||||||
if (error != CL.CL_SUCCESS) { |
|
||||||
String errname = getErrorName(error); |
|
||||||
if (errname == null) { |
|
||||||
errname = "UNKNOWN"; |
|
||||||
} |
|
||||||
throw new OpenCLException("OpenCL error in " + callName + ": " + errname + " (0x" + Integer.toHexString(error) + ")", error); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void reportError(int error, String callName) { |
|
||||||
if (error != CL.CL_SUCCESS) { |
|
||||||
String errname = getErrorName(error); |
|
||||||
if (errname == null) { |
|
||||||
errname = "UNKNOWN"; |
|
||||||
} |
|
||||||
LOG.log(Level.WARNING, "OpenCL error in {0}: {1} (0x{2})", new Object[]{callName, errname, Integer.toHexString(error)}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static String getErrorName(int code) { |
|
||||||
return CLException.resolveErrorCode(code); |
|
||||||
} |
|
||||||
|
|
||||||
public static long getMemoryAccessFlags(MemoryAccess ma) { |
|
||||||
switch (ma) { |
|
||||||
case READ_ONLY: return CL.CL_MEM_READ_ONLY; |
|
||||||
case WRITE_ONLY: return CL.CL_MEM_WRITE_ONLY; |
|
||||||
case READ_WRITE: return CL.CL_MEM_READ_WRITE; |
|
||||||
default: throw new IllegalArgumentException("Unknown memory access: "+ma); |
|
||||||
} |
|
||||||
} |
|
||||||
public static MemoryAccess getMemoryAccessFromFlag(long flag) { |
|
||||||
if ((flag & CL.CL_MEM_READ_WRITE) > 0) { |
|
||||||
return MemoryAccess.READ_WRITE; |
|
||||||
} |
|
||||||
if ((flag & CL.CL_MEM_READ_ONLY) > 0) { |
|
||||||
return MemoryAccess.READ_ONLY; |
|
||||||
} |
|
||||||
if ((flag & CL.CL_MEM_WRITE_ONLY) > 0) { |
|
||||||
return MemoryAccess.WRITE_ONLY; |
|
||||||
} |
|
||||||
throw new OpenCLException("Unknown memory access flag: "+flag); |
|
||||||
} |
|
||||||
|
|
||||||
public static long getMappingAccessFlags(MappingAccess ma) { |
|
||||||
switch (ma) { |
|
||||||
case MAP_READ_ONLY: return CL.CL_MAP_READ; |
|
||||||
case MAP_READ_WRITE: return CL.CL_MAP_READ | CL.CL_MAP_WRITE; |
|
||||||
case MAP_WRITE_ONLY: return CL.CL_MAP_WRITE; |
|
||||||
case MAP_WRITE_INVALIDATE: return CL.CL_MAP_WRITE; //MAP_WRITE_INVALIDATE_REGION not supported
|
|
||||||
default: throw new IllegalArgumentException("Unknown mapping access: "+ma); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,662 +0,0 @@ |
|||||||
package com.jme3.renderer.jogl; |
|
||||||
|
|
||||||
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.jogamp.opengl.GLContext; |
|
||||||
|
|
||||||
import java.nio.*; |
|
||||||
|
|
||||||
public class JoglGL implements GL, GL2, GL3, GL4 { |
|
||||||
|
|
||||||
private static int getLimitBytes(ByteBuffer buffer) { |
|
||||||
checkLimit(buffer); |
|
||||||
return buffer.limit(); |
|
||||||
} |
|
||||||
|
|
||||||
private static int getLimitBytes(ShortBuffer buffer) { |
|
||||||
checkLimit(buffer); |
|
||||||
return buffer.limit() * 2; |
|
||||||
} |
|
||||||
|
|
||||||
private static int getLimitBytes(FloatBuffer buffer) { |
|
||||||
checkLimit(buffer); |
|
||||||
return buffer.limit() * 4; |
|
||||||
} |
|
||||||
|
|
||||||
private static int getLimitCount(Buffer buffer, int elementSize) { |
|
||||||
checkLimit(buffer); |
|
||||||
return buffer.limit() / elementSize; |
|
||||||
} |
|
||||||
|
|
||||||
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 resetStats() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glActiveTexture(int param1) { |
|
||||||
GLContext.getCurrentGL().glActiveTexture(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glAlphaFunc(int param1, float param2) { |
|
||||||
GLContext.getCurrentGL().getGL2ES1().glAlphaFunc(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glAttachShader(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glAttachShader(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBeginQuery(int target, int query) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glBeginQuery(target, query); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindBuffer(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().glBindBuffer(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindTexture(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().glBindTexture(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBlendEquationSeparate(int colorMode, int alphaMode){ |
|
||||||
GLContext.getCurrentGL().glBlendEquationSeparate(colorMode, alphaMode); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBlendFunc(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().glBlendFunc(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha) { |
|
||||||
GLContext.getCurrentGL().glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferData(int param1, long param2, int param3) { |
|
||||||
GLContext.getCurrentGL().glBufferData(param1, param2, null, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferData(int param1, FloatBuffer param2, int param3) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().glBufferData(param1, getLimitBytes(param2), param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferData(int param1, ShortBuffer param2, int param3) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().glBufferData(param1, getLimitBytes(param2), param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferData(int param1, ByteBuffer param2, int param3) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().glBufferData(param1, getLimitBytes(param2), param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferSubData(int param1, long param2, FloatBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().glBufferSubData(param1, param2, getLimitBytes(param3), param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferSubData(int param1, long param2, ShortBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().glBufferSubData(param1, param2, getLimitBytes(param3), param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferSubData(int param1, long param2, ByteBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().glBufferSubData(param1, param2, getLimitBytes(param3), param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glClear(int param1) { |
|
||||||
GLContext.getCurrentGL().glClear(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glClearColor(float param1, float param2, float param3, float param4) { |
|
||||||
GLContext.getCurrentGL().glClearColor(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glColorMask(boolean param1, boolean param2, boolean param3, boolean param4) { |
|
||||||
GLContext.getCurrentGL().glColorMask(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glCompileShader(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glCompileShader(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glCompressedTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) { |
|
||||||
checkLimit(param7); |
|
||||||
GLContext.getCurrentGL().glCompressedTexImage2D(param1, param2, param3, param4, param5, param6, getLimitBytes(param7), param7); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glCompressedTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) { |
|
||||||
checkLimit(param8); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glCompressedTexImage3D(param1, param2, param3, param4, param5, param6, param7, getLimitBytes(param8), param8); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glCompressedTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) { |
|
||||||
checkLimit(param8); |
|
||||||
GLContext.getCurrentGL().glCompressedTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, getLimitBytes(param8), param8); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
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); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glCompressedTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, getLimitBytes(param10), param10); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glCreateProgram() { |
|
||||||
return GLContext.getCurrentGL().getGL2ES2().glCreateProgram(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glCreateShader(int param1) { |
|
||||||
return GLContext.getCurrentGL().getGL2ES2().glCreateShader(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glCullFace(int param1) { |
|
||||||
GLContext.getCurrentGL().glCullFace(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteBuffers(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glDeleteBuffers(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteProgram(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glDeleteProgram(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteShader(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glDeleteShader(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteTextures(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glDeleteTextures(param1.limit() ,param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDepthFunc(int param1) { |
|
||||||
GLContext.getCurrentGL().glDepthFunc(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDepthMask(boolean param1) { |
|
||||||
GLContext.getCurrentGL().glDepthMask(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDepthRange(double param1, double param2) { |
|
||||||
GLContext.getCurrentGL().glDepthRange(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDetachShader(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glDetachShader(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDisable(int param1) { |
|
||||||
GLContext.getCurrentGL().glDisable(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDisableVertexAttribArray(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glDisableVertexAttribArray(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDrawArrays(int param1, int param2, int param3) { |
|
||||||
GLContext.getCurrentGL().glDrawArrays(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDrawBuffer(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2GL3().glDrawBuffer(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDrawRangeElements(int param1, int param2, int param3, int param4, int param5, long param6) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glDrawRangeElements(param1, param2, param3, param4, param5, param6); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glEnable(int param1) { |
|
||||||
GLContext.getCurrentGL().glEnable(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glEnableVertexAttribArray(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glEnableVertexAttribArray(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glEndQuery(int target) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glEndQuery(target); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenBuffers(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glGenBuffers(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenQueries(int num, IntBuffer buff) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGenQueries(num, buff); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenTextures(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glGenTextures(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGetBoolean(int param1, ByteBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().glGetBooleanv(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGetBufferSubData(int target, long offset, ByteBuffer data) { |
|
||||||
checkLimit(data); |
|
||||||
GLContext.getCurrentGL().getGL2GL3().glGetBufferSubData(target, offset, getLimitBytes(data), data); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glGetError() { |
|
||||||
return GLContext.getCurrentGL().glGetError(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGetInteger(int param1, IntBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().glGetIntegerv(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGetProgram(int param1, int param2, IntBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetProgramiv(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGetShader(int param1, int param2, IntBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetShaderiv(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String glGetString(int param1) { |
|
||||||
return GLContext.getCurrentGL().glGetString(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String glGetString(int param1, int param2) { |
|
||||||
return GLContext.getCurrentGL().getGL2ES3().glGetStringi(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean glIsEnabled(int param1) { |
|
||||||
return GLContext.getCurrentGL().glIsEnabled(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glLineWidth(float param1) { |
|
||||||
GLContext.getCurrentGL().glLineWidth(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glLinkProgram(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glLinkProgram(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glPixelStorei(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().glPixelStorei(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glPointSize(float param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES1().glPointSize(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glPolygonMode(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().getGL2().glPolygonMode(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glPolygonOffset(float param1, float param2) { |
|
||||||
GLContext.getCurrentGL().glPolygonOffset(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glReadBuffer(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glReadBuffer(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) { |
|
||||||
checkLimit(param7); |
|
||||||
GLContext.getCurrentGL().glReadPixels(param1, param2, param3, param4, param5, param6, param7); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, long param7) { |
|
||||||
GLContext.getCurrentGL().glReadPixels(param1, param2, param3, param4, param5, param6, param7); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glScissor(int param1, int param2, int param3, int param4) { |
|
||||||
GLContext.getCurrentGL().glScissor(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glStencilFuncSeparate(int param1, int param2, int param3, int param4) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glStencilFuncSeparate(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glStencilOpSeparate(int param1, int param2, int param3, int param4) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glStencilOpSeparate(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) { |
|
||||||
checkLimit(param9); |
|
||||||
GLContext.getCurrentGL().glTexImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
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); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glTexImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glTexParameterf(int param1, int param2, float param3) { |
|
||||||
GLContext.getCurrentGL().glTexParameterf(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glTexParameteri(int param1, int param2, int param3) { |
|
||||||
GLContext.getCurrentGL().glTexParameteri(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) { |
|
||||||
checkLimit(param9); |
|
||||||
GLContext.getCurrentGL().glTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
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); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform1(int param1, FloatBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform1fv(param1, getLimitCount(param2, 1), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform1(int param1, IntBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform1iv(param1, getLimitCount(param2, 1), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform1f(int param1, float param2) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform1f(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform1i(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform1i(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform2(int param1, IntBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform2iv(param1, getLimitCount(param2, 2), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform2(int param1, FloatBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform2fv(param1, getLimitCount(param2, 2), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform2f(int param1, float param2, float param3) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform2f(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform3(int param1, IntBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform3iv(param1, getLimitCount(param2, 3), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform3(int param1, FloatBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform3fv(param1, getLimitCount(param2, 3), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform3f(int param1, float param2, float param3, float param4) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform3f(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform4(int param1, FloatBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform4fv(param1, getLimitCount(param2, 4), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform4(int param1, IntBuffer param2) { |
|
||||||
checkLimit(param2); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform4iv(param1, getLimitCount(param2, 4), param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniform4f(int param1, float param2, float param3, float param4, float param5) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniform4f(param1, param2, param3, param4, param5); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniformMatrix3(int param1, boolean param2, FloatBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniformMatrix3fv(param1, getLimitCount(param3, 3 * 3), param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniformMatrix4(int param1, boolean param2, FloatBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUniformMatrix4fv(param1, getLimitCount(param3, 4 * 4), param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUseProgram(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glUseProgram(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glVertexAttribPointer(int param1, int param2, int param3, boolean param4, int param5, long param6) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glVertexAttribPointer(param1, param2, param3, param4, param5, param6); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glViewport(int param1, int param2, int param3, int param4) { |
|
||||||
GLContext.getCurrentGL().glViewport(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glGetAttribLocation(int param1, String param2) { |
|
||||||
// JOGL 2.0 doesn't need a null-terminated string
|
|
||||||
return GLContext.getCurrentGL().getGL2ES2().glGetAttribLocation(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glGetUniformLocation(int param1, String param2) { |
|
||||||
// JOGL 2.0 doesn't need a null-terminated string
|
|
||||||
return GLContext.getCurrentGL().getGL2ES2().glGetUniformLocation(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glShaderSource(int param1, String[] param2, IntBuffer param3) { |
|
||||||
checkLimit(param3); |
|
||||||
|
|
||||||
int param3pos = param3.position(); |
|
||||||
try { |
|
||||||
for (final String param2string : param2) { |
|
||||||
param3.put(Math.max(param2string.length(), param2string.getBytes().length)); |
|
||||||
} |
|
||||||
} finally { |
|
||||||
param3.position(param3pos); |
|
||||||
} |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glShaderSource(param1, param2.length, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String glGetProgramInfoLog(int program, int maxSize) { |
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(maxSize); |
|
||||||
buffer.order(ByteOrder.nativeOrder()); |
|
||||||
ByteBuffer tmp = ByteBuffer.allocateDirect(4); |
|
||||||
tmp.order(ByteOrder.nativeOrder()); |
|
||||||
IntBuffer intBuffer = tmp.asIntBuffer(); |
|
||||||
|
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetProgramInfoLog(program, maxSize, intBuffer, buffer); |
|
||||||
int numBytes = intBuffer.get(0); |
|
||||||
byte[] bytes = new byte[numBytes]; |
|
||||||
buffer.get(bytes); |
|
||||||
return new String(bytes); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public long glGetQueryObjectui64(int query, int target) { |
|
||||||
LongBuffer buff = LongBuffer.allocate(1); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetQueryObjectui64v(query, target, buff); |
|
||||||
return buff.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glGetQueryObjectiv(int query, int pname) { |
|
||||||
IntBuffer buff = IntBuffer.allocate(1); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetQueryObjectiv(query, pname, buff); |
|
||||||
return buff.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String glGetShaderInfoLog(int shader, int maxSize) { |
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(maxSize); |
|
||||||
buffer.order(ByteOrder.nativeOrder()); |
|
||||||
ByteBuffer tmp = ByteBuffer.allocateDirect(4); |
|
||||||
tmp.order(ByteOrder.nativeOrder()); |
|
||||||
IntBuffer intBuffer = tmp.asIntBuffer(); |
|
||||||
|
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetShaderInfoLog(shader, maxSize, intBuffer, buffer); |
|
||||||
int numBytes = intBuffer.get(0); |
|
||||||
byte[] bytes = new byte[numBytes]; |
|
||||||
buffer.get(bytes); |
|
||||||
return new String(bytes); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindFragDataLocation(int param1, int param2, String param3) { |
|
||||||
GLContext.getCurrentGL().getGL2GL3().glBindFragDataLocation(param1, param2, param3); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindVertexArray(int param1) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glBindVertexArray(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenVertexArrays(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glGenVertexArrays(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glPatchParameter(int count) { |
|
||||||
GLContext.getCurrentGL().getGL3().glPatchParameteri(com.jogamp.opengl.GL3.GL_PATCH_VERTICES, count); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteVertexArrays(IntBuffer arrays) { |
|
||||||
checkLimit(arrays); |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glDeleteVertexArrays(arrays.limit(), arrays); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glGetUniformBlockIndex(final int program, final String uniformBlockName) { |
|
||||||
return GLContext.getCurrentGL().getGL3bc().glGetUniformBlockIndex(program, uniformBlockName); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindBufferBase(final int target, final int index, final int buffer) { |
|
||||||
GLContext.getCurrentGL().getGL3bc().glBindBufferBase(target, index, buffer); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glGetProgramResourceIndex(final int program, final int programInterface, final String name) { |
|
||||||
throw new UnsupportedOperationException(); |
|
||||||
//return GLContext.getCurrentGL().getGL4bc().glGetProgramResourceIndex(program, programInterface, name);
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glShaderStorageBlockBinding(final int program, final int storageBlockIndex, final int storageBlockBinding) { |
|
||||||
GLContext.getCurrentGL().getGL4bc().glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { |
|
||||||
GLContext.getCurrentGL().getGL3bc().glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); |
|
||||||
} |
|
||||||
} |
|
@ -1,88 +0,0 @@ |
|||||||
package com.jme3.renderer.jogl; |
|
||||||
|
|
||||||
import com.jme3.renderer.RendererException; |
|
||||||
import com.jme3.renderer.opengl.GLExt; |
|
||||||
import com.jogamp.opengl.GLContext; |
|
||||||
|
|
||||||
import java.nio.Buffer; |
|
||||||
import java.nio.FloatBuffer; |
|
||||||
import java.nio.IntBuffer; |
|
||||||
|
|
||||||
public class JoglGLExt implements GLExt { |
|
||||||
|
|
||||||
private static int getLimitBytes(IntBuffer buffer) { |
|
||||||
checkLimit(buffer); |
|
||||||
return buffer.limit() * 4; |
|
||||||
} |
|
||||||
|
|
||||||
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); |
|
||||||
GLContext.getCurrentGL().glBufferData(target, getLimitBytes(data), data, usage); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBufferSubData(int target, long offset, IntBuffer data) { |
|
||||||
checkLimit(data); |
|
||||||
GLContext.getCurrentGL().glBufferSubData(target, getLimitBytes(data), offset, data); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glDrawArraysInstanced(mode, first, count, primcount); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDrawBuffers(IntBuffer bufs) { |
|
||||||
checkLimit(bufs); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glDrawBuffers(bufs.limit(), bufs); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glDrawElementsInstanced(mode, indices_count, type, indices_buffer_offset, primcount); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGetMultisample(int pname, int index, FloatBuffer val) { |
|
||||||
checkLimit(val); |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glGetMultisamplefv(pname, index, val); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations) { |
|
||||||
GLContext.getCurrentGL().getGL2ES2().glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glVertexAttribDivisorARB(int index, int divisor) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().glVertexAttribDivisor(index, divisor); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Object glFenceSync(int condition, int flags) { |
|
||||||
return GLContext.getCurrentGL().getGL3ES3().glFenceSync(condition, flags); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glClientWaitSync(Object sync, int flags, long timeout) { |
|
||||||
return GLContext.getCurrentGL().getGL3ES3().glClientWaitSync(((Long) sync).longValue(), flags, timeout); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteSync(Object sync) { |
|
||||||
GLContext.getCurrentGL().getGL3ES3().glDeleteSync(((Long) sync).longValue()); |
|
||||||
} |
|
||||||
} |
|
@ -1,102 +0,0 @@ |
|||||||
package com.jme3.renderer.jogl; |
|
||||||
|
|
||||||
import com.jme3.renderer.RendererException; |
|
||||||
import com.jme3.renderer.opengl.GLFbo; |
|
||||||
import com.jogamp.opengl.GLContext; |
|
||||||
|
|
||||||
import java.nio.Buffer; |
|
||||||
import java.nio.IntBuffer; |
|
||||||
|
|
||||||
/** |
|
||||||
* Implements GLFbo |
|
||||||
* |
|
||||||
* @author Kirill Vainer |
|
||||||
*/ |
|
||||||
public class JoglGLFbo 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) { |
|
||||||
GLContext.getCurrentGL().getGL2ES3().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) { |
|
||||||
GLContext.getCurrentGL().glRenderbufferStorageMultisample(target, samples, internalformat, width, height); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindFramebufferEXT(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().glBindFramebuffer(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glBindRenderbufferEXT(int param1, int param2) { |
|
||||||
GLContext.getCurrentGL().glBindRenderbuffer(param1, param2); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int glCheckFramebufferStatusEXT(int param1) { |
|
||||||
return GLContext.getCurrentGL().glCheckFramebufferStatus(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteFramebuffersEXT(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glDeleteFramebuffers(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glDeleteRenderbuffersEXT(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glDeleteRenderbuffers(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) { |
|
||||||
GLContext.getCurrentGL().glFramebufferRenderbuffer(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) { |
|
||||||
GLContext.getCurrentGL().glFramebufferTexture2D(param1, param2, param3, param4, param5); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenFramebuffersEXT(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glGenFramebuffers(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenRenderbuffersEXT(IntBuffer param1) { |
|
||||||
checkLimit(param1); |
|
||||||
GLContext.getCurrentGL().glGenRenderbuffers(param1.limit(), param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glGenerateMipmapEXT(int param1) { |
|
||||||
GLContext.getCurrentGL().glGenerateMipmap(param1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) { |
|
||||||
GLContext.getCurrentGL().glRenderbufferStorage(param1, param2, param3, param4); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) { |
|
||||||
GLContext.getCurrentGL().getGL3().glFramebufferTextureLayer(param1, param2, param3, param4, param5); |
|
||||||
} |
|
||||||
} |
|
@ -1,529 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2018 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.jogl; |
|
||||||
|
|
||||||
import com.jme3.renderer.RendererException; |
|
||||||
import com.jme3.texture.Image; |
|
||||||
import com.jme3.texture.Image.Format; |
|
||||||
import com.jme3.texture.image.ColorSpace; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import com.jogamp.opengl.GL; |
|
||||||
import com.jogamp.opengl.GL2; |
|
||||||
import com.jogamp.opengl.GL2ES2; |
|
||||||
import com.jogamp.opengl.GL2ES3; |
|
||||||
import com.jogamp.opengl.GL2GL3; |
|
||||||
import com.jogamp.opengl.GLContext; |
|
||||||
|
|
||||||
public class TextureUtil { |
|
||||||
|
|
||||||
private static boolean abgrToRgbaConversionEnabled = false; |
|
||||||
|
|
||||||
public static int convertTextureFormat(Format fmt) { |
|
||||||
switch (fmt) { |
|
||||||
case Alpha8: |
|
||||||
return GL.GL_ALPHA; |
|
||||||
case Luminance8Alpha8: |
|
||||||
return GL.GL_LUMINANCE_ALPHA; |
|
||||||
case Luminance8: |
|
||||||
return GL.GL_LUMINANCE; |
|
||||||
case BGR8: |
|
||||||
case RGB8: |
|
||||||
case RGB565: |
|
||||||
return GL.GL_RGB; |
|
||||||
case RGB5A1: |
|
||||||
case RGBA8: |
|
||||||
return GL.GL_RGBA; |
|
||||||
case Depth: |
|
||||||
return GL2ES2.GL_DEPTH_COMPONENT; |
|
||||||
default: |
|
||||||
throw new UnsupportedOperationException("Unrecognized format: " + fmt); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static class GLImageFormat { |
|
||||||
|
|
||||||
int internalFormat; |
|
||||||
int format; |
|
||||||
int dataType; |
|
||||||
boolean compressed; |
|
||||||
|
|
||||||
public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed) { |
|
||||||
this.internalFormat = internalFormat; |
|
||||||
this.format = format; |
|
||||||
this.dataType = dataType; |
|
||||||
this.compressed = compressed; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static final GLImageFormat[] formatToGL = new GLImageFormat[Format.values().length]; |
|
||||||
|
|
||||||
private static void setFormat(Format format, int glInternalFormat, int glFormat, int glDataType, boolean glCompressed){ |
|
||||||
formatToGL[format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, glCompressed); |
|
||||||
} |
|
||||||
|
|
||||||
static { |
|
||||||
// Alpha formats
|
|
||||||
setFormat(Format.Alpha8, GL2.GL_ALPHA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
|
|
||||||
// Luminance formats
|
|
||||||
setFormat(Format.Luminance8, GL2.GL_LUMINANCE8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.Luminance16F, GL2.GL_LUMINANCE16F, GL.GL_LUMINANCE, GL.GL_HALF_FLOAT, false); |
|
||||||
setFormat(Format.Luminance32F, GL2.GL_LUMINANCE32F, GL.GL_LUMINANCE, GL.GL_FLOAT, false); |
|
||||||
|
|
||||||
// Luminance alpha formats
|
|
||||||
setFormat(Format.Luminance8Alpha8, GL2.GL_LUMINANCE8_ALPHA8, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.Luminance16FAlpha16F, GL2.GL_LUMINANCE_ALPHA16F, GL.GL_LUMINANCE_ALPHA, GL.GL_HALF_FLOAT, false); |
|
||||||
|
|
||||||
// Depth formats
|
|
||||||
setFormat(Format.Depth, GL2ES2.GL_DEPTH_COMPONENT, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.Depth16, GL.GL_DEPTH_COMPONENT16, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_SHORT, false); |
|
||||||
setFormat(Format.Depth24, GL.GL_DEPTH_COMPONENT24, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, false); |
|
||||||
setFormat(Format.Depth32, GL.GL_DEPTH_COMPONENT32, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, false); |
|
||||||
setFormat(Format.Depth32F, GL2GL3.GL_DEPTH_COMPONENT32F, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_FLOAT, false); |
|
||||||
|
|
||||||
// Depth stencil formats
|
|
||||||
setFormat(Format.Depth24Stencil8, GL.GL_DEPTH24_STENCIL8, GL.GL_DEPTH_STENCIL, GL.GL_UNSIGNED_INT_24_8, false); |
|
||||||
|
|
||||||
// RGB formats
|
|
||||||
setFormat(Format.BGR8, GL.GL_RGB8, GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.ARGB8, GL.GL_RGBA8, GL.GL_BGRA, GL2.GL_UNSIGNED_INT_8_8_8_8_REV, false); |
|
||||||
setFormat(Format.BGRA8, GL.GL_RGBA8, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.RGB8, GL.GL_RGB8, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.RGB16F, GL2ES2.GL_RGB16F, GL.GL_RGB, GL.GL_HALF_FLOAT, false); |
|
||||||
setFormat(Format.RGB32F, GL.GL_RGB32F, GL.GL_RGB, GL.GL_FLOAT, false); |
|
||||||
|
|
||||||
// Special RGB formats
|
|
||||||
setFormat(Format.RGB111110F, GL2ES3.GL_R11F_G11F_B10F, GL.GL_RGB, GL.GL_UNSIGNED_INT_10F_11F_11F_REV, false); |
|
||||||
setFormat(Format.RGB9E5, GL2GL3.GL_RGB9_E5, GL.GL_RGB, GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV, false); |
|
||||||
setFormat(Format.RGB16F_to_RGB111110F, GL2ES3.GL_R11F_G11F_B10F, GL.GL_RGB, GL.GL_HALF_FLOAT, false); |
|
||||||
setFormat(Format.RGB16F_to_RGB9E5, GL2.GL_RGB9_E5, GL.GL_RGB, GL.GL_HALF_FLOAT, false); |
|
||||||
|
|
||||||
// RGBA formats
|
|
||||||
setFormat(Format.ABGR8, GL.GL_RGBA8, GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.RGB5A1, GL.GL_RGB5_A1, GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1, false); |
|
||||||
setFormat(Format.RGBA8, GL.GL_RGBA8, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
setFormat(Format.RGBA16F, GL2ES2.GL_RGBA16F, GL.GL_RGBA, GL.GL_HALF_FLOAT, false); |
|
||||||
setFormat(Format.RGBA32F, GL.GL_RGBA32F, GL.GL_RGBA, GL.GL_FLOAT, false); |
|
||||||
|
|
||||||
// DXT formats
|
|
||||||
setFormat(Format.DXT1, GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
setFormat(Format.DXT1A, GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
setFormat(Format.DXT3, GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
setFormat(Format.DXT5, GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
} |
|
||||||
|
|
||||||
//sRGB formats
|
|
||||||
private static final GLImageFormat sRGB_RGB8 = new GLImageFormat(GL2.GL_SRGB8,GL.GL_RGB, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
private static final GLImageFormat sRGB_RGBA8 = new GLImageFormat(GL.GL_SRGB8_ALPHA8,GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
private static final GLImageFormat sRGB_Luminance8 = new GLImageFormat(GL2.GL_SLUMINANCE8,GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
private static final GLImageFormat sRGB_LuminanceAlpha8 = new GLImageFormat(GL2.GL_SLUMINANCE8_ALPHA8,GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
private static final GLImageFormat sRGB_BGR8 = new GLImageFormat(GL2.GL_SRGB8, GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
private static final GLImageFormat sRGB_ABGR8 = new GLImageFormat(GL2.GL_SRGB8_ALPHA8, GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
|
|
||||||
//FIXME cannot find GL_COMPRESSED_RGB_S3TC_DXT1,GL_COMPRESSED_RGBA_S3TC_DXT1,GL_COMPRESSED_RGB_S3TC_DXT3,GL_COMPRESSED_RGB_S3TC_DXT5 in JOGL used constants
|
|
||||||
//GL_COMPRESSED_RGB_S3TC_DXT1 = 33776;
|
|
||||||
//GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 33777;
|
|
||||||
//GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 33778;
|
|
||||||
//GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 33779;
|
|
||||||
private static final GLImageFormat sRGB_DXT1 = new GLImageFormat(33776, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
private static final GLImageFormat sRGB_DXT1A = new GLImageFormat( 33777, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(33778, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
private static final GLImageFormat sRGB_DXT5 = new GLImageFormat( 33779, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, true); |
|
||||||
|
|
||||||
|
|
||||||
public static GLImageFormat getImageFormat(Format fmt, boolean isSrgb){ |
|
||||||
GL gl = GLContext.getCurrentGL(); |
|
||||||
switch (fmt){ |
|
||||||
case ABGR8: |
|
||||||
if (!gl.isExtensionAvailable("GL_EXT_abgr") && !abgrToRgbaConversionEnabled) { |
|
||||||
setFormat(Format.ABGR8, GL.GL_RGBA, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, false); |
|
||||||
abgrToRgbaConversionEnabled = true; |
|
||||||
} |
|
||||||
break; |
|
||||||
case BGR8: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_1_2") && !gl.isExtensionAvailable("EXT_bgra")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case DXT1: |
|
||||||
case DXT1A: |
|
||||||
case DXT3: |
|
||||||
case DXT5: |
|
||||||
if (!gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc")) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Depth: |
|
||||||
case Depth16: |
|
||||||
case Depth24: |
|
||||||
case Depth32: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_1_4") && !gl.isExtensionAvailable("ARB_depth_texture")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Depth24Stencil8: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Luminance16F: |
|
||||||
case Luminance16FAlpha16F: |
|
||||||
case Luminance32F: |
|
||||||
if (!gl.isExtensionAvailable("GL_ARB_texture_float")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case RGB16F: |
|
||||||
case RGB32F: |
|
||||||
case RGBA16F: |
|
||||||
case RGBA32F: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_ARB_texture_float")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case Depth32F: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_NV_depth_buffer_float")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case RGB9E5: |
|
||||||
case RGB16F_to_RGB9E5: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_EXT_texture_shared_exponent")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
case RGB111110F: |
|
||||||
case RGB16F_to_RGB111110F: |
|
||||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_EXT_packed_float")){ |
|
||||||
return null; |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
if(isSrgb){ |
|
||||||
return getSrgbFormat(fmt); |
|
||||||
} |
|
||||||
return formatToGL[fmt.ordinal()]; |
|
||||||
} |
|
||||||
|
|
||||||
public static GLImageFormat getImageFormatWithError(Format fmt, boolean isSrgb) { |
|
||||||
GLImageFormat glFmt = getImageFormat(fmt, isSrgb); |
|
||||||
if (glFmt == null) { |
|
||||||
throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware."); |
|
||||||
} |
|
||||||
return glFmt; |
|
||||||
} |
|
||||||
|
|
||||||
private static GLImageFormat getSrgbFormat(Format fmt){ |
|
||||||
switch (fmt){ |
|
||||||
case RGB8 : return sRGB_RGB8; |
|
||||||
case RGBA8 : return sRGB_RGBA8; |
|
||||||
case BGR8 : return sRGB_BGR8; |
|
||||||
case ABGR8 : return sRGB_ABGR8; |
|
||||||
case Luminance8 : return sRGB_Luminance8; |
|
||||||
case Luminance8Alpha8 : return sRGB_LuminanceAlpha8; |
|
||||||
case DXT1 : return sRGB_DXT1; |
|
||||||
case DXT1A : return sRGB_DXT1A; |
|
||||||
case DXT3 : return sRGB_DXT3; |
|
||||||
case DXT5 : return sRGB_DXT5; |
|
||||||
default : Logger.getLogger(TextureUtil.class.getName()).log(Level.WARNING, "Format {0} has no sRGB equivalent, using linear format.", fmt.toString()); |
|
||||||
return formatToGL[fmt.ordinal()]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void uploadTexture(Image image, |
|
||||||
int target, |
|
||||||
int index, |
|
||||||
int border, |
|
||||||
boolean linearizeSrgb){ |
|
||||||
GL gl = GLContext.getCurrentGL(); |
|
||||||
Image.Format fmt = image.getFormat(); |
|
||||||
GLImageFormat glFmt = getImageFormatWithError(fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb); |
|
||||||
|
|
||||||
ByteBuffer data; |
|
||||||
if (index >= 0 && image.getData() != null && image.getData().size() > 0){ |
|
||||||
data = image.getData(index); |
|
||||||
}else{ |
|
||||||
data = null; |
|
||||||
} |
|
||||||
|
|
||||||
int width = image.getWidth(); |
|
||||||
int height = image.getHeight(); |
|
||||||
int depth = image.getDepth(); |
|
||||||
|
|
||||||
if (data != null) { |
|
||||||
if (abgrToRgbaConversionEnabled) { |
|
||||||
convertABGRtoRGBA(data); |
|
||||||
} |
|
||||||
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); |
|
||||||
} |
|
||||||
|
|
||||||
int[] mipSizes = image.getMipMapSizes(); |
|
||||||
int pos = 0; |
|
||||||
// TODO: Remove unnecessary allocation
|
|
||||||
if (mipSizes == null){ |
|
||||||
if (data != null) |
|
||||||
mipSizes = new int[]{ data.capacity() }; |
|
||||||
else |
|
||||||
mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 }; |
|
||||||
} |
|
||||||
|
|
||||||
boolean subtex = false; |
|
||||||
int samples = image.getMultiSamples(); |
|
||||||
|
|
||||||
for (int i = 0; i < mipSizes.length; i++){ |
|
||||||
int mipWidth = Math.max(1, width >> i); |
|
||||||
int mipHeight = Math.max(1, height >> i); |
|
||||||
int mipDepth = Math.max(1, depth >> i); |
|
||||||
|
|
||||||
if (data != null){ |
|
||||||
data.position(pos); |
|
||||||
data.limit(pos + mipSizes[i]); |
|
||||||
} |
|
||||||
|
|
||||||
if (glFmt.compressed && data != null){ |
|
||||||
if (target == GL2ES2.GL_TEXTURE_3D){ |
|
||||||
gl.getGL2ES2().glCompressedTexImage3D(target, |
|
||||||
i, |
|
||||||
glFmt.internalFormat, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
mipDepth, |
|
||||||
data.remaining(), |
|
||||||
border, |
|
||||||
data); |
|
||||||
}else{ |
|
||||||
//all other targets use 2D: array, cubemap, 2d
|
|
||||||
gl.glCompressedTexImage2D(target, |
|
||||||
i, |
|
||||||
glFmt.internalFormat, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
data.remaining(), |
|
||||||
border, |
|
||||||
data); |
|
||||||
} |
|
||||||
}else{ |
|
||||||
if (target == GL2ES2.GL_TEXTURE_3D){ |
|
||||||
gl.getGL2ES2().glTexImage3D(target, |
|
||||||
i, |
|
||||||
glFmt.internalFormat, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
mipDepth, |
|
||||||
border, |
|
||||||
glFmt.format, |
|
||||||
glFmt.dataType, |
|
||||||
data); |
|
||||||
}else if (target == GL2ES3.GL_TEXTURE_2D_ARRAY){ |
|
||||||
// prepare data for 2D array
|
|
||||||
// or upload slice
|
|
||||||
if (index == -1){ |
|
||||||
gl.getGL2ES2().glTexImage3D(target, |
|
||||||
0, |
|
||||||
glFmt.internalFormat, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
image.getData().size(), //# of slices
|
|
||||||
border, |
|
||||||
glFmt.format, |
|
||||||
glFmt.dataType, |
|
||||||
data); |
|
||||||
}else{ |
|
||||||
gl.getGL2ES2().glTexSubImage3D(target, |
|
||||||
i, // level
|
|
||||||
0, // xoffset
|
|
||||||
0, // yoffset
|
|
||||||
index, // zoffset
|
|
||||||
width, // width
|
|
||||||
height, // height
|
|
||||||
1, // depth
|
|
||||||
glFmt.format, |
|
||||||
glFmt.dataType, |
|
||||||
data); |
|
||||||
} |
|
||||||
}else{ |
|
||||||
if (subtex){ |
|
||||||
if (samples > 1){ |
|
||||||
throw new IllegalStateException("Cannot update multisample textures"); |
|
||||||
} |
|
||||||
|
|
||||||
gl.glTexSubImage2D(target, |
|
||||||
i, |
|
||||||
0, 0, |
|
||||||
mipWidth, mipHeight, |
|
||||||
glFmt.format, |
|
||||||
glFmt.dataType, |
|
||||||
data); |
|
||||||
}else{ |
|
||||||
if (samples > 1){ |
|
||||||
if (gl.isGL2GL3()) { |
|
||||||
gl.getGL3().glTexImage2DMultisample(target, |
|
||||||
samples, |
|
||||||
glFmt.internalFormat, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
true); |
|
||||||
} |
|
||||||
} else { |
|
||||||
gl.glTexImage2D(target, |
|
||||||
i, |
|
||||||
glFmt.internalFormat, |
|
||||||
mipWidth, |
|
||||||
mipHeight, |
|
||||||
border, |
|
||||||
glFmt.format, |
|
||||||
glFmt.dataType, |
|
||||||
data); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pos += mipSizes[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static void convertABGRtoRGBA(ByteBuffer buffer) { |
|
||||||
|
|
||||||
for (int i = 0; i < buffer.capacity(); i++) { |
|
||||||
|
|
||||||
int a = buffer.get(i++); |
|
||||||
int b = buffer.get(i++); |
|
||||||
int g = buffer.get(i++); |
|
||||||
int r = buffer.get(i); |
|
||||||
|
|
||||||
buffer.put(i - 3, (byte) r); |
|
||||||
buffer.put(i - 2, (byte) g); |
|
||||||
buffer.put(i - 1, (byte) b); |
|
||||||
buffer.put(i, (byte) a); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Update the texture currently bound to target at with data from the given Image at position x and y. The parameter |
|
||||||
* index is used as the zoffset in case a 3d texture or texture 2d array is being updated. |
|
||||||
* |
|
||||||
* @param image Image with the source data (this data will be put into the texture) |
|
||||||
* @param target the target texture |
|
||||||
* @param index the mipmap level to update |
|
||||||
* @param x the x position where to put the image in the texture |
|
||||||
* @param y the y position where to put the image in the texture |
|
||||||
*/ |
|
||||||
public static void uploadSubTexture( |
|
||||||
Image image, |
|
||||||
int target, |
|
||||||
int index, |
|
||||||
int x, |
|
||||||
int y, |
|
||||||
boolean linearizeSrgb) { |
|
||||||
GL gl = GLContext.getCurrentGL(); |
|
||||||
Image.Format fmt = image.getFormat(); |
|
||||||
GLImageFormat glFmt = getImageFormatWithError(fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb); |
|
||||||
|
|
||||||
ByteBuffer data = null; |
|
||||||
if (index >= 0 && image.getData() != null && image.getData().size() > 0) { |
|
||||||
data = image.getData(index); |
|
||||||
} |
|
||||||
|
|
||||||
int width = image.getWidth(); |
|
||||||
int height = image.getHeight(); |
|
||||||
int depth = image.getDepth(); |
|
||||||
|
|
||||||
if (data != null) { |
|
||||||
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); |
|
||||||
} |
|
||||||
|
|
||||||
int[] mipSizes = image.getMipMapSizes(); |
|
||||||
int pos = 0; |
|
||||||
|
|
||||||
// TODO: Remove unnecessary allocation
|
|
||||||
if (mipSizes == null){ |
|
||||||
if (data != null) { |
|
||||||
mipSizes = new int[]{ data.capacity() }; |
|
||||||
} else { |
|
||||||
mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 }; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int samples = image.getMultiSamples(); |
|
||||||
|
|
||||||
for (int i = 0; i < mipSizes.length; i++){ |
|
||||||
int mipWidth = Math.max(1, width >> i); |
|
||||||
int mipHeight = Math.max(1, height >> i); |
|
||||||
int mipDepth = Math.max(1, depth >> i); |
|
||||||
|
|
||||||
if (data != null){ |
|
||||||
data.position(pos); |
|
||||||
data.limit(pos + mipSizes[i]); |
|
||||||
} |
|
||||||
|
|
||||||
// to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each
|
|
||||||
// gl*Image call in an attempt to unclutter things a bit
|
|
||||||
pos += mipSizes[i]; |
|
||||||
|
|
||||||
int glFmtInternal = glFmt.internalFormat; |
|
||||||
int glFmtFormat = glFmt.format; |
|
||||||
int glFmtDataType = glFmt.dataType; |
|
||||||
|
|
||||||
if (glFmt.compressed && data != null){ |
|
||||||
if (target == GL2ES2.GL_TEXTURE_3D){ |
|
||||||
gl.getGL2ES2().glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data.limit(), data); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
// all other targets use 2D: array, cubemap, 2d
|
|
||||||
gl.getGL2ES2().glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data.limit(), data); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (target == GL2ES2.GL_TEXTURE_3D){ |
|
||||||
gl.getGL2ES2().glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (samples > 1){ |
|
||||||
throw new IllegalStateException("Cannot update multisample textures"); |
|
||||||
} |
|
||||||
|
|
||||||
gl.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data); |
|
||||||
continue; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,198 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.system.jogl; |
|
||||||
|
|
||||||
import com.jme3.input.KeyInput; |
|
||||||
import com.jme3.input.MouseInput; |
|
||||||
import com.jme3.input.TouchInput; |
|
||||||
import com.jme3.input.awt.AwtKeyInput; |
|
||||||
import com.jme3.input.awt.AwtMouseInput; |
|
||||||
import com.jme3.system.AppSettings; |
|
||||||
import com.jogamp.opengl.util.Animator; |
|
||||||
import com.jogamp.opengl.util.AnimatorBase; |
|
||||||
import com.jogamp.opengl.util.FPSAnimator; |
|
||||||
|
|
||||||
import java.awt.GraphicsDevice; |
|
||||||
import java.awt.GraphicsEnvironment; |
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import com.jogamp.opengl.GLAutoDrawable; |
|
||||||
import com.jogamp.opengl.GLCapabilities; |
|
||||||
import com.jogamp.opengl.GLEventListener; |
|
||||||
import com.jogamp.opengl.GLProfile; |
|
||||||
import com.jogamp.opengl.GLRunnable; |
|
||||||
import com.jogamp.opengl.awt.GLCanvas; |
|
||||||
|
|
||||||
public abstract class JoglAbstractDisplay extends JoglContext implements GLEventListener { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglAbstractDisplay.class.getName()); |
|
||||||
|
|
||||||
protected GraphicsDevice device; |
|
||||||
|
|
||||||
protected GLCanvas canvas; |
|
||||||
|
|
||||||
protected AnimatorBase animator; |
|
||||||
|
|
||||||
protected AtomicBoolean active = new AtomicBoolean(false); |
|
||||||
|
|
||||||
protected boolean wasActive = false; |
|
||||||
|
|
||||||
protected int frameRate; |
|
||||||
|
|
||||||
protected boolean useAwt = true; |
|
||||||
|
|
||||||
protected AtomicBoolean autoFlush = new AtomicBoolean(true); |
|
||||||
|
|
||||||
protected boolean wasAnimating = false; |
|
||||||
|
|
||||||
protected void initGLCanvas() { |
|
||||||
device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); |
|
||||||
|
|
||||||
GLCapabilities caps; |
|
||||||
if (settings.getRenderer().equals(AppSettings.JOGL_OPENGL_FORWARD_COMPATIBLE)) { |
|
||||||
caps = new GLCapabilities(GLProfile.getMaxProgrammable(true)); |
|
||||||
} else { |
|
||||||
caps = new GLCapabilities(GLProfile.getMaxFixedFunc(true)); |
|
||||||
} |
|
||||||
|
|
||||||
caps.setHardwareAccelerated(true); |
|
||||||
caps.setDoubleBuffered(true); |
|
||||||
caps.setStencilBits(settings.getStencilBits()); |
|
||||||
caps.setDepthBits(settings.getDepthBits()); |
|
||||||
|
|
||||||
if (settings.getSamples() > 1) { |
|
||||||
caps.setSampleBuffers(true); |
|
||||||
caps.setNumSamples(settings.getSamples()); |
|
||||||
} |
|
||||||
|
|
||||||
canvas = new GLCanvas(caps) { |
|
||||||
@Override |
|
||||||
public void addNotify() { |
|
||||||
super.addNotify(); |
|
||||||
onCanvasAdded(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void removeNotify() { |
|
||||||
onCanvasRemoved(); |
|
||||||
super.removeNotify(); |
|
||||||
} |
|
||||||
}; |
|
||||||
canvas.invoke(false, new GLRunnable() { |
|
||||||
@Override |
|
||||||
public boolean run(GLAutoDrawable glad) { |
|
||||||
canvas.getGL().setSwapInterval(settings.isVSync() ? 1 : 0); |
|
||||||
return true; |
|
||||||
} |
|
||||||
}); |
|
||||||
canvas.setFocusable(true); |
|
||||||
canvas.requestFocus(); |
|
||||||
canvas.setSize(settings.getWidth(), settings.getHeight()); |
|
||||||
canvas.setIgnoreRepaint(true); |
|
||||||
canvas.addGLEventListener(this); |
|
||||||
|
|
||||||
//FIXME not sure it is the best place to do that
|
|
||||||
renderable.set(true); |
|
||||||
} |
|
||||||
|
|
||||||
protected void startGLCanvas() { |
|
||||||
if (frameRate > 0) { |
|
||||||
animator = new FPSAnimator(canvas, frameRate); |
|
||||||
} |
|
||||||
else { |
|
||||||
animator = new Animator(); |
|
||||||
animator.add(canvas); |
|
||||||
((Animator) animator).setRunAsFastAsPossible(true); |
|
||||||
} |
|
||||||
|
|
||||||
animator.start(); |
|
||||||
wasAnimating = true; |
|
||||||
} |
|
||||||
|
|
||||||
protected void onCanvasAdded() { |
|
||||||
} |
|
||||||
|
|
||||||
protected void onCanvasRemoved() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public KeyInput getKeyInput() { |
|
||||||
if (keyInput == null) { |
|
||||||
keyInput = new AwtKeyInput(); |
|
||||||
((AwtKeyInput)keyInput).setInputSource(canvas); |
|
||||||
} |
|
||||||
return keyInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public MouseInput getMouseInput() { |
|
||||||
if (mouseInput == null) { |
|
||||||
mouseInput = new AwtMouseInput(); |
|
||||||
((AwtMouseInput)mouseInput).setInputSource(canvas); |
|
||||||
} |
|
||||||
return mouseInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public TouchInput getTouchInput() { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setAutoFlushFrames(boolean enabled) { |
|
||||||
autoFlush.set(enabled); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { |
|
||||||
listener.reshape(width, height); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback. |
|
||||||
*/ |
|
||||||
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void dispose(GLAutoDrawable drawable) { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,155 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.jogl; |
|
||||||
|
|
||||||
import com.jme3.system.JmeCanvasContext; |
|
||||||
import java.awt.Canvas; |
|
||||||
import java.util.logging.Logger; |
|
||||||
import com.jogamp.opengl.GLAutoDrawable; |
|
||||||
|
|
||||||
public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglCanvas.class.getName()); |
|
||||||
private int width, height; |
|
||||||
private boolean runningFirstTime = true; |
|
||||||
|
|
||||||
public JoglCanvas(){ |
|
||||||
super(); |
|
||||||
initGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Type getType() { |
|
||||||
return Type.Canvas; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setTitle(String title) { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void restart() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void create(boolean waitFor){ |
|
||||||
if (waitFor) |
|
||||||
waitFor(true); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy(boolean waitFor){ |
|
||||||
if (waitFor) |
|
||||||
waitFor(false); |
|
||||||
if (animator.isAnimating()) |
|
||||||
animator.stop(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void onCanvasRemoved(){ |
|
||||||
super.onCanvasRemoved(); |
|
||||||
created.set(false); |
|
||||||
waitFor(false); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void onCanvasAdded(){ |
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void init(GLAutoDrawable drawable) { |
|
||||||
canvas.requestFocus(); |
|
||||||
|
|
||||||
super.internalCreate(); |
|
||||||
logger.fine("Display created."); |
|
||||||
|
|
||||||
// At this point, the OpenGL context is active.
|
|
||||||
if (runningFirstTime){ |
|
||||||
// THIS is the part that creates the renderer.
|
|
||||||
// It must always be called, now that we have the pbuffer workaround.
|
|
||||||
initContextFirstTime(); |
|
||||||
runningFirstTime = false; |
|
||||||
} |
|
||||||
listener.initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void startGLCanvas() { |
|
||||||
frameRate = settings.getFrameRate(); |
|
||||||
super.startGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void display(GLAutoDrawable glad) { |
|
||||||
if (!created.get() && renderer != null){ |
|
||||||
listener.destroy(); |
|
||||||
logger.fine("Canvas destroyed."); |
|
||||||
super.internalDestroy(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
int newWidth = Math.max(canvas.getWidth(), 1); |
|
||||||
int newHeight = Math.max(canvas.getHeight(), 1); |
|
||||||
if (width != newWidth || height != newHeight) { |
|
||||||
width = newWidth; |
|
||||||
height = newHeight; |
|
||||||
if (listener != null) { |
|
||||||
listener.reshape(width, height); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
boolean flush = autoFlush.get(); |
|
||||||
if (flush && !wasAnimating){ |
|
||||||
animator.start(); |
|
||||||
wasAnimating = true; |
|
||||||
}else if (!flush && wasAnimating){ |
|
||||||
animator.stop(); |
|
||||||
wasAnimating = false; |
|
||||||
} |
|
||||||
|
|
||||||
listener.update(); |
|
||||||
renderer.postFrame(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Canvas getCanvas() { |
|
||||||
return canvas; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void dispose(GLAutoDrawable arg0) { |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,383 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.jogl; |
|
||||||
|
|
||||||
import com.jme3.input.JoyInput; |
|
||||||
import com.jme3.input.KeyInput; |
|
||||||
import com.jme3.input.MouseInput; |
|
||||||
import com.jme3.opencl.Context; |
|
||||||
import com.jme3.opencl.DefaultPlatformChooser; |
|
||||||
import com.jme3.opencl.Device; |
|
||||||
import com.jme3.opencl.PlatformChooser; |
|
||||||
import com.jme3.opencl.jocl.JoclDevice; |
|
||||||
import com.jme3.opencl.jocl.JoclPlatform; |
|
||||||
import com.jme3.renderer.Renderer; |
|
||||||
import com.jme3.renderer.RendererException; |
|
||||||
import com.jme3.renderer.jogl.JoglGL; |
|
||||||
import com.jme3.renderer.jogl.JoglGLExt; |
|
||||||
import com.jme3.renderer.jogl.JoglGLFbo; |
|
||||||
import com.jme3.renderer.opengl.GL2; |
|
||||||
import com.jme3.renderer.opengl.GL3; |
|
||||||
import com.jme3.renderer.opengl.GL4; |
|
||||||
import com.jme3.renderer.opengl.GLDebug; |
|
||||||
import com.jme3.renderer.opengl.GLExt; |
|
||||||
import com.jme3.renderer.opengl.GLFbo; |
|
||||||
import com.jme3.renderer.opengl.GLRenderer; |
|
||||||
import com.jme3.renderer.opengl.GLTiming; |
|
||||||
import com.jme3.renderer.opengl.GLTimingState; |
|
||||||
import com.jme3.renderer.opengl.GLTracer; |
|
||||||
import com.jme3.system.AppSettings; |
|
||||||
import com.jme3.system.JmeContext; |
|
||||||
import com.jme3.system.NanoTimer; |
|
||||||
import com.jme3.system.SystemListener; |
|
||||||
import com.jme3.system.Timer; |
|
||||||
import com.jogamp.opencl.CLDevice; |
|
||||||
import com.jogamp.opencl.CLPlatform; |
|
||||||
import com.jogamp.opencl.gl.CLGLContext; |
|
||||||
|
|
||||||
import java.nio.IntBuffer; |
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import com.jogamp.opengl.GL; |
|
||||||
import com.jogamp.opengl.GL2GL3; |
|
||||||
import com.jogamp.opengl.GLContext; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
public abstract class JoglContext implements JmeContext { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglContext.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 Timer timer; |
|
||||||
protected SystemListener listener; |
|
||||||
|
|
||||||
protected KeyInput keyInput; |
|
||||||
protected MouseInput mouseInput; |
|
||||||
protected JoyInput joyInput; |
|
||||||
|
|
||||||
protected com.jme3.opencl.Context clContext; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setSystemListener(SystemListener listener){ |
|
||||||
this.listener = listener; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setSettings(AppSettings settings) { |
|
||||||
this.settings.copyFrom(settings); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isRenderable(){ |
|
||||||
return renderable.get(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public AppSettings getSettings() { |
|
||||||
return settings; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Renderer getRenderer() { |
|
||||||
return renderer; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public MouseInput getMouseInput() { |
|
||||||
return mouseInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public KeyInput getKeyInput() { |
|
||||||
return keyInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public JoyInput getJoyInput() { |
|
||||||
return joyInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Timer getTimer() { |
|
||||||
return timer; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isCreated() { |
|
||||||
return created.get(); |
|
||||||
} |
|
||||||
|
|
||||||
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) { |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected void initContextFirstTime(){ |
|
||||||
if (GLContext.getCurrent().getGLVersionNumber().getMajor() < 2) { |
|
||||||
throw new RendererException("OpenGL 2.0 or higher is " + |
|
||||||
"required for jMonkeyEngine"); |
|
||||||
} |
|
||||||
|
|
||||||
if (settings.getRenderer().startsWith("JOGL")) { |
|
||||||
com.jme3.renderer.opengl.GL gl = new JoglGL(); |
|
||||||
GLExt glext = new JoglGLExt(); |
|
||||||
GLFbo glfbo = new JoglGLFbo(); |
|
||||||
|
|
||||||
if (settings.getBoolean("GraphicsDebug")) { |
|
||||||
gl = (com.jme3.renderer.opengl.GL) GLDebug.createProxy(gl, gl, com.jme3.renderer.opengl.GL.class, GL2.class, GL3.class, GL4.class); |
|
||||||
glext = (GLExt) GLDebug.createProxy(gl, glext, GLExt.class); |
|
||||||
glfbo = (GLFbo) GLDebug.createProxy(gl, glfbo, GLFbo.class); |
|
||||||
} |
|
||||||
|
|
||||||
if (settings.getBoolean("GraphicsTiming")) { |
|
||||||
GLTimingState timingState = new GLTimingState(); |
|
||||||
gl = (com.jme3.renderer.opengl.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 = (com.jme3.renderer.opengl.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 (GLContext.getCurrentGL().isExtensionAvailable("GL_ARB_debug_output") && settings.getBoolean("GraphicsDebug")) { |
|
||||||
GLContext.getCurrent().enableGLDebugMessage(true); |
|
||||||
GLContext.getCurrent().addGLDebugListener(new JoglGLDebugOutputHandler()); |
|
||||||
} |
|
||||||
|
|
||||||
renderer.setMainFrameBufferSrgb(settings.isGammaCorrection()); |
|
||||||
renderer.setLinearizeSrgbImages(settings.isGammaCorrection()); |
|
||||||
|
|
||||||
// Init input
|
|
||||||
if (keyInput != null) { |
|
||||||
keyInput.initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
if (mouseInput != null) { |
|
||||||
mouseInput.initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
if (joyInput != null) { |
|
||||||
joyInput.initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
if (settings.isOpenCLSupport()) { |
|
||||||
initOpenCL(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
protected void initOpenCL() { |
|
||||||
logger.info("Initialize OpenCL with JOGL"); |
|
||||||
|
|
||||||
//load platforms and devices
|
|
||||||
StringBuilder platformInfos = new StringBuilder(); |
|
||||||
ArrayList<JoclPlatform> platforms = new ArrayList<JoclPlatform>(); |
|
||||||
for (CLPlatform p : CLPlatform.listCLPlatforms()) { |
|
||||||
platforms.add(new JoclPlatform(p)); |
|
||||||
} |
|
||||||
platformInfos.append("Available OpenCL platforms:"); |
|
||||||
for (int i=0; i<platforms.size(); ++i) { |
|
||||||
JoclPlatform platform = platforms.get(i); |
|
||||||
platformInfos.append("\n * Platform ").append(i+1); |
|
||||||
platformInfos.append("\n * Name: ").append(platform.getName()); |
|
||||||
platformInfos.append("\n * Vendor: ").append(platform.getVendor()); |
|
||||||
platformInfos.append("\n * Version: ").append(platform.getVersion()); |
|
||||||
platformInfos.append("\n * Profile: ").append(platform.getProfile()); |
|
||||||
platformInfos.append("\n * Supports interop: ").append(platform.hasOpenGLInterop()); |
|
||||||
List<JoclDevice> devices = platform.getDevices(); |
|
||||||
platformInfos.append("\n * Available devices:"); |
|
||||||
for (int j=0; j<devices.size(); ++j) { |
|
||||||
JoclDevice device = devices.get(j); |
|
||||||
platformInfos.append("\n * * Device ").append(j+1); |
|
||||||
platformInfos.append("\n * * Name: ").append(device.getName()); |
|
||||||
platformInfos.append("\n * * Vendor: ").append(device.getVendor()); |
|
||||||
platformInfos.append("\n * * Version: ").append(device.getVersion()); |
|
||||||
platformInfos.append("\n * * Profile: ").append(device.getProfile()); |
|
||||||
platformInfos.append("\n * * Compiler version: ").append(device.getCompilerVersion()); |
|
||||||
platformInfos.append("\n * * Device type: ").append(device.getDeviceType()); |
|
||||||
platformInfos.append("\n * * Compute units: ").append(device.getComputeUnits()); |
|
||||||
platformInfos.append("\n * * Work group size: ").append(device.getMaxiumWorkItemsPerGroup()); |
|
||||||
platformInfos.append("\n * * Global memory: ").append(device.getGlobalMemorySize()).append("B"); |
|
||||||
platformInfos.append("\n * * Local memory: ").append(device.getLocalMemorySize()).append("B"); |
|
||||||
platformInfos.append("\n * * Constant memory: ").append(device.getMaximumConstantBufferSize()).append("B"); |
|
||||||
platformInfos.append("\n * * Supports double: ").append(device.hasDouble()); |
|
||||||
platformInfos.append("\n * * Supports half floats: ").append(device.hasHalfFloat()); |
|
||||||
platformInfos.append("\n * * Supports writable 3d images: ").append(device.hasWritableImage3D()); |
|
||||||
platformInfos.append("\n * * Supports interop: ").append(device.hasOpenGLInterop()); |
|
||||||
} |
|
||||||
} |
|
||||||
logger.info(platformInfos.toString()); |
|
||||||
|
|
||||||
//choose devices
|
|
||||||
PlatformChooser chooser = null; |
|
||||||
if (settings.getOpenCLPlatformChooser() != null) { |
|
||||||
try { |
|
||||||
chooser = (PlatformChooser) Class.forName(settings.getOpenCLPlatformChooser()).newInstance(); |
|
||||||
} catch (Exception ex) { |
|
||||||
logger.log(Level.WARNING, "unable to instantiate custom PlatformChooser", ex); |
|
||||||
} |
|
||||||
} |
|
||||||
if (chooser == null) { |
|
||||||
chooser = new DefaultPlatformChooser(); |
|
||||||
} |
|
||||||
List<? extends Device> choosenDevices = chooser.chooseDevices(platforms); |
|
||||||
List<CLDevice> devices = new ArrayList<>(choosenDevices.size()); |
|
||||||
JoclPlatform platform = null; |
|
||||||
for (Device d : choosenDevices) { |
|
||||||
if (!(d instanceof JoclDevice)) { |
|
||||||
logger.log(Level.SEVERE, "attempt to return a custom Device implementation from PlatformChooser: {0}", d); |
|
||||||
return; |
|
||||||
} |
|
||||||
JoclDevice ld = (JoclDevice) d; |
|
||||||
if (platform == null) { |
|
||||||
platform = ld.getPlatform(); |
|
||||||
} else if (platform != ld.getPlatform()) { |
|
||||||
logger.severe("attempt to use devices from different platforms"); |
|
||||||
return; |
|
||||||
} |
|
||||||
devices.add(ld.getDevice()); |
|
||||||
} |
|
||||||
if (devices.isEmpty()) { |
|
||||||
logger.warning("no devices specified, no OpenCL context created"); |
|
||||||
return; |
|
||||||
} |
|
||||||
logger.log(Level.INFO, "chosen platform: {0}", platform.getName()); |
|
||||||
logger.log(Level.INFO, "chosen devices: {0}", choosenDevices); |
|
||||||
|
|
||||||
//create context
|
|
||||||
try { |
|
||||||
CLGLContext c = CLGLContext.create(GLContext.getCurrent(), devices.toArray(new CLDevice[devices.size()])); |
|
||||||
clContext = new com.jme3.opencl.jocl.JoclContext(c, (List<JoclDevice>) choosenDevices); |
|
||||||
} catch (Exception ex) { |
|
||||||
logger.log(Level.SEVERE, "Unable to create OpenCL context", ex); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
logger.info("OpenCL context created"); |
|
||||||
} |
|
||||||
|
|
||||||
public void internalCreate() { |
|
||||||
timer = new NanoTimer(); |
|
||||||
synchronized (createdLock){ |
|
||||||
created.set(true); |
|
||||||
createdLock.notifyAll(); |
|
||||||
} |
|
||||||
if (renderable.get()){ |
|
||||||
initContextFirstTime(); |
|
||||||
} else { |
|
||||||
assert getType() == Type.Canvas; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected void internalDestroy() { |
|
||||||
renderer = null; |
|
||||||
timer = null; |
|
||||||
renderable.set(false); |
|
||||||
synchronized (createdLock){ |
|
||||||
created.set(false); |
|
||||||
createdLock.notifyAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected int determineMaxSamples(int requestedSamples) { |
|
||||||
GL gl = GLContext.getCurrentGL(); |
|
||||||
if (gl.hasFullFBOSupport()) { |
|
||||||
return gl.getMaxRenderbufferSamples(); |
|
||||||
} else { |
|
||||||
if (gl.isExtensionAvailable("GL_ARB_framebuffer_object") |
|
||||||
|| gl.isExtensionAvailable("GL_EXT_framebuffer_multisample")) { |
|
||||||
IntBuffer intBuf1 = IntBuffer.allocate(1); |
|
||||||
gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, intBuf1); |
|
||||||
return intBuf1.get(0); |
|
||||||
} else { |
|
||||||
return Integer.MAX_VALUE; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected int getNumSamplesToUse() { |
|
||||||
int samples = 0; |
|
||||||
if (settings.getSamples() > 1){ |
|
||||||
samples = settings.getSamples(); |
|
||||||
int supportedSamples = determineMaxSamples(samples); |
|
||||||
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; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Context getOpenCLContext() { |
|
||||||
return clContext; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,365 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.system.jogl; |
|
||||||
|
|
||||||
import com.jme3.system.AppSettings; |
|
||||||
import java.awt.Dimension; |
|
||||||
import java.awt.DisplayMode; |
|
||||||
import java.awt.Frame; |
|
||||||
import java.awt.GraphicsDevice; |
|
||||||
import java.awt.GraphicsEnvironment; |
|
||||||
import java.awt.Toolkit; |
|
||||||
import java.awt.event.WindowAdapter; |
|
||||||
import java.awt.event.WindowEvent; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
import com.jogamp.opengl.GLAutoDrawable; |
|
||||||
import javax.swing.JFrame; |
|
||||||
import javax.swing.SwingUtilities; |
|
||||||
|
|
||||||
public class JoglDisplay extends JoglAbstractDisplay { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglDisplay.class.getName()); |
|
||||||
|
|
||||||
protected AtomicBoolean windowCloseRequest = new AtomicBoolean(false); |
|
||||||
protected AtomicBoolean needClose = new AtomicBoolean(false); |
|
||||||
protected AtomicBoolean needRestart = new AtomicBoolean(false); |
|
||||||
protected volatile boolean wasInited = false; |
|
||||||
protected Frame frame; |
|
||||||
|
|
||||||
@Override |
|
||||||
public Type getType() { |
|
||||||
return Type.Display; |
|
||||||
} |
|
||||||
|
|
||||||
protected void createGLFrame(){ |
|
||||||
if (useAwt){ |
|
||||||
frame = new Frame(settings.getTitle()); |
|
||||||
}else{ |
|
||||||
frame = new JFrame(settings.getTitle()); |
|
||||||
} |
|
||||||
frame.setResizable(false); |
|
||||||
frame.add(canvas); |
|
||||||
|
|
||||||
applySettings(settings); |
|
||||||
|
|
||||||
// Make the window visible to realize the OpenGL surface.
|
|
||||||
frame.setVisible(true); |
|
||||||
|
|
||||||
canvas.setVisible(true); |
|
||||||
|
|
||||||
//this is the earliest safe opportunity to get the context
|
|
||||||
//final GLContext context = canvas.getContext();
|
|
||||||
|
|
||||||
/*canvas.invoke(true, new GLRunnable() { |
|
||||||
@Override |
|
||||||
public boolean run(GLAutoDrawable glAutoDrawable) { |
|
||||||
context.makeCurrent(); |
|
||||||
try { |
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
finally { |
|
||||||
context.release(); |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
});*/ |
|
||||||
} |
|
||||||
|
|
||||||
protected void applySettings(AppSettings settings){ |
|
||||||
final boolean isDisplayModeModified; |
|
||||||
final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); |
|
||||||
// Get the current display mode
|
|
||||||
final DisplayMode previousDisplayMode = gd.getDisplayMode(); |
|
||||||
// Handle full screen mode if requested.
|
|
||||||
if (settings.isFullscreen()) { |
|
||||||
frame.setUndecorated(true); |
|
||||||
// Check if the full-screen mode is supported by the OS
|
|
||||||
boolean isFullScreenSupported = gd.isFullScreenSupported(); |
|
||||||
if (isFullScreenSupported) { |
|
||||||
gd.setFullScreenWindow(frame); |
|
||||||
// Check if display mode changes are supported by the OS
|
|
||||||
if (gd.isDisplayChangeSupported()) { |
|
||||||
// Get all available display modes
|
|
||||||
final DisplayMode[] displayModes = gd.getDisplayModes(); |
|
||||||
DisplayMode multiBitsDepthSupportedDisplayMode = null; |
|
||||||
DisplayMode refreshRateUnknownDisplayMode = null; |
|
||||||
DisplayMode multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = null; |
|
||||||
DisplayMode matchingDisplayMode = null; |
|
||||||
DisplayMode currentDisplayMode; |
|
||||||
// Look for the display mode that matches with our parameters
|
|
||||||
// Look for some display modes that are close to these parameters
|
|
||||||
// and that could be used as substitutes
|
|
||||||
// On some machines, the refresh rate is unknown and/or multi bit
|
|
||||||
// depths are supported. If you try to force a particular refresh
|
|
||||||
// rate or a bit depth, you might find no available display mode
|
|
||||||
// that matches exactly with your parameters
|
|
||||||
for (int i = 0; i < displayModes.length && matchingDisplayMode == null; i++) { |
|
||||||
currentDisplayMode = displayModes[i]; |
|
||||||
if (currentDisplayMode.getWidth() == settings.getWidth() |
|
||||||
&& currentDisplayMode.getHeight() == settings.getHeight()) { |
|
||||||
if (currentDisplayMode.getBitDepth() == settings.getBitsPerPixel()) { |
|
||||||
if (currentDisplayMode.getRefreshRate() == settings.getFrequency()) { |
|
||||||
matchingDisplayMode = currentDisplayMode; |
|
||||||
} else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) { |
|
||||||
refreshRateUnknownDisplayMode = currentDisplayMode; |
|
||||||
} |
|
||||||
} else if (currentDisplayMode.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) { |
|
||||||
if (currentDisplayMode.getRefreshRate() == settings.getFrequency()) { |
|
||||||
multiBitsDepthSupportedDisplayMode = currentDisplayMode; |
|
||||||
} else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) { |
|
||||||
multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = currentDisplayMode; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
DisplayMode nextDisplayMode = null; |
|
||||||
if (matchingDisplayMode != null) { |
|
||||||
nextDisplayMode = matchingDisplayMode; |
|
||||||
} else if (multiBitsDepthSupportedDisplayMode != null) { |
|
||||||
nextDisplayMode = multiBitsDepthSupportedDisplayMode; |
|
||||||
} else if (refreshRateUnknownDisplayMode != null) { |
|
||||||
nextDisplayMode = refreshRateUnknownDisplayMode; |
|
||||||
} else if (multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode != null) { |
|
||||||
nextDisplayMode = multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode; |
|
||||||
} else { |
|
||||||
isFullScreenSupported = false; |
|
||||||
} |
|
||||||
// If we have found a display mode that approximatively matches
|
|
||||||
// with the input parameters, use it
|
|
||||||
if (nextDisplayMode != null) { |
|
||||||
gd.setDisplayMode(nextDisplayMode); |
|
||||||
isDisplayModeModified = true; |
|
||||||
} else { |
|
||||||
isDisplayModeModified = false; |
|
||||||
} |
|
||||||
} else { |
|
||||||
isDisplayModeModified = false; |
|
||||||
// Resize the canvas if the display mode cannot be changed
|
|
||||||
// and the screen size is not equal to the canvas size
|
|
||||||
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
|
||||||
if (screenSize.width != settings.getWidth() || screenSize.height != settings.getHeight()) { |
|
||||||
canvas.setSize(screenSize); |
|
||||||
} |
|
||||||
} |
|
||||||
} else { |
|
||||||
isDisplayModeModified = false; |
|
||||||
} |
|
||||||
|
|
||||||
// Software windowed full-screen mode
|
|
||||||
if (!isFullScreenSupported) { |
|
||||||
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
|
||||||
// Resize the canvas
|
|
||||||
canvas.setSize(screenSize); |
|
||||||
// Resize the frame so that it occupies the whole screen
|
|
||||||
frame.setSize(screenSize); |
|
||||||
// Set its location at the top left corner
|
|
||||||
frame.setLocation(0, 0); |
|
||||||
} |
|
||||||
} |
|
||||||
// Otherwise, center the window on the screen.
|
|
||||||
else { |
|
||||||
isDisplayModeModified = false; |
|
||||||
frame.pack(); |
|
||||||
|
|
||||||
int x, y; |
|
||||||
x = (Toolkit.getDefaultToolkit().getScreenSize().width - settings.getWidth()) / 2; |
|
||||||
y = (Toolkit.getDefaultToolkit().getScreenSize().height - settings.getHeight()) / 2; |
|
||||||
frame.setLocation(x, y); |
|
||||||
} |
|
||||||
|
|
||||||
frame.addWindowListener(new WindowAdapter() { |
|
||||||
@Override |
|
||||||
public void windowClosing(WindowEvent evt) { |
|
||||||
// If required, restore the previous display mode
|
|
||||||
if (isDisplayModeModified) { |
|
||||||
gd.setDisplayMode(previousDisplayMode); |
|
||||||
} |
|
||||||
// If required, get back to the windowed mode
|
|
||||||
if (gd.getFullScreenWindow() == frame) { |
|
||||||
gd.setFullScreenWindow(null); |
|
||||||
} |
|
||||||
windowCloseRequest.set(true); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void windowActivated(WindowEvent evt) { |
|
||||||
active.set(true); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void windowDeactivated(WindowEvent evt) { |
|
||||||
active.set(false); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
logger.log(Level.FINE, "Selected display mode: {0}x{1}x{2} @{3}", |
|
||||||
new Object[]{gd.getDisplayMode().getWidth(), |
|
||||||
gd.getDisplayMode().getHeight(), |
|
||||||
gd.getDisplayMode().getBitDepth(), |
|
||||||
gd.getDisplayMode().getRefreshRate()}); |
|
||||||
} |
|
||||||
|
|
||||||
private void initInEDT(){ |
|
||||||
initGLCanvas(); |
|
||||||
|
|
||||||
createGLFrame(); |
|
||||||
|
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void init(GLAutoDrawable drawable){ |
|
||||||
// prevent initializing twice on restart
|
|
||||||
if (!wasInited){ |
|
||||||
wasInited = true; |
|
||||||
|
|
||||||
canvas.requestFocus(); |
|
||||||
|
|
||||||
super.internalCreate(); |
|
||||||
logger.fine("Display created."); |
|
||||||
|
|
||||||
renderer.initialize(); |
|
||||||
listener.initialize(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void create(boolean waitFor){ |
|
||||||
if (SwingUtilities.isEventDispatchThread()) { |
|
||||||
initInEDT(); |
|
||||||
} else { |
|
||||||
try { |
|
||||||
if (waitFor) { |
|
||||||
try { |
|
||||||
SwingUtilities.invokeAndWait(new Runnable() { |
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
initInEDT(); |
|
||||||
} |
|
||||||
}); |
|
||||||
} catch (InterruptedException ex) { |
|
||||||
listener.handleError("Interrupted", ex); |
|
||||||
} |
|
||||||
} else { |
|
||||||
SwingUtilities.invokeLater(new Runnable() { |
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
initInEDT(); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
} catch (InvocationTargetException ex) { |
|
||||||
throw new AssertionError(); // can never happen
|
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy(boolean waitFor){ |
|
||||||
needClose.set(true); |
|
||||||
if (waitFor){ |
|
||||||
waitFor(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void restart() { |
|
||||||
if (created.get()){ |
|
||||||
needRestart.set(true); |
|
||||||
}else{ |
|
||||||
throw new IllegalStateException("Display not started yet. Cannot restart"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setTitle(String title){ |
|
||||||
if (frame != null) |
|
||||||
frame.setTitle(title); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void display(GLAutoDrawable drawable) { |
|
||||||
if (needClose.get()) { |
|
||||||
listener.destroy(); |
|
||||||
animator.stop(); |
|
||||||
if (settings.isFullscreen()) { |
|
||||||
device.setFullScreenWindow(null); |
|
||||||
} |
|
||||||
frame.dispose(); |
|
||||||
logger.fine("Display destroyed."); |
|
||||||
super.internalDestroy(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (windowCloseRequest.get()){ |
|
||||||
listener.requestClose(false); |
|
||||||
windowCloseRequest.set(false); |
|
||||||
} |
|
||||||
|
|
||||||
if (needRestart.getAndSet(false)){ |
|
||||||
// for restarting contexts
|
|
||||||
if (frame.isVisible()){ |
|
||||||
animator.stop(); |
|
||||||
frame.dispose(); |
|
||||||
createGLFrame(); |
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// boolean flush = autoFlush.get();
|
|
||||||
// if (animator.isAnimating() != flush){
|
|
||||||
// if (flush)
|
|
||||||
// animator.stop();
|
|
||||||
// else
|
|
||||||
// animator.start();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (wasActive != active.get()){ |
|
||||||
if (!wasActive){ |
|
||||||
listener.gainFocus(); |
|
||||||
wasActive = true; |
|
||||||
}else{ |
|
||||||
listener.loseFocus(); |
|
||||||
wasActive = false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
listener.update(); |
|
||||||
renderer.postFrame(); |
|
||||||
} |
|
||||||
} |
|
@ -1,80 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.jogl; |
|
||||||
|
|
||||||
import java.util.HashMap; |
|
||||||
|
|
||||||
import com.jogamp.opengl.GL2ES2; |
|
||||||
import com.jogamp.opengl.GLDebugListener; |
|
||||||
import com.jogamp.opengl.GLDebugMessage; |
|
||||||
|
|
||||||
class JoglGLDebugOutputHandler implements GLDebugListener { |
|
||||||
|
|
||||||
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(GL2ES2.GL_DEBUG_SOURCE_API, "API"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SOURCE_APPLICATION, "APPLICATION"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SOURCE_OTHER, "OTHER"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SOURCE_SHADER_COMPILER, "SHADER_COMPILER"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SOURCE_THIRD_PARTY, "THIRD_PARTY"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SOURCE_WINDOW_SYSTEM, "WINDOW_SYSTEM"); |
|
||||||
|
|
||||||
constMap.put(GL2ES2.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, "DEPRECATED_BEHAVIOR"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_TYPE_ERROR, "ERROR"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_TYPE_OTHER, "OTHER"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_TYPE_PERFORMANCE, "PERFORMANCE"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_TYPE_PORTABILITY, "PORTABILITY"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, "UNDEFINED_BEHAVIOR"); |
|
||||||
|
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SEVERITY_HIGH, "HIGH"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SEVERITY_MEDIUM, "MEDIUM"); |
|
||||||
constMap.put(GL2ES2.GL_DEBUG_SEVERITY_LOW, "LOW"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void messageSent(GLDebugMessage event) { |
|
||||||
String sourceStr = constMap.get(event.getDbgSource()); |
|
||||||
String typeStr = constMap.get(event.getDbgType()); |
|
||||||
String severityStr = constMap.get(event.getDbgSeverity()); |
|
||||||
|
|
||||||
System.err.println(String.format(MESSAGE_FORMAT, event.getDbgId(), sourceStr, typeStr, severityStr, event.getDbgMsg())); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,176 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.system.jogl; |
|
||||||
|
|
||||||
import com.jme3.input.KeyInput; |
|
||||||
import com.jme3.input.MouseInput; |
|
||||||
import com.jme3.input.TouchInput; |
|
||||||
import com.jme3.input.jogl.NewtKeyInput; |
|
||||||
import com.jme3.input.jogl.NewtMouseInput; |
|
||||||
import com.jme3.system.AppSettings; |
|
||||||
import com.jogamp.newt.opengl.GLWindow; |
|
||||||
import com.jogamp.opengl.util.Animator; |
|
||||||
import com.jogamp.opengl.util.AnimatorBase; |
|
||||||
import com.jogamp.opengl.util.FPSAnimator; |
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import com.jogamp.opengl.GLAutoDrawable; |
|
||||||
import com.jogamp.opengl.GLCapabilities; |
|
||||||
import com.jogamp.opengl.GLEventListener; |
|
||||||
import com.jogamp.opengl.GLProfile; |
|
||||||
import com.jogamp.opengl.GLRunnable; |
|
||||||
|
|
||||||
public abstract class JoglNewtAbstractDisplay extends JoglContext implements GLEventListener { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglNewtAbstractDisplay.class.getName()); |
|
||||||
|
|
||||||
protected GLWindow canvas; |
|
||||||
|
|
||||||
protected AnimatorBase animator; |
|
||||||
|
|
||||||
protected AtomicBoolean active = new AtomicBoolean(false); |
|
||||||
|
|
||||||
protected boolean wasActive = false; |
|
||||||
|
|
||||||
protected int frameRate; |
|
||||||
|
|
||||||
protected boolean useAwt = true; |
|
||||||
|
|
||||||
protected AtomicBoolean autoFlush = new AtomicBoolean(true); |
|
||||||
|
|
||||||
protected boolean wasAnimating = false; |
|
||||||
|
|
||||||
protected void initGLCanvas() { |
|
||||||
GLCapabilities caps; |
|
||||||
if (settings.getRenderer().equals(AppSettings.JOGL_OPENGL_FORWARD_COMPATIBLE)) { |
|
||||||
caps = new GLCapabilities(GLProfile.getMaxProgrammable(true)); |
|
||||||
} else { |
|
||||||
caps = new GLCapabilities(GLProfile.getMaxFixedFunc(true)); |
|
||||||
} |
|
||||||
caps.setHardwareAccelerated(true); |
|
||||||
caps.setDoubleBuffered(true); |
|
||||||
caps.setStencilBits(settings.getStencilBits()); |
|
||||||
caps.setDepthBits(settings.getDepthBits()); |
|
||||||
|
|
||||||
if (settings.getSamples() > 1) { |
|
||||||
caps.setSampleBuffers(true); |
|
||||||
caps.setNumSamples(settings.getSamples()); |
|
||||||
} |
|
||||||
canvas = GLWindow.create(caps); |
|
||||||
canvas.invoke(false, new GLRunnable() { |
|
||||||
@Override |
|
||||||
public boolean run(GLAutoDrawable glad) { |
|
||||||
canvas.getGL().setSwapInterval(settings.isVSync() ? 1 : 0); |
|
||||||
return true; |
|
||||||
} |
|
||||||
}); |
|
||||||
canvas.requestFocus(); |
|
||||||
canvas.setSize(settings.getWidth(), settings.getHeight()); |
|
||||||
canvas.addGLEventListener(this); |
|
||||||
|
|
||||||
//FIXME not sure it is the best place to do that
|
|
||||||
renderable.set(true); |
|
||||||
} |
|
||||||
|
|
||||||
protected void startGLCanvas() { |
|
||||||
if (frameRate > 0) { |
|
||||||
animator = new FPSAnimator(canvas, frameRate); |
|
||||||
} |
|
||||||
else { |
|
||||||
animator = new Animator(); |
|
||||||
animator.add(canvas); |
|
||||||
((Animator) animator).setRunAsFastAsPossible(true); |
|
||||||
} |
|
||||||
|
|
||||||
animator.start(); |
|
||||||
wasAnimating = true; |
|
||||||
} |
|
||||||
|
|
||||||
protected void onCanvasAdded() { |
|
||||||
} |
|
||||||
|
|
||||||
protected void onCanvasRemoved() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public KeyInput getKeyInput() { |
|
||||||
if (keyInput == null) { |
|
||||||
keyInput = new NewtKeyInput(); |
|
||||||
((NewtKeyInput)keyInput).setInputSource(canvas); |
|
||||||
} |
|
||||||
return keyInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public MouseInput getMouseInput() { |
|
||||||
if (mouseInput == null) { |
|
||||||
mouseInput = new NewtMouseInput(); |
|
||||||
((NewtMouseInput)mouseInput).setInputSource(canvas); |
|
||||||
} |
|
||||||
return mouseInput; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public TouchInput getTouchInput() { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setAutoFlushFrames(boolean enabled) { |
|
||||||
autoFlush.set(enabled); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { |
|
||||||
listener.reshape(width, height); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback. |
|
||||||
*/ |
|
||||||
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void dispose(GLAutoDrawable drawable) { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,177 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.jogl; |
|
||||||
|
|
||||||
import com.jme3.system.JmeCanvasContext; |
|
||||||
import com.jogamp.newt.awt.NewtCanvasAWT; |
|
||||||
import java.util.logging.Logger; |
|
||||||
import com.jogamp.opengl.GLAutoDrawable; |
|
||||||
|
|
||||||
public class JoglNewtCanvas extends JoglNewtAbstractDisplay implements JmeCanvasContext { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglNewtCanvas.class.getName()); |
|
||||||
private int width, height; |
|
||||||
private boolean runningFirstTime = true; |
|
||||||
|
|
||||||
private NewtCanvasAWT newtAwtCanvas; |
|
||||||
|
|
||||||
public JoglNewtCanvas(){ |
|
||||||
super(); |
|
||||||
initGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final void initGLCanvas() { |
|
||||||
super.initGLCanvas(); |
|
||||||
newtAwtCanvas = new NewtCanvasAWT(canvas) { |
|
||||||
private static final long serialVersionUID = 1L; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void addNotify() { |
|
||||||
super.addNotify(); |
|
||||||
onCanvasAdded(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void removeNotify() { |
|
||||||
onCanvasRemoved(); |
|
||||||
super.removeNotify(); |
|
||||||
} |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Type getType() { |
|
||||||
return Type.Canvas; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setTitle(String title) { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void restart() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void create(boolean waitFor){ |
|
||||||
if (waitFor) |
|
||||||
waitFor(true); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy(boolean waitFor){ |
|
||||||
if (waitFor) |
|
||||||
waitFor(false); |
|
||||||
if (animator.isAnimating()) |
|
||||||
animator.stop(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void onCanvasRemoved(){ |
|
||||||
super.onCanvasRemoved(); |
|
||||||
created.set(false); |
|
||||||
waitFor(false); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void onCanvasAdded(){ |
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void init(GLAutoDrawable drawable) { |
|
||||||
canvas.requestFocus(); |
|
||||||
|
|
||||||
super.internalCreate(); |
|
||||||
logger.fine("Display created."); |
|
||||||
|
|
||||||
// At this point, the OpenGL context is active.
|
|
||||||
if (runningFirstTime){ |
|
||||||
// THIS is the part that creates the renderer.
|
|
||||||
// It must always be called, now that we have the pbuffer workaround.
|
|
||||||
initContextFirstTime(); |
|
||||||
runningFirstTime = false; |
|
||||||
} |
|
||||||
listener.initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void startGLCanvas() { |
|
||||||
frameRate = settings.getFrameRate(); |
|
||||||
super.startGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void display(GLAutoDrawable glad) { |
|
||||||
if (!created.get() && renderer != null){ |
|
||||||
listener.destroy(); |
|
||||||
logger.fine("Canvas destroyed."); |
|
||||||
super.internalDestroy(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
int newWidth = Math.max(canvas.getWidth(), 1); |
|
||||||
int newHeight = Math.max(canvas.getHeight(), 1); |
|
||||||
if (width != newWidth || height != newHeight) { |
|
||||||
width = newWidth; |
|
||||||
height = newHeight; |
|
||||||
if (listener != null) { |
|
||||||
listener.reshape(width, height); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
boolean flush = autoFlush.get(); |
|
||||||
if (flush && !wasAnimating){ |
|
||||||
animator.start(); |
|
||||||
wasAnimating = true; |
|
||||||
}else if (!flush && wasAnimating){ |
|
||||||
animator.stop(); |
|
||||||
wasAnimating = false; |
|
||||||
} |
|
||||||
|
|
||||||
listener.update(); |
|
||||||
renderer.postFrame(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public NewtCanvasAWT getCanvas() { |
|
||||||
return newtAwtCanvas; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void dispose(GLAutoDrawable arg0) { |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,254 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009-2020 jMonkeyEngine |
|
||||||
* All rights reserved. |
|
||||||
* |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions are |
|
||||||
* met: |
|
||||||
* |
|
||||||
* * Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* |
|
||||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer in the |
|
||||||
* documentation and/or other materials provided with the distribution. |
|
||||||
* |
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
|
||||||
* may be used to endorse or promote products derived from this software |
|
||||||
* without specific prior written permission. |
|
||||||
* |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.jme3.system.jogl; |
|
||||||
|
|
||||||
import com.jme3.system.AppSettings; |
|
||||||
import com.jogamp.newt.MonitorMode; |
|
||||||
import com.jogamp.newt.Screen; |
|
||||||
import com.jogamp.newt.event.WindowAdapter; |
|
||||||
import com.jogamp.newt.event.WindowEvent; |
|
||||||
import com.jogamp.newt.util.MonitorModeUtil; |
|
||||||
import java.util.List; |
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
import com.jogamp.nativewindow.util.Dimension; |
|
||||||
import com.jogamp.opengl.GLAutoDrawable; |
|
||||||
|
|
||||||
public class JoglNewtDisplay extends JoglNewtAbstractDisplay { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglNewtDisplay.class.getName()); |
|
||||||
|
|
||||||
protected AtomicBoolean windowCloseRequest = new AtomicBoolean(false); |
|
||||||
protected AtomicBoolean needClose = new AtomicBoolean(false); |
|
||||||
protected AtomicBoolean needRestart = new AtomicBoolean(false); |
|
||||||
protected volatile boolean wasInited = false; |
|
||||||
|
|
||||||
@Override |
|
||||||
public Type getType() { |
|
||||||
return Type.Display; |
|
||||||
} |
|
||||||
|
|
||||||
protected void createGLFrame(){ |
|
||||||
canvas.setTitle(settings.getTitle()); |
|
||||||
|
|
||||||
applySettings(settings); |
|
||||||
|
|
||||||
// Make the window visible to realize the OpenGL surface.
|
|
||||||
canvas.setVisible(true); |
|
||||||
|
|
||||||
//this is the earliest safe opportunity to get the context
|
|
||||||
//final GLContext context = canvas.getContext();
|
|
||||||
|
|
||||||
/*canvas.invoke(true, new GLRunnable() { |
|
||||||
@Override |
|
||||||
public boolean run(GLAutoDrawable glAutoDrawable) { |
|
||||||
context.makeCurrent(); |
|
||||||
try { |
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
finally { |
|
||||||
context.release(); |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
});*/ |
|
||||||
} |
|
||||||
|
|
||||||
protected void applySettings(AppSettings settings){ |
|
||||||
active.set(true); |
|
||||||
canvas.addWindowListener(new WindowAdapter() { |
|
||||||
@Override |
|
||||||
public void windowDestroyNotify(WindowEvent e) { |
|
||||||
windowCloseRequest.set(true); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void windowGainedFocus(WindowEvent e) { |
|
||||||
active.set(true); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void windowLostFocus(WindowEvent e) { |
|
||||||
active.set(false); |
|
||||||
} |
|
||||||
}); |
|
||||||
canvas.setSize(settings.getWidth(), settings.getHeight()); |
|
||||||
canvas.setUndecorated(settings.isFullscreen()); |
|
||||||
canvas.setFullscreen(settings.isFullscreen()); |
|
||||||
|
|
||||||
/** |
|
||||||
* uses the filtering relying on resolution with the size to fetch only |
|
||||||
* the screen mode matching with the current resolution |
|
||||||
*/ |
|
||||||
Screen screen = canvas.getScreen(); |
|
||||||
/** |
|
||||||
* The creation of native resources is lazy in JogAmp, i.e they are |
|
||||||
* created only when they are used for the first time. When the GLWindow |
|
||||||
* is not yet visible, its screen might have been unused for now and |
|
||||||
* then its native counterpart has not yet been created. That's why |
|
||||||
* forcing the creation of this resource is necessary |
|
||||||
*/ |
|
||||||
screen.addReference(); |
|
||||||
if (settings.isFullscreen()) { |
|
||||||
List<MonitorMode> screenModes = canvas.getMainMonitor().getSupportedModes(); |
|
||||||
//the resolution is provided by the user
|
|
||||||
Dimension dimension = new Dimension(settings.getWidth(), settings.getHeight()); |
|
||||||
screenModes = MonitorModeUtil.filterByResolution(screenModes, dimension); |
|
||||||
screenModes = MonitorModeUtil.getHighestAvailableBpp(screenModes); |
|
||||||
if (settings.getFrequency() > 0) { |
|
||||||
screenModes = MonitorModeUtil.filterByRate(screenModes, settings.getFrequency()); |
|
||||||
} else { |
|
||||||
screenModes = MonitorModeUtil.getHighestAvailableRate(screenModes); |
|
||||||
} |
|
||||||
canvas.getMainMonitor().setCurrentMode(screenModes.get(0)); |
|
||||||
} |
|
||||||
|
|
||||||
MonitorMode currentScreenMode = canvas.getMainMonitor().getCurrentMode(); |
|
||||||
logger.log(Level.FINE, "Selected display mode: {0}x{1}x{2} @{3}", |
|
||||||
new Object[]{currentScreenMode.getRotatedWidth(), |
|
||||||
currentScreenMode.getRotatedHeight(), |
|
||||||
currentScreenMode.getSurfaceSize().getBitsPerPixel(), |
|
||||||
currentScreenMode.getRefreshRate()}); |
|
||||||
} |
|
||||||
|
|
||||||
private void privateInit(){ |
|
||||||
initGLCanvas(); |
|
||||||
|
|
||||||
createGLFrame(); |
|
||||||
|
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void init(GLAutoDrawable drawable){ |
|
||||||
// prevent initializing twice on restart
|
|
||||||
if (!wasInited){ |
|
||||||
wasInited = true; |
|
||||||
|
|
||||||
canvas.requestFocus(); |
|
||||||
|
|
||||||
super.internalCreate(); |
|
||||||
logger.fine("Display created."); |
|
||||||
|
|
||||||
renderer.initialize(); |
|
||||||
listener.initialize(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void create(boolean waitFor){ |
|
||||||
privateInit(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy(boolean waitFor){ |
|
||||||
needClose.set(true); |
|
||||||
if (waitFor){ |
|
||||||
waitFor(false); |
|
||||||
} |
|
||||||
if (animator.isAnimating()) |
|
||||||
animator.stop(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void restart() { |
|
||||||
if (created.get()){ |
|
||||||
needRestart.set(true); |
|
||||||
}else{ |
|
||||||
throw new IllegalStateException("Display not started yet. Cannot restart"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setTitle(String title){ |
|
||||||
if (canvas != null) { |
|
||||||
canvas.setTitle(title); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void display(GLAutoDrawable drawable) { |
|
||||||
if (needClose.get()) { |
|
||||||
listener.destroy(); |
|
||||||
animator.stop(); |
|
||||||
if (settings.isFullscreen()) { |
|
||||||
canvas.setFullscreen(false); |
|
||||||
} |
|
||||||
canvas.destroy(); |
|
||||||
logger.fine("Display destroyed."); |
|
||||||
super.internalDestroy(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (windowCloseRequest.get()){ |
|
||||||
listener.requestClose(false); |
|
||||||
windowCloseRequest.set(false); |
|
||||||
} |
|
||||||
|
|
||||||
if (needRestart.getAndSet(false)){ |
|
||||||
// for restarting contexts
|
|
||||||
if (canvas.isVisible()){ |
|
||||||
animator.stop(); |
|
||||||
canvas.destroy(); |
|
||||||
createGLFrame(); |
|
||||||
startGLCanvas(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// boolean flush = autoFlush.get();
|
|
||||||
// if (animator.isAnimating() != flush){
|
|
||||||
// if (flush)
|
|
||||||
// animator.stop();
|
|
||||||
// else
|
|
||||||
// animator.start();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (wasActive != active.get()){ |
|
||||||
if (!wasActive){ |
|
||||||
listener.gainFocus(); |
|
||||||
wasActive = true; |
|
||||||
}else{ |
|
||||||
listener.loseFocus(); |
|
||||||
wasActive = false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
listener.update(); |
|
||||||
renderer.postFrame(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,206 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.jogl; |
|
||||||
|
|
||||||
import com.jme3.input.JoyInput; |
|
||||||
import com.jme3.input.KeyInput; |
|
||||||
import com.jme3.input.MouseInput; |
|
||||||
import com.jme3.input.TouchInput; |
|
||||||
import com.jme3.input.dummy.DummyKeyInput; |
|
||||||
import com.jme3.input.dummy.DummyMouseInput; |
|
||||||
import com.jme3.system.AppSettings; |
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import com.jogamp.opengl.GLCapabilities; |
|
||||||
import com.jogamp.opengl.GLDrawableFactory; |
|
||||||
import com.jogamp.opengl.GLOffscreenAutoDrawable; |
|
||||||
import com.jogamp.opengl.GLProfile; |
|
||||||
import com.jogamp.opengl.JoglVersion; |
|
||||||
|
|
||||||
|
|
||||||
public class JoglOffscreenBuffer extends JoglContext implements Runnable { |
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(JoglOffscreenBuffer.class.getName()); |
|
||||||
private GLOffscreenAutoDrawable offscreenDrawable; |
|
||||||
protected AtomicBoolean needClose = new AtomicBoolean(false); |
|
||||||
private int width; |
|
||||||
private int height; |
|
||||||
private GLCapabilities caps; |
|
||||||
|
|
||||||
protected void initInThread(){ |
|
||||||
// not necessary as JOGL can create an offscreen buffer even without full FBO support
|
|
||||||
// if (!GLContext.getCurrent().hasFullFBOSupport()){
|
|
||||||
// logger.severe("Offscreen surfaces are not supported.");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
final GLProfile profile; |
|
||||||
if (settings.getRenderer().equals(AppSettings.JOGL_OPENGL_FORWARD_COMPATIBLE)) { |
|
||||||
profile = GLProfile.getMaxProgrammable(true); |
|
||||||
} else { |
|
||||||
profile = GLProfile.getMaxFixedFunc(true); |
|
||||||
} |
|
||||||
caps = new GLCapabilities(profile); |
|
||||||
int samples = getNumSamplesToUse(); |
|
||||||
caps.setHardwareAccelerated(true); |
|
||||||
caps.setDoubleBuffered(true); |
|
||||||
caps.setStencilBits(settings.getStencilBits()); |
|
||||||
caps.setDepthBits(settings.getDepthBits()); |
|
||||||
caps.setOnscreen(false); |
|
||||||
caps.setSampleBuffers(true); |
|
||||||
caps.setNumSamples(samples); |
|
||||||
|
|
||||||
offscreenDrawable = GLDrawableFactory.getFactory(profile).createOffscreenAutoDrawable(null, caps, null, width, height); |
|
||||||
|
|
||||||
offscreenDrawable.display(); |
|
||||||
|
|
||||||
renderable.set(true); |
|
||||||
|
|
||||||
logger.fine("Offscreen buffer created."); |
|
||||||
|
|
||||||
super.internalCreate(); |
|
||||||
listener.initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void initContextFirstTime(){ |
|
||||||
offscreenDrawable.getContext().makeCurrent(); |
|
||||||
try { |
|
||||||
super.initContextFirstTime(); |
|
||||||
} finally { |
|
||||||
offscreenDrawable.getContext().release(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected boolean checkGLError(){ |
|
||||||
//FIXME
|
|
||||||
// NOTE: Always return true since this is used in an "assert" statement
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
protected void runLoop(){ |
|
||||||
if (!created.get()) { |
|
||||||
throw new IllegalStateException(); |
|
||||||
} |
|
||||||
|
|
||||||
listener.update(); |
|
||||||
checkGLError(); |
|
||||||
|
|
||||||
renderer.postFrame(); |
|
||||||
|
|
||||||
int frameRate = settings.getFrameRate(); |
|
||||||
if (frameRate >= 1) { |
|
||||||
//FIXME
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected void deinitInThread(){ |
|
||||||
renderable.set(false); |
|
||||||
|
|
||||||
listener.destroy(); |
|
||||||
renderer.cleanup(); |
|
||||||
offscreenDrawable.destroy(); |
|
||||||
logger.fine("Offscreen buffer destroyed."); |
|
||||||
|
|
||||||
super.internalDestroy(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
logger.log(Level.FINE, "Using JOGL {0}", JoglVersion.getInstance().getImplementationVersion()); |
|
||||||
initInThread(); |
|
||||||
while (!needClose.get()){ |
|
||||||
runLoop(); |
|
||||||
} |
|
||||||
deinitInThread(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void destroy(boolean waitFor){ |
|
||||||
needClose.set(true); |
|
||||||
if (waitFor) { |
|
||||||
waitFor(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void create(boolean waitFor){ |
|
||||||
if (created.get()){ |
|
||||||
logger.warning("create() called when pbuffer is already created!"); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
new Thread(this, THREAD_NAME).start(); |
|
||||||
if (waitFor) { |
|
||||||
waitFor(true); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void restart() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setAutoFlushFrames(boolean enabled){ |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Type getType() { |
|
||||||
return Type.OffscreenSurface; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public MouseInput getMouseInput() { |
|
||||||
return new DummyMouseInput(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public KeyInput getKeyInput() { |
|
||||||
return new DummyKeyInput(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public JoyInput getJoyInput() { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public TouchInput getTouchInput() { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setTitle(String title) { |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue