A complete 3D game development suite written purely in Java.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jmonkeyengine/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java

479 lines
17 KiB

/*
* 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.system.android;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ConfigurationInfo;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.text.InputType;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.FrameLayout;
import com.jme3.input.*;
import com.jme3.input.android.AndroidInputHandler;
import com.jme3.input.android.AndroidInputHandler14;
import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.android.AndroidGL;
import com.jme3.renderer.opengl.*;
import com.jme3.system.*;
import com.jme3.util.AndroidBufferAllocator;
import com.jme3.util.BufferAllocatorFactory;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());
protected final AtomicBoolean created = new AtomicBoolean(false);
protected final AtomicBoolean renderable = new AtomicBoolean(false);
protected final AtomicBoolean needClose = new AtomicBoolean(false);
protected AppSettings settings = new AppSettings(true);
protected GLRenderer renderer;
protected Timer timer;
protected SystemListener listener;
protected boolean autoFlush = true;
protected AndroidInputHandler androidInput;
protected long minFrameDuration = 0; // No FPS cap
protected long lastUpdateTime = 0;
static {
final String implementation = BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION;
if (System.getProperty(implementation) == null) {
System.setProperty(implementation, AndroidBufferAllocator.class.getName());
}
}
public OGLESContext() {
}
@Override
public Type getType() {
return Type.Display;
}
/**
* <code>createView</code> creates the GLSurfaceView that the renderer will
* draw to. <p> The result GLSurfaceView will receive input events and
* forward them to the Application. Any rendering will be done into the
* GLSurfaceView. Only one GLSurfaceView can be created at this time. The
* given configType specifies how to determine the display configuration.
*
* @return GLSurfaceView The newly created view
*/
public GLSurfaceView createView(Context context) {
Android openGL ES 3 support (#1147) * Update GLImageFormats.java * Added basic support for openGL ES 3.0 and GLSL300 for android Added instancing support for android which is core feature in GLES3.0 Added fix for shadows in android * Fixed required types of GLES30.glDrawElementsInstanced * Properly check GLES3 version and setting precision for shaders for all GLSL ES versions * Added support for Opengl ES 3.1 and 3.2 and their shader versions Added proper checkings for new OpenGL ES versions Fixed some issues with shadow rendering in GLES 3.0 or better (strict type checking, OpenGL ES specific extensions and percision definition) Added GLSL320 and GLSL300 to Unshaded and Lighting materials * Added depth texture 24bit for OpenGL ES * Added geometry shaders and tessellation to GLES 3.1 as extension and GLES 3.2 as core Modified test materials to use GLSL310 * Added FB blit for android GLES30 * Added GlSL300 or better to all effects not able to run in GLSL100 Mods on Shadows.glsllib to try to fix android shadow rendering Fixed ssaoBlur.frag that was using a reserved word Fixed precision type missmatch from vertex to fragment shader * Partial multisample support Framebuffer MRT support * Temporarily removed texture multisampling (not being able to compile using GLES31) * Updated android.jar to api28 Enabled multisampling * Better checking for GLES3 * Removed insert precision for all shaders. This avoided some random precision missmatch error but created rendering issues * Removed border check for GLES, caused filtered shadows not to render on GLES2.0 devices Added texture compare mode for GLES3.0 and better to be able to use sampler2DShadow Modified base materials (Lighting and Unshaded) to use only GLSL100 for post shadow pass * Corrected texture comparison function that were incorrectly changed * Added precision to samplers for GLESSL300 also * Created a subclass of Glsl150ShaderGenerator (Glsl300ShaderGenerator) to support ShaderNodes in GLES SL30 and included it's usage in DesktopAssetManager. Nowadays just copied and overwrote the version string. Needs a full review Added image format RGB16F to be used as texture format only in GLES30 (cannot be used as FB format) Added GLSL300 and/or GLSL310 to different materials * Cleaned GLSL300 generator Fixed shadows glsl lib removing use of GL_EXT_gpu_shaders5 * Fixed usag of textureCubeLod in fragment shader of envMapping which is unsupported in GLES2.0 Modified PBRLighting frag to properly compile on GLES3 * Added GLSL300 and 310 to PostShadowFilter material definition * Make post shadow filter use GLSL100 for GLSL300 Set highp as default precision to fix glitched shadows caused because not enough precision * Changed water_normalmap.dds to uncompressed RGB8 because DXT1 is mostly unsupported in GLES * Fixed GLES30 compilation issues in Water shaders and added GLSL300 to LightScattering material. ** Not fully tested * Added RGB8 dds formatted FullskiesSunset to be used in any platform. Previous file moved to _dtx1.dds * Set GL_TEXTURE_MAX_LEVEL in GLES30 contexts fixing issue with not fully mipmapped images and PBR rendering * Fixed compilation of jme3-android-examples and upgraded sdk version to use * Fixed Geometry Shader and Tessellation Shaders in testdata package to properly compile on GLES320 * Added non-compressed textures to be able to run all examples on android Enabled texture arrays and 3d textures on opengl es 3.0. Peding to implement wrappers to android gl functions (currently getting NullPointerException) * More GLES30 functions included to properly support texture arrays, 3d textures and multisampling matching jme core code * Fixed 3D texture tests for GLES30 Fixed texture 3D and texture array example shader compilation on GLES30 Fixed some random missing precision compilation errors on GLES30 * Fixed TestTextureArray for GLES30 * Some multisample additions and removal of GLES3 multisampling enable caps Added RGBA16F as valid format for GLES32 and using it by default in env camera instead of RGB16F. kept fall back to RGB8 * added float and half float formats for gles30 added rgb10a2 format for gles30 fixed usage of glTexImage2D removed EnvironmentCamera fallback image format as it's useless now * Added more image formats for GLES30 Fixed rgb8 if having Caps.Rgba8 * Enabled RadialBlur for gles30 * Fixed luminance texture formats for gles * Added more depth image formats for gles3 * Enabled multisampling in gles3 * Added GLES30 functions to GLDebugES Reverted TestTexture3D and TestTextureArray to use RGB8 format Updated EnvMapping100.frag to use EXT_shader_texture_lod in gles sl 100 if available * Removed all aditional not used compressed dds files Removed also Pond and rock png files previously used in TestTextureArray * Removed compressed water_normalmap_dxt1.dds * Changed GLES_30 and AndroidGL implementing GL2 to avoid duplicated code checking GL2 vs GLES30 * Added aditional checking to avoid gles30 calls from gles20 only devices
5 years ago
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
// NOTE: We assume all ICS devices have OpenGL ES 2.0.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// below 4.0, check OpenGL ES 2.0 support.
if (info.reqGlEsVersion < 0x20000) {
Android openGL ES 3 support (#1147) * Update GLImageFormats.java * Added basic support for openGL ES 3.0 and GLSL300 for android Added instancing support for android which is core feature in GLES3.0 Added fix for shadows in android * Fixed required types of GLES30.glDrawElementsInstanced * Properly check GLES3 version and setting precision for shaders for all GLSL ES versions * Added support for Opengl ES 3.1 and 3.2 and their shader versions Added proper checkings for new OpenGL ES versions Fixed some issues with shadow rendering in GLES 3.0 or better (strict type checking, OpenGL ES specific extensions and percision definition) Added GLSL320 and GLSL300 to Unshaded and Lighting materials * Added depth texture 24bit for OpenGL ES * Added geometry shaders and tessellation to GLES 3.1 as extension and GLES 3.2 as core Modified test materials to use GLSL310 * Added FB blit for android GLES30 * Added GlSL300 or better to all effects not able to run in GLSL100 Mods on Shadows.glsllib to try to fix android shadow rendering Fixed ssaoBlur.frag that was using a reserved word Fixed precision type missmatch from vertex to fragment shader * Partial multisample support Framebuffer MRT support * Temporarily removed texture multisampling (not being able to compile using GLES31) * Updated android.jar to api28 Enabled multisampling * Better checking for GLES3 * Removed insert precision for all shaders. This avoided some random precision missmatch error but created rendering issues * Removed border check for GLES, caused filtered shadows not to render on GLES2.0 devices Added texture compare mode for GLES3.0 and better to be able to use sampler2DShadow Modified base materials (Lighting and Unshaded) to use only GLSL100 for post shadow pass * Corrected texture comparison function that were incorrectly changed * Added precision to samplers for GLESSL300 also * Created a subclass of Glsl150ShaderGenerator (Glsl300ShaderGenerator) to support ShaderNodes in GLES SL30 and included it's usage in DesktopAssetManager. Nowadays just copied and overwrote the version string. Needs a full review Added image format RGB16F to be used as texture format only in GLES30 (cannot be used as FB format) Added GLSL300 and/or GLSL310 to different materials * Cleaned GLSL300 generator Fixed shadows glsl lib removing use of GL_EXT_gpu_shaders5 * Fixed usag of textureCubeLod in fragment shader of envMapping which is unsupported in GLES2.0 Modified PBRLighting frag to properly compile on GLES3 * Added GLSL300 and 310 to PostShadowFilter material definition * Make post shadow filter use GLSL100 for GLSL300 Set highp as default precision to fix glitched shadows caused because not enough precision * Changed water_normalmap.dds to uncompressed RGB8 because DXT1 is mostly unsupported in GLES * Fixed GLES30 compilation issues in Water shaders and added GLSL300 to LightScattering material. ** Not fully tested * Added RGB8 dds formatted FullskiesSunset to be used in any platform. Previous file moved to _dtx1.dds * Set GL_TEXTURE_MAX_LEVEL in GLES30 contexts fixing issue with not fully mipmapped images and PBR rendering * Fixed compilation of jme3-android-examples and upgraded sdk version to use * Fixed Geometry Shader and Tessellation Shaders in testdata package to properly compile on GLES320 * Added non-compressed textures to be able to run all examples on android Enabled texture arrays and 3d textures on opengl es 3.0. Peding to implement wrappers to android gl functions (currently getting NullPointerException) * More GLES30 functions included to properly support texture arrays, 3d textures and multisampling matching jme core code * Fixed 3D texture tests for GLES30 Fixed texture 3D and texture array example shader compilation on GLES30 Fixed some random missing precision compilation errors on GLES30 * Fixed TestTextureArray for GLES30 * Some multisample additions and removal of GLES3 multisampling enable caps Added RGBA16F as valid format for GLES32 and using it by default in env camera instead of RGB16F. kept fall back to RGB8 * added float and half float formats for gles30 added rgb10a2 format for gles30 fixed usage of glTexImage2D removed EnvironmentCamera fallback image format as it's useless now * Added more image formats for GLES30 Fixed rgb8 if having Caps.Rgba8 * Enabled RadialBlur for gles30 * Fixed luminance texture formats for gles * Added more depth image formats for gles3 * Enabled multisampling in gles3 * Added GLES30 functions to GLDebugES Reverted TestTexture3D and TestTextureArray to use RGB8 format Updated EnvMapping100.frag to use EXT_shader_texture_lod in gles sl 100 if available * Removed all aditional not used compressed dds files Removed also Pond and rock png files previously used in TestTextureArray * Removed compressed water_normalmap_dxt1.dds * Changed GLES_30 and AndroidGL implementing GL2 to avoid duplicated code checking GL2 vs GLES30 * Added aditional checking to avoid gles30 calls from gles20 only devices
5 years ago
throw new UnsupportedOperationException("OpenGL ES 2.0 or better is not supported on this device");
}
} else if (Build.VERSION.SDK_INT < 9){
throw new UnsupportedOperationException("jME3 requires Android 2.3 or later");
}
// Start to set up the view
GLSurfaceView view = new GLSurfaceView(context);
logger.log(Level.INFO, "Android Build Version: {0}", Build.VERSION.SDK_INT);
if (androidInput == null) {
if (Build.VERSION.SDK_INT >= 14) {
androidInput = new AndroidInputHandler14();
} else if (Build.VERSION.SDK_INT >= 9){
androidInput = new AndroidInputHandler();
}
}
androidInput.setView(view);
androidInput.loadSettings(settings);
// setEGLContextClientVersion must be set before calling setRenderer
// this means it cannot be set in AndroidConfigChooser (too late)
Android openGL ES 3 support (#1147) * Update GLImageFormats.java * Added basic support for openGL ES 3.0 and GLSL300 for android Added instancing support for android which is core feature in GLES3.0 Added fix for shadows in android * Fixed required types of GLES30.glDrawElementsInstanced * Properly check GLES3 version and setting precision for shaders for all GLSL ES versions * Added support for Opengl ES 3.1 and 3.2 and their shader versions Added proper checkings for new OpenGL ES versions Fixed some issues with shadow rendering in GLES 3.0 or better (strict type checking, OpenGL ES specific extensions and percision definition) Added GLSL320 and GLSL300 to Unshaded and Lighting materials * Added depth texture 24bit for OpenGL ES * Added geometry shaders and tessellation to GLES 3.1 as extension and GLES 3.2 as core Modified test materials to use GLSL310 * Added FB blit for android GLES30 * Added GlSL300 or better to all effects not able to run in GLSL100 Mods on Shadows.glsllib to try to fix android shadow rendering Fixed ssaoBlur.frag that was using a reserved word Fixed precision type missmatch from vertex to fragment shader * Partial multisample support Framebuffer MRT support * Temporarily removed texture multisampling (not being able to compile using GLES31) * Updated android.jar to api28 Enabled multisampling * Better checking for GLES3 * Removed insert precision for all shaders. This avoided some random precision missmatch error but created rendering issues * Removed border check for GLES, caused filtered shadows not to render on GLES2.0 devices Added texture compare mode for GLES3.0 and better to be able to use sampler2DShadow Modified base materials (Lighting and Unshaded) to use only GLSL100 for post shadow pass * Corrected texture comparison function that were incorrectly changed * Added precision to samplers for GLESSL300 also * Created a subclass of Glsl150ShaderGenerator (Glsl300ShaderGenerator) to support ShaderNodes in GLES SL30 and included it's usage in DesktopAssetManager. Nowadays just copied and overwrote the version string. Needs a full review Added image format RGB16F to be used as texture format only in GLES30 (cannot be used as FB format) Added GLSL300 and/or GLSL310 to different materials * Cleaned GLSL300 generator Fixed shadows glsl lib removing use of GL_EXT_gpu_shaders5 * Fixed usag of textureCubeLod in fragment shader of envMapping which is unsupported in GLES2.0 Modified PBRLighting frag to properly compile on GLES3 * Added GLSL300 and 310 to PostShadowFilter material definition * Make post shadow filter use GLSL100 for GLSL300 Set highp as default precision to fix glitched shadows caused because not enough precision * Changed water_normalmap.dds to uncompressed RGB8 because DXT1 is mostly unsupported in GLES * Fixed GLES30 compilation issues in Water shaders and added GLSL300 to LightScattering material. ** Not fully tested * Added RGB8 dds formatted FullskiesSunset to be used in any platform. Previous file moved to _dtx1.dds * Set GL_TEXTURE_MAX_LEVEL in GLES30 contexts fixing issue with not fully mipmapped images and PBR rendering * Fixed compilation of jme3-android-examples and upgraded sdk version to use * Fixed Geometry Shader and Tessellation Shaders in testdata package to properly compile on GLES320 * Added non-compressed textures to be able to run all examples on android Enabled texture arrays and 3d textures on opengl es 3.0. Peding to implement wrappers to android gl functions (currently getting NullPointerException) * More GLES30 functions included to properly support texture arrays, 3d textures and multisampling matching jme core code * Fixed 3D texture tests for GLES30 Fixed texture 3D and texture array example shader compilation on GLES30 Fixed some random missing precision compilation errors on GLES30 * Fixed TestTextureArray for GLES30 * Some multisample additions and removal of GLES3 multisampling enable caps Added RGBA16F as valid format for GLES32 and using it by default in env camera instead of RGB16F. kept fall back to RGB8 * added float and half float formats for gles30 added rgb10a2 format for gles30 fixed usage of glTexImage2D removed EnvironmentCamera fallback image format as it's useless now * Added more image formats for GLES30 Fixed rgb8 if having Caps.Rgba8 * Enabled RadialBlur for gles30 * Fixed luminance texture formats for gles * Added more depth image formats for gles3 * Enabled multisampling in gles3 * Added GLES30 functions to GLDebugES Reverted TestTexture3D and TestTextureArray to use RGB8 format Updated EnvMapping100.frag to use EXT_shader_texture_lod in gles sl 100 if available * Removed all aditional not used compressed dds files Removed also Pond and rock png files previously used in TestTextureArray * Removed compressed water_normalmap_dxt1.dds * Changed GLES_30 and AndroidGL implementing GL2 to avoid duplicated code checking GL2 vs GLES30 * Added aditional checking to avoid gles30 calls from gles20 only devices
5 years ago
// use proper openGL ES version
view.setEGLContextClientVersion(info.reqGlEsVersion>>16);
view.setFocusableInTouchMode(true);
view.setFocusable(true);
// setFormat must be set before AndroidConfigChooser is called by the surfaceview.
// if setFormat is called after ConfigChooser is called, then execution
// stops at the setFormat call without a crash.
// We look at the user setting for alpha bits and set the surfaceview
// PixelFormat to either Opaque, Transparent, or Translucent.
// ConfigChooser will do its best to honor the alpha requested by the user
// For best rendering performance, use Opaque (alpha bits = 0).
int curAlphaBits = settings.getAlphaBits();
logger.log(Level.FINE, "curAlphaBits: {0}", curAlphaBits);
if (curAlphaBits >= 8) {
logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
view.setZOrderOnTop(true);
} else if (curAlphaBits >= 1) {
logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
view.getHolder().setFormat(PixelFormat.TRANSPARENT);
} else {
logger.log(Level.FINE, "Pixel Format: OPAQUE");
view.getHolder().setFormat(PixelFormat.OPAQUE);
}
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings);
view.setEGLConfigChooser(configChooser);
view.setRenderer(this);
// Attempt to preserve the EGL Context on app pause/resume.
// Not destroying and recreating the EGL context
// will help with resume time by reusing the existing context to avoid
// reloading all the OpenGL objects.
if (Build.VERSION.SDK_INT >= 11) {
view.setPreserveEGLContextOnPause(true);
}
return view;
}
// renderer:initialize
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig cfg) {
if (created.get() && renderer != null) {
renderer.resetGLObjects();
} else {
if (!created.get()) {
logger.fine("GL Surface created, initializing JME3 renderer");
initInThread();
} else {
logger.warning("GL Surface already created");
}
}
}
protected void initInThread() {
created.set(true);
logger.fine("OGLESContext create");
logger.log(Level.FINE, "Running on thread: {0}", Thread.currentThread().getName());
// Setup unhandled Exception Handler
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable thrown) {
listener.handleError("Exception thrown in " + thread.toString(), thrown);
}
});
timer = new NanoTimer();
GL gl = new AndroidGL();
if (settings.getBoolean("GraphicsDebug")) {
gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GLES_30.class, GLFbo.class, GLExt.class);
}
if (settings.getBoolean("GraphicsTrace")) {
gl = (GL)GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class);
}
renderer = new GLRenderer(gl, (GLExt)gl, (GLFbo)gl);
renderer.initialize();
JmeSystem.setSoftTextDialogInput(this);
needClose.set(false);
}
/**
* De-initialize in the OpenGL thread.
*/
protected void deinitInThread() {
if (renderable.get()) {
created.set(false);
if (renderer != null) {
renderer.cleanup();
}
listener.destroy();
listener = null;
renderer = null;
timer = null;
// do android specific cleaning here
logger.fine("Display destroyed.");
renderable.set(false);
}
}
@Override
public void setSettings(AppSettings settings) {
this.settings.copyFrom(settings);
if (androidInput != null) {
androidInput.loadSettings(settings);
}
if (settings.getFrameRate() > 0) {
minFrameDuration = (long)(1000d / settings.getFrameRate()); // ms
logger.log(Level.FINE, "Setting min tpf: {0}ms", minFrameDuration);
} else {
minFrameDuration = 0;
}
}
@Override
public void setSystemListener(SystemListener listener) {
this.listener = listener;
}
@Override
public AppSettings getSettings() {
return settings;
}
@Override
public com.jme3.renderer.Renderer getRenderer() {
return renderer;
}
@Override
public MouseInput getMouseInput() {
return new DummyMouseInput();
}
@Override
public KeyInput getKeyInput() {
return new DummyKeyInput();
}
@Override
public JoyInput getJoyInput() {
return androidInput.getJoyInput();
}
@Override
public TouchInput getTouchInput() {
return androidInput.getTouchInput();
}
@Override
public Timer getTimer() {
return timer;
}
@Override
public void setTitle(String title) {
}
@Override
public boolean isCreated() {
return created.get();
}
@Override
public void setAutoFlushFrames(boolean enabled) {
this.autoFlush = enabled;
}
// SystemListener:reshape
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
logger.log(Level.FINE, "GL Surface changed, width: {0} height: {1}", new Object[]{width, height});
// update the application settings with the new resolution
settings.setResolution(width, height);
// reload settings in androidInput so the correct touch event scaling can be
// calculated in case the surface resolution is different than the view
androidInput.loadSettings(settings);
// if the application has already been initialized (ie renderable is set)
// then call reshape so the app can adjust to the new resolution.
if (renderable.get()) {
logger.log(Level.FINE, "App already initialized, calling reshape");
listener.reshape(width, height);
}
}
// SystemListener:update
@Override
public void onDrawFrame(GL10 gl) {
if (needClose.get()) {
deinitInThread();
return;
}
if (!renderable.get()) {
if (created.get()) {
logger.fine("GL Surface is setup, initializing application");
listener.initialize();
renderable.set(true);
}
} else {
if (!created.get()) {
throw new IllegalStateException("onDrawFrame without create");
}
listener.update();
if (autoFlush) {
renderer.postFrame();
}
long updateDelta = System.currentTimeMillis() - lastUpdateTime;
// Enforce a FPS cap
if (updateDelta < minFrameDuration) {
// logger.log(Level.INFO, "lastUpdateTime: {0}, updateDelta: {1}, minTimePerFrame: {2}",
// new Object[]{lastUpdateTime, updateDelta, minTimePerFrame});
try {
Thread.sleep(minFrameDuration - updateDelta);
} catch (InterruptedException e) {
}
}
lastUpdateTime = System.currentTimeMillis();
}
}
@Override
public boolean isRenderable() {
return renderable.get();
}
@Override
public void create(boolean waitFor) {
if (waitFor) {
waitFor(true);
}
}
public void create() {
create(false);
}
@Override
public void restart() {
}
@Override
public void destroy(boolean waitFor) {
needClose.set(true);
if (waitFor) {
waitFor(false);
}
}
public void destroy() {
destroy(true);
}
protected void waitFor(boolean createdVal) {
while (renderable.get() != createdVal) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
}
}
}
public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
logger.log(Level.FINE, "requestDialog: title: {0}, initialValue: {1}",
new Object[]{title, initialValue});
final View view = JmeAndroidSystem.getView();
view.getHandler().post(new Runnable() {
@Override
public void run() {
final FrameLayout layoutTextDialogInput = new FrameLayout(view.getContext());
final EditText editTextDialogInput = new EditText(view.getContext());
editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
editTextDialogInput.setPadding(20, 20, 20, 20);
editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);
//editTextDialogInput.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
editTextDialogInput.setText(initialValue);
switch (id) {
case SoftTextDialogInput.TEXT_ENTRY_DIALOG:
editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);
break;
case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:
editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
break;
case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:
editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);
break;
default:
break;
}
layoutTextDialogInput.addView(editTextDialogInput);
AlertDialog dialogTextInput = new AlertDialog.Builder(view.getContext()).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK, send COMPLETE action
* and text */
listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());
}
}).setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked CANCEL, send CANCEL action
* and text */
listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());
}
}).create();
dialogTextInput.show();
}
});
}
@Override
public com.jme3.opencl.Context getOpenCLContext() {
logger.warning("OpenCL is not yet supported on android");
return null;
}
}