159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2003-2009 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.system.android;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.app.Activity;
35a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.app.AlertDialog;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.content.Context;
37a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.content.DialogInterface;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.opengl.GLSurfaceView;
39a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.text.InputType;
40a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.view.Gravity;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.view.SurfaceHolder;
42a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.view.ViewGroup.LayoutParams;
43a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.widget.EditText;
44a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport android.widget.FrameLayout;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.app.AndroidHarness;
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.app.Application;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.JoyInput;
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.KeyInput;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.MouseInput;
50a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport com.jme3.input.SoftTextDialogInput;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.TouchInput;
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.android.AndroidInput;
53a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport com.jme3.input.controls.SoftTextDialogInputListener;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.controls.TouchTrigger;
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.dummy.DummyKeyInput;
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.dummy.DummyMouseInput;
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.android.OGLESShaderRenderer;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.AppSettings;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.JmeContext;
60a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport com.jme3.system.JmeSystem;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.SystemListener;
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.Timer;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.system.android.AndroidConfigChooser.ConfigType;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.concurrent.atomic.AtomicBoolean;
65a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartaimport java.util.logging.Level;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport javax.microedition.khronos.egl.EGL10;
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport javax.microedition.khronos.egl.EGLConfig;
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport javax.microedition.khronos.egl.EGLContext;
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport javax.microedition.khronos.egl.EGLDisplay;
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport javax.microedition.khronos.opengles.GL10;
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
73a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Bartapublic class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected final AtomicBoolean created = new AtomicBoolean(false);
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected final AtomicBoolean renderable = new AtomicBoolean(false);
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected final AtomicBoolean needClose = new AtomicBoolean(false);
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected final AppSettings settings = new AppSettings(true);
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * >= OpenGL ES 2.0 (Android 2.2+)
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected OGLESShaderRenderer renderer;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Timer timer;
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected SystemListener listener;
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean autoFlush = true;
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AndroidInput view;
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean firstDrawFrame = true;
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //protected int minFrameDuration = 1000 / frameRate;  // Set a max FPS of 33
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int minFrameDuration = 0;                   // No FPS cap
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 |
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int clientOpenGLESVersion = 1;
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean verboseLogging = false;
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    final private String ESCAPE_EVENT = "TouchEscape";
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public OGLESContext() {
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Type getType() {
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return Type.Display;
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>createView</code>
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param activity The Android activity which is parent for the
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * GLSurfaceView
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return GLSurfaceView The newly created view
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public GLSurfaceView createView(Activity activity) {
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createView(new AndroidInput(activity));
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>createView</code>
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param view The Android input which will be used as the GLSurfaceView for
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * this context
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return GLSurfaceView The newly created view
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public GLSurfaceView createView(AndroidInput view) {
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createView(view, ConfigType.FASTEST, false);
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>createView</code> initializes the GLSurfaceView
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param view The Android input which will be used as the GLSurfaceView for
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * this context
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY |
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * ConfigType.BEST
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param eglConfigVerboseLogging if true show all found configs
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return GLSurfaceView The newly created view
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public GLSurfaceView createView(AndroidInput view, ConfigType configType, boolean eglConfigVerboseLogging) {
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Start to set up the view
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.view = view;
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        verboseLogging = eglConfigVerboseLogging;
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (configType == ConfigType.LEGACY) {
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Hardcoded egl setup
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clientOpenGLESVersion = 2;
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            view.setEGLContextClientVersion(2);
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //RGB565, Depth16
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("ConfigType.LEGACY using RGB565");
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            EGL10 egl = (EGL10) EGLContext.getEGL();
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int[] version = new int[2];
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (egl.eglInitialize(display, version) == true) {
158a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            try {
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Create a config chooser
163a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                AndroidConfigChooser configChooser = new AndroidConfigChooser(configType);
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Init chooser
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (!configChooser.findConfig(egl, display)) {
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    listener.handleError("Unable to find suitable EGL config", null);
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return null;
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (clientOpenGLESVersion < 2) {
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    listener.handleError("OpenGL ES 2.0 is not supported on this device", null);
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return null;
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
175a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Requesting client version from GLSurfaceView which is extended by
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // AndroidInput.
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                view.setEGLContextClientVersion(clientOpenGLESVersion);
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                view.setEGLConfigChooser(configChooser);
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                view.getHolder().setFormat(configChooser.getPixelFormat());
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } finally {
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (display != null) {
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    egl.eglTerminate(display);
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        view.setFocusableInTouchMode(true);
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        view.setFocusable(true);
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        view.setRenderer(this);
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return view;
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // renderer:initialize
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void onSurfaceCreated(GL10 gl, EGLConfig cfg) {
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (created.get() && renderer != null) {
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            renderer.resetGLObjects();
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!created.get()) {
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GL Surface created, doing JME3 init");
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                initInThread();
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.warning("GL Surface already created");
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void initInThread() {
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        created.set(true);
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.info("OGLESContext create");
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.info("Running on thread: " + Thread.currentThread().getName());
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final Context ctx = this.view.getContext();
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Setup unhandled Exception Handler
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctx instanceof AndroidHarness) {
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
223a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                public void uncaughtException(Thread thread, Throwable thrown) {
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    ((AndroidHarness) ctx).handleError("Exception thrown in " + thread.toString(), thrown);
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            });
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
230a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                public void uncaughtException(Thread thread, Throwable thrown) {
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    listener.handleError("Exception thrown in " + thread.toString(), thrown);
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            });
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (clientOpenGLESVersion < 2) {
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        timer = new AndroidTimer();
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer = new OGLESShaderRenderer();
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer.setUseVA(true);
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer.setVerboseLogging(verboseLogging);
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer.initialize();
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        listener.initialize();
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Setup exit hook
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctx instanceof AndroidHarness) {
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Application app = ((AndroidHarness) ctx).getJmeApplication();
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (app.getInputManager() != null) {
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                app.getInputManager().addMapping(ESCAPE_EVENT, new TouchTrigger(TouchInput.KEYCODE_BACK));
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                app.getInputManager().addListener((AndroidHarness) ctx, new String[]{ESCAPE_EVENT});
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
259a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        JmeSystem.setSoftTextDialogInput(this);
260a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        needClose.set(false);
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderable.set(true);
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * De-initialize in the OpenGL thread.
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void deinitInThread() {
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (renderable.get()) {
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            created.set(false);
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (renderer != null) {
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                renderer.cleanup();
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            listener.destroy();
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            listener = null;
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            renderer = null;
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            timer = null;
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // do android specific cleaning here
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("Display destroyed.");
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            renderable.set(false);
285a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            final Context ctx = this.view.getContext();
286a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            if (ctx instanceof AndroidHarness) {
287a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                AndroidHarness harness = (AndroidHarness) ctx;
288a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                if (harness.isFinishOnAppStop()) {
289a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    harness.finish();
290a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                }
291a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            }
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void applySettingsToRenderer(OGLESShaderRenderer renderer, AppSettings settings) {
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("setSettings.USE_VA: [" + settings.getBoolean("USE_VA") + "]");
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("setSettings.VERBOSE_LOGGING: [" + settings.getBoolean("VERBOSE_LOGGING") + "]");
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer.setUseVA(settings.getBoolean("USE_VA"));
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        renderer.setVerboseLogging(settings.getBoolean("VERBOSE_LOGGING"));
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void applySettings(AppSettings settings) {
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setSettings(settings);
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (renderer != null) {
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            applySettingsToRenderer(renderer, this.settings);
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setSettings(AppSettings settings) {
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.settings.copyFrom(settings);
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setSystemListener(SystemListener listener) {
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.listener = listener;
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AppSettings getSettings() {
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return settings;
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public com.jme3.renderer.Renderer getRenderer() {
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return renderer;
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public MouseInput getMouseInput() {
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return new DummyMouseInput();
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public KeyInput getKeyInput() {
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return new DummyKeyInput();
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public JoyInput getJoyInput() {
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return null;
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public TouchInput getTouchInput() {
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return view;
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Timer getTimer() {
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return timer;
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setTitle(String title) {
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isCreated() {
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return created.get();
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAutoFlushFrames(boolean enabled) {
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.autoFlush = enabled;
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // SystemListener:reshape
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void onSurfaceChanged(GL10 gl, int width, int height) {
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.info("GL Surface changed, width: " + width + " height: " + height);
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        settings.setResolution(width, height);
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        listener.reshape(width, height);
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // SystemListener:update
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void onDrawFrame(GL10 gl) {
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (needClose.get()) {
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            deinitInThread();
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (renderable.get()) {
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!created.get()) {
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalStateException("onDrawFrame without create");
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            long milliStart = System.currentTimeMillis();
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            listener.update();
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // call to AndroidHarness to remove the splash screen, if present.
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // call after listener.update() to make sure no gap between
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //   splash screen going away and app display being shown.
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (firstDrawFrame) {
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                final Context ctx = this.view.getContext();
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (ctx instanceof AndroidHarness) {
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    ((AndroidHarness) ctx).removeSplashScreen();
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                firstDrawFrame = false;
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (autoFlush) {
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                renderer.onFrame();
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            long milliDelta = System.currentTimeMillis() - milliStart;
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Enforce a FPS cap
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (milliDelta < minFrameDuration) {
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                //logger.log(Level.INFO, "Time per frame {0}", milliDelta);
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                try {
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    Thread.sleep(minFrameDuration - milliDelta);
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } catch (InterruptedException e) {
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isRenderable() {
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return renderable.get();
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void create(boolean waitFor) {
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (waitFor) {
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            waitFor(true);
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void create() {
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        create(false);
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void restart() {
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void destroy(boolean waitFor) {
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        needClose.set(true);
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (waitFor) {
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            waitFor(false);
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void destroy() {
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        destroy(true);
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void waitFor(boolean createdVal) {
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while (renderable.get() != createdVal) {
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            try {
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Thread.sleep(10);
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } catch (InterruptedException ex) {
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int getClientOpenGLESVersion() {
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return clientOpenGLESVersion;
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
466a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
467a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
468a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        logger.log(Level.INFO, "requestDialog: title: {0}, initialValue: {1}",
469a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                new Object[]{title, initialValue});
470a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
471a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() {
472a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
473a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            @Override
474a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            public void run() {
475a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
476a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                final FrameLayout layoutTextDialogInput = new FrameLayout(JmeAndroidSystem.getActivity());
477a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                final EditText editTextDialogInput = new EditText(JmeAndroidSystem.getActivity());
478a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
479a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
480a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                editTextDialogInput.setPadding(20, 20, 20, 20);
481a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);
482a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
483a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                editTextDialogInput.setText(initialValue);
484a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
485a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                switch (id) {
486a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    case SoftTextDialogInput.TEXT_ENTRY_DIALOG:
487a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
488a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);
489a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        break;
490a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
491a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:
492a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
493a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
494a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        break;
495a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
496a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:
497a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
498a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);
499a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        break;
500a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
501a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                    default:
502a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        break;
503a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                }
504a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
505a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                layoutTextDialogInput.addView(editTextDialogInput);
506a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
507a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                AlertDialog dialogTextInput = new AlertDialog.Builder(JmeAndroidSystem.getActivity()).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK",
508a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        new DialogInterface.OnClickListener() {
509a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
510a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                            public void onClick(DialogInterface dialog, int whichButton) {
511a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                                /* User clicked OK, send COMPLETE action
512a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                                 * and text */
513a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                                listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());
514a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                            }
515a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        }).setNegativeButton("Cancel",
516a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        new DialogInterface.OnClickListener() {
517a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
518a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                            public void onClick(DialogInterface dialog, int whichButton) {
519a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                                /* User clicked CANCEL, send CANCEL action
520a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                                 * and text */
521a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                                listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());
522a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                            }
523a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                        }).create();
524a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta
525a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                dialogTextInput.show();
526a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            }
527a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        });
528a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta    }
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
530