2011-03-14 12:55:32 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2003-2009 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.Activity;
|
2012-03-02 10:23:22 +00:00
|
|
|
import android.app.AlertDialog;
|
2011-05-18 19:12:25 +00:00
|
|
|
import android.content.Context;
|
2012-03-02 10:23:22 +00:00
|
|
|
import android.content.DialogInterface;
|
2011-03-14 12:55:32 +00:00
|
|
|
import android.opengl.GLSurfaceView;
|
2012-03-02 10:23:22 +00:00
|
|
|
import android.text.InputType;
|
|
|
|
import android.view.Gravity;
|
2011-03-14 12:55:32 +00:00
|
|
|
import android.view.SurfaceHolder;
|
2012-03-02 10:23:22 +00:00
|
|
|
import android.view.ViewGroup.LayoutParams;
|
|
|
|
import android.widget.EditText;
|
|
|
|
import android.widget.FrameLayout;
|
2011-05-18 19:12:25 +00:00
|
|
|
import com.jme3.app.AndroidHarness;
|
2011-06-17 09:56:55 +00:00
|
|
|
import com.jme3.app.Application;
|
2011-03-14 12:55:32 +00:00
|
|
|
import com.jme3.input.JoyInput;
|
|
|
|
import com.jme3.input.KeyInput;
|
|
|
|
import com.jme3.input.MouseInput;
|
2012-03-02 10:23:22 +00:00
|
|
|
import com.jme3.input.SoftTextDialogInput;
|
2011-06-04 20:28:36 +00:00
|
|
|
import com.jme3.input.TouchInput;
|
2011-03-14 12:55:32 +00:00
|
|
|
import com.jme3.input.android.AndroidInput;
|
2012-03-02 10:23:22 +00:00
|
|
|
import com.jme3.input.controls.SoftTextDialogInputListener;
|
2011-06-17 09:56:55 +00:00
|
|
|
import com.jme3.input.controls.TouchTrigger;
|
2011-06-04 20:28:36 +00:00
|
|
|
import com.jme3.input.dummy.DummyKeyInput;
|
|
|
|
import com.jme3.input.dummy.DummyMouseInput;
|
2011-03-14 12:55:32 +00:00
|
|
|
import com.jme3.renderer.android.OGLESShaderRenderer;
|
|
|
|
import com.jme3.system.AppSettings;
|
|
|
|
import com.jme3.system.JmeContext;
|
2012-03-02 10:23:22 +00:00
|
|
|
import com.jme3.system.JmeSystem;
|
2011-03-14 12:55:32 +00:00
|
|
|
import com.jme3.system.SystemListener;
|
|
|
|
import com.jme3.system.Timer;
|
2011-06-21 22:13:42 +00:00
|
|
|
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
|
2011-03-14 12:55:32 +00:00
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
2012-02-25 19:49:15 +00:00
|
|
|
import java.util.logging.Level;
|
2011-03-14 12:55:32 +00:00
|
|
|
import java.util.logging.Logger;
|
2011-06-12 09:26:22 +00:00
|
|
|
import javax.microedition.khronos.egl.EGL10;
|
2011-03-14 12:55:32 +00:00
|
|
|
import javax.microedition.khronos.egl.EGLConfig;
|
2011-06-12 09:26:22 +00:00
|
|
|
import javax.microedition.khronos.egl.EGLContext;
|
|
|
|
import javax.microedition.khronos.egl.EGLDisplay;
|
2011-03-14 12:55:32 +00:00
|
|
|
import javax.microedition.khronos.opengles.GL10;
|
|
|
|
|
2012-03-02 10:23:22 +00:00
|
|
|
public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
|
2011-03-14 12:55:32 +00:00
|
|
|
|
|
|
|
private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());
|
2011-05-15 19:17:34 +00:00
|
|
|
protected final AtomicBoolean created = new AtomicBoolean(false);
|
|
|
|
protected final AtomicBoolean renderable = new AtomicBoolean(false);
|
|
|
|
protected final AtomicBoolean needClose = new AtomicBoolean(false);
|
|
|
|
protected final AppSettings settings = new AppSettings(true);
|
2011-03-14 12:55:32 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
/*
|
|
|
|
* >= OpenGL ES 2.0 (Android 2.2+)
|
|
|
|
*/
|
|
|
|
protected OGLESShaderRenderer renderer;
|
2011-03-14 12:55:32 +00:00
|
|
|
protected Timer timer;
|
|
|
|
protected SystemListener listener;
|
|
|
|
protected boolean autoFlush = true;
|
|
|
|
protected AndroidInput view;
|
2011-05-15 19:17:34 +00:00
|
|
|
//protected int minFrameDuration = 1000 / frameRate; // Set a max FPS of 33
|
|
|
|
protected int minFrameDuration = 0; // No FPS cap
|
2011-06-12 09:26:22 +00:00
|
|
|
/**
|
2012-02-11 06:08:49 +00:00
|
|
|
* EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 |
|
|
|
|
* EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
|
2011-06-12 09:26:22 +00:00
|
|
|
*/
|
|
|
|
protected int clientOpenGLESVersion = 1;
|
2011-08-25 17:35:30 +00:00
|
|
|
protected boolean verboseLogging = false;
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
public OGLESContext() {
|
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public Type getType() {
|
2011-03-14 12:55:32 +00:00
|
|
|
return Type.Display;
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-24 14:57:50 +00:00
|
|
|
/**
|
2012-02-11 06:08:49 +00:00
|
|
|
* <code>createView</code>
|
|
|
|
*
|
|
|
|
* @param activity The Android activity which is parent for the
|
|
|
|
* GLSurfaceView
|
2011-05-24 14:57:50 +00:00
|
|
|
* @return GLSurfaceView The newly created view
|
|
|
|
*/
|
2012-02-11 06:08:49 +00:00
|
|
|
public GLSurfaceView createView(Activity activity) {
|
|
|
|
return createView(new AndroidInput(activity));
|
2011-05-15 19:17:34 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-24 14:57:50 +00:00
|
|
|
/**
|
2012-02-11 06:08:49 +00:00
|
|
|
* <code>createView</code>
|
|
|
|
*
|
|
|
|
* @param view The Android input which will be used as the GLSurfaceView for
|
|
|
|
* this context
|
2011-05-24 14:57:50 +00:00
|
|
|
* @return GLSurfaceView The newly created view
|
|
|
|
*/
|
2012-02-11 06:08:49 +00:00
|
|
|
public GLSurfaceView createView(AndroidInput view) {
|
2011-06-24 20:11:27 +00:00
|
|
|
return createView(view, ConfigType.FASTEST, false);
|
2011-05-24 14:57:50 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-24 14:57:50 +00:00
|
|
|
/**
|
2011-07-13 10:32:00 +00:00
|
|
|
* <code>createView</code> initializes the GLSurfaceView
|
2012-02-11 06:08:49 +00:00
|
|
|
*
|
|
|
|
* @param view The Android input which will be used as the GLSurfaceView for
|
|
|
|
* this context
|
|
|
|
* @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY |
|
|
|
|
* ConfigType.BEST
|
2011-07-13 10:32:00 +00:00
|
|
|
* @param eglConfigVerboseLogging if true show all found configs
|
2011-05-24 14:57:50 +00:00
|
|
|
* @return GLSurfaceView The newly created view
|
2012-02-11 06:08:49 +00:00
|
|
|
*/
|
|
|
|
public GLSurfaceView createView(AndroidInput view, ConfigType configType, boolean eglConfigVerboseLogging) {
|
2011-06-21 22:13:42 +00:00
|
|
|
// Start to set up the view
|
2012-02-11 06:08:49 +00:00
|
|
|
this.view = view;
|
2011-08-25 17:35:30 +00:00
|
|
|
verboseLogging = eglConfigVerboseLogging;
|
2011-06-12 09:26:22 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
if (configType == ConfigType.LEGACY) {
|
2011-07-13 10:32:00 +00:00
|
|
|
// Hardcoded egl setup
|
2012-02-11 06:08:49 +00:00
|
|
|
clientOpenGLESVersion = 2;
|
2011-07-13 10:32:00 +00:00
|
|
|
view.setEGLContextClientVersion(2);
|
|
|
|
//RGB565, Depth16
|
|
|
|
view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
|
|
|
|
logger.info("ConfigType.LEGACY using RGB565");
|
2012-02-11 06:08:49 +00:00
|
|
|
} else {
|
2011-07-13 10:32:00 +00:00
|
|
|
EGL10 egl = (EGL10) EGLContext.getEGL();
|
|
|
|
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-07-13 10:32:00 +00:00
|
|
|
int[] version = new int[2];
|
2012-02-11 06:08:49 +00:00
|
|
|
if (egl.eglInitialize(display, version) == true) {
|
2012-02-25 19:49:15 +00:00
|
|
|
logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});
|
2011-07-13 10:32:00 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
// Create a config chooser
|
2012-02-25 19:49:15 +00:00
|
|
|
AndroidConfigChooser configChooser = new AndroidConfigChooser(configType);
|
2012-02-11 06:08:49 +00:00
|
|
|
// Init chooser
|
|
|
|
if (!configChooser.findConfig(egl, display)) {
|
|
|
|
listener.handleError("Unable to find suitable EGL config", null);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
|
|
|
|
if (clientOpenGLESVersion < 2) {
|
|
|
|
listener.handleError("OpenGL ES 2.0 is not supported on this device", null);
|
|
|
|
return null;
|
|
|
|
}
|
2012-03-02 10:23:22 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
// Requesting client version from GLSurfaceView which is extended by
|
|
|
|
// AndroidInput.
|
|
|
|
view.setEGLContextClientVersion(clientOpenGLESVersion);
|
|
|
|
view.setEGLConfigChooser(configChooser);
|
|
|
|
view.getHolder().setFormat(configChooser.getPixelFormat());
|
|
|
|
} finally {
|
|
|
|
if (display != null) {
|
|
|
|
egl.eglTerminate(display);
|
|
|
|
}
|
2011-07-13 10:32:00 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-03-14 12:55:32 +00:00
|
|
|
view.setFocusableInTouchMode(true);
|
|
|
|
view.setFocusable(true);
|
2012-02-11 06:08:49 +00:00
|
|
|
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
2011-06-12 09:26:22 +00:00
|
|
|
view.setRenderer(this);
|
2011-07-13 10:32:00 +00:00
|
|
|
|
2011-03-14 12:55:32 +00:00
|
|
|
return view;
|
2011-06-12 09:26:22 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-07-12 09:25:36 +00:00
|
|
|
// renderer:initialize
|
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void onSurfaceCreated(GL10 gl, EGLConfig cfg) {
|
|
|
|
|
|
|
|
if (created.get() && renderer != null) {
|
2011-07-12 09:25:36 +00:00
|
|
|
renderer.resetGLObjects();
|
2012-02-11 06:08:49 +00:00
|
|
|
} else {
|
|
|
|
if (!created.get()) {
|
|
|
|
logger.info("GL Surface created, doing JME3 init");
|
2011-07-12 09:25:36 +00:00
|
|
|
initInThread();
|
2012-02-11 06:08:49 +00:00
|
|
|
} else {
|
2011-07-12 09:25:36 +00:00
|
|
|
logger.warning("GL Surface already created");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
protected void initInThread() {
|
|
|
|
created.set(true);
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
logger.info("OGLESContext create");
|
2012-02-11 06:08:49 +00:00
|
|
|
logger.info("Running on thread: " + Thread.currentThread().getName());
|
2011-03-14 12:55:32 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-18 19:12:25 +00:00
|
|
|
// Setup unhandled Exception Handler
|
2012-03-02 10:23:22 +00:00
|
|
|
|
2012-03-07 19:22:41 +00:00
|
|
|
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
2012-03-02 10:23:22 +00:00
|
|
|
|
2012-03-07 19:22:41 +00:00
|
|
|
public void uncaughtException(Thread thread, Throwable thrown) {
|
|
|
|
listener.handleError("Exception thrown in " + thread.toString(), thrown);
|
|
|
|
}
|
|
|
|
});
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
if (clientOpenGLESVersion < 2) {
|
2011-06-12 09:26:22 +00:00
|
|
|
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
|
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
timer = new AndroidTimer();
|
2011-05-15 19:17:34 +00:00
|
|
|
renderer = new OGLESShaderRenderer();
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
renderer.setUseVA(true);
|
2011-08-25 17:35:30 +00:00
|
|
|
renderer.setVerboseLogging(verboseLogging);
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-03-14 12:55:32 +00:00
|
|
|
renderer.initialize();
|
2011-06-17 09:56:55 +00:00
|
|
|
listener.initialize();
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
|
2012-03-02 10:23:22 +00:00
|
|
|
JmeSystem.setSoftTextDialogInput(this);
|
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
needClose.set(false);
|
2011-07-12 09:25:36 +00:00
|
|
|
renderable.set(true);
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* De-initialize in the OpenGL thread.
|
|
|
|
*/
|
2012-02-11 06:08:49 +00:00
|
|
|
protected void deinitInThread() {
|
|
|
|
if (renderable.get()) {
|
2011-07-12 09:25:36 +00:00
|
|
|
created.set(false);
|
2012-02-11 06:08:49 +00:00
|
|
|
if (renderer != null) {
|
2011-06-24 20:11:27 +00:00
|
|
|
renderer.cleanup();
|
2012-02-11 06:08:49 +00:00
|
|
|
}
|
|
|
|
|
2011-06-24 20:11:27 +00:00
|
|
|
listener.destroy();
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-06-24 20:11:27 +00:00
|
|
|
listener = null;
|
2012-02-11 06:08:49 +00:00
|
|
|
renderer = null;
|
|
|
|
timer = null;
|
|
|
|
|
2011-06-24 20:11:27 +00:00
|
|
|
// do android specific cleaning here
|
2011-07-12 09:25:36 +00:00
|
|
|
logger.info("Display destroyed.");
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-07-12 09:25:36 +00:00
|
|
|
renderable.set(false);
|
2012-03-07 19:22:41 +00:00
|
|
|
|
2011-06-24 20:11:27 +00:00
|
|
|
}
|
2011-05-15 19:17:34 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
protected void applySettingsToRenderer(OGLESShaderRenderer renderer, AppSettings settings) {
|
2011-05-15 19:17:34 +00:00
|
|
|
logger.warning("setSettings.USE_VA: [" + settings.getBoolean("USE_VA") + "]");
|
|
|
|
logger.warning("setSettings.VERBOSE_LOGGING: [" + settings.getBoolean("VERBOSE_LOGGING") + "]");
|
|
|
|
renderer.setUseVA(settings.getBoolean("USE_VA"));
|
|
|
|
renderer.setVerboseLogging(settings.getBoolean("VERBOSE_LOGGING"));
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
protected void applySettings(AppSettings settings) {
|
2011-12-03 14:06:48 +00:00
|
|
|
setSettings(settings);
|
2012-02-11 06:08:49 +00:00
|
|
|
if (renderer != null) {
|
|
|
|
applySettingsToRenderer(renderer, this.settings);
|
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void setSettings(AppSettings settings) {
|
2011-05-15 19:17:34 +00:00
|
|
|
this.settings.copyFrom(settings);
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void setSystemListener(SystemListener listener) {
|
2011-03-14 12:55:32 +00:00
|
|
|
this.listener = listener;
|
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2011-03-14 12:55:32 +00:00
|
|
|
public AppSettings getSettings() {
|
|
|
|
return settings;
|
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2011-03-14 12:55:32 +00:00
|
|
|
public com.jme3.renderer.Renderer getRenderer() {
|
|
|
|
return renderer;
|
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2011-03-14 12:55:32 +00:00
|
|
|
public MouseInput getMouseInput() {
|
2011-06-04 20:28:36 +00:00
|
|
|
return new DummyMouseInput();
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2011-03-14 12:55:32 +00:00
|
|
|
public KeyInput getKeyInput() {
|
2011-06-04 20:28:36 +00:00
|
|
|
return new DummyKeyInput();
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2011-03-14 12:55:32 +00:00
|
|
|
public JoyInput getJoyInput() {
|
|
|
|
return null;
|
|
|
|
}
|
2011-06-04 20:28:36 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public TouchInput getTouchInput() {
|
|
|
|
return view;
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public Timer getTimer() {
|
2011-03-14 12:55:32 +00:00
|
|
|
return timer;
|
|
|
|
}
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void setTitle(String title) {
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public boolean isCreated() {
|
2011-03-14 12:55:32 +00:00
|
|
|
return created.get();
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void setAutoFlushFrames(boolean enabled) {
|
2011-03-14 12:55:32 +00:00
|
|
|
this.autoFlush = enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SystemListener:reshape
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
2011-07-21 09:19:50 +00:00
|
|
|
logger.info("GL Surface changed, width: " + width + " height: " + height);
|
2011-03-14 12:55:32 +00:00
|
|
|
settings.setResolution(width, height);
|
|
|
|
listener.reshape(width, height);
|
2012-03-07 19:22:41 +00:00
|
|
|
// androidListener.reshape(width, height);
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SystemListener:update
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void onDrawFrame(GL10 gl) {
|
|
|
|
if (needClose.get()) {
|
2011-05-15 19:17:34 +00:00
|
|
|
deinitInThread();
|
2011-03-14 12:55:32 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-05-29 20:55:28 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
if (renderable.get()) {
|
|
|
|
if (!created.get()) {
|
2011-05-29 20:55:28 +00:00
|
|
|
throw new IllegalStateException("onDrawFrame without create");
|
2012-02-11 06:08:49 +00:00
|
|
|
}
|
2011-05-29 20:55:28 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
long milliStart = System.currentTimeMillis();
|
2011-03-14 12:55:32 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
listener.update();
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (autoFlush) {
|
2011-05-15 19:17:34 +00:00
|
|
|
renderer.onFrame();
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
long milliDelta = System.currentTimeMillis() - milliStart;
|
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
// Enforce a FPS cap
|
2012-02-11 06:08:49 +00:00
|
|
|
if (milliDelta < minFrameDuration) {
|
2011-05-15 19:17:34 +00:00
|
|
|
//logger.log(Level.INFO, "Time per frame {0}", milliDelta);
|
|
|
|
try {
|
|
|
|
Thread.sleep(minFrameDuration - milliDelta);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
}
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public boolean isRenderable() {
|
2011-05-15 19:17:34 +00:00
|
|
|
return renderable.get();
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void create(boolean waitFor) {
|
|
|
|
if (waitFor) {
|
2011-05-15 19:17:34 +00:00
|
|
|
waitFor(true);
|
2012-02-11 06:08:49 +00:00
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
public void create() {
|
2011-05-15 19:17:34 +00:00
|
|
|
create(false);
|
2011-05-02 23:41:10 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void restart() {
|
2011-05-15 19:17:34 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
2011-05-15 19:17:34 +00:00
|
|
|
@Override
|
2012-02-11 06:08:49 +00:00
|
|
|
public void destroy(boolean waitFor) {
|
2011-03-14 12:55:32 +00:00
|
|
|
needClose.set(true);
|
2012-02-11 06:08:49 +00:00
|
|
|
if (waitFor) {
|
2011-05-15 19:17:34 +00:00
|
|
|
waitFor(false);
|
2012-02-11 06:08:49 +00:00
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
public void destroy() {
|
2011-05-29 20:55:28 +00:00
|
|
|
destroy(true);
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|
2012-02-11 06:08:49 +00:00
|
|
|
|
|
|
|
protected void waitFor(boolean createdVal) {
|
|
|
|
while (renderable.get() != createdVal) {
|
2011-06-24 20:11:27 +00:00
|
|
|
try {
|
|
|
|
Thread.sleep(10);
|
|
|
|
} catch (InterruptedException ex) {
|
2011-05-15 19:17:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
|
2012-02-11 06:08:49 +00:00
|
|
|
public int getClientOpenGLESVersion() {
|
2011-06-12 09:26:22 +00:00
|
|
|
return clientOpenGLESVersion;
|
|
|
|
}
|
2012-03-02 10:23:22 +00:00
|
|
|
|
|
|
|
public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
|
|
|
|
logger.log(Level.INFO, "requestDialog: title: {0}, initialValue: {1}",
|
|
|
|
new Object[]{title, initialValue});
|
|
|
|
|
|
|
|
JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
final FrameLayout layoutTextDialogInput = new FrameLayout(JmeAndroidSystem.getActivity());
|
|
|
|
final EditText editTextDialogInput = new EditText(JmeAndroidSystem.getActivity());
|
|
|
|
editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
|
|
|
|
editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
|
|
|
|
editTextDialogInput.setPadding(20, 20, 20, 20);
|
|
|
|
editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);
|
|
|
|
|
|
|
|
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(JmeAndroidSystem.getActivity()).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();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2011-03-14 12:55:32 +00:00
|
|
|
}
|