Advertisement
Guest User

OGLESContext.java

a guest
Jul 20th, 2013
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.86 KB | None | 0 0
  1. /*
  2.  * Copyright (c) 2009-2012 jMonkeyEngine
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are
  7.  * met:
  8.  *
  9.  * * Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  *
  12.  * * Redistributions in binary form must reproduce the above copyright
  13.  *   notice, this list of conditions and the following disclaimer in the
  14.  *   documentation and/or other materials provided with the distribution.
  15.  *
  16.  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  17.  *   may be used to endorse or promote products derived from this software
  18.  *   without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22.  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23.  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  */
  32. package com.jme3.system.android;
  33.  
  34. import android.app.Activity;
  35. import com.jme3.renderer.android.AndroidGLSurfaceView;
  36. import android.app.AlertDialog;
  37. import android.content.DialogInterface;
  38. import android.opengl.GLSurfaceView;
  39. import android.text.InputType;
  40. import android.view.Gravity;
  41. import android.view.SurfaceHolder;
  42. import android.view.View;
  43. import android.view.ViewGroup.LayoutParams;
  44. import android.widget.EditText;
  45. import android.widget.FrameLayout;
  46. import com.jme3.input.*;
  47. import com.jme3.input.android.AndroidInput;
  48. import com.jme3.input.android.AndroidSensorJoyInput;
  49. import com.jme3.input.android.GamepadJoyInput;
  50. import com.jme3.input.controls.SoftTextDialogInputListener;
  51. import com.jme3.input.dummy.DummyKeyInput;
  52. import com.jme3.input.dummy.DummyMouseInput;
  53. import com.jme3.renderer.android.OGLESShaderRenderer;
  54. import com.jme3.system.*;
  55. import com.jme3.system.android.AndroidConfigChooser.ConfigType;
  56. import java.util.concurrent.atomic.AtomicBoolean;
  57. import java.util.logging.Level;
  58. import java.util.logging.Logger;
  59. import javax.microedition.khronos.egl.EGL10;
  60. import javax.microedition.khronos.egl.EGLConfig;
  61. import javax.microedition.khronos.egl.EGLContext;
  62. import javax.microedition.khronos.egl.EGLDisplay;
  63. import javax.microedition.khronos.opengles.GL10;
  64.  
  65. public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
  66.  
  67.     private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());
  68.     protected final AtomicBoolean created = new AtomicBoolean(false);
  69.     protected final AtomicBoolean renderable = new AtomicBoolean(false);
  70.     protected final AtomicBoolean needClose = new AtomicBoolean(false);
  71.     protected AppSettings settings = new AppSettings(true);
  72.  
  73.     /*
  74.      * >= OpenGL ES 2.0 (Android 2.2+)
  75.      */
  76.     protected OGLESShaderRenderer renderer;
  77.     protected Timer timer;
  78.     protected SystemListener listener;
  79.     protected boolean autoFlush = true;
  80.     protected AndroidInput androidInput;
  81.     protected int minFrameDuration = 0;                   // No FPS cap
  82.     protected GamepadJoyInput joyInput = null;
  83.     protected View mView = null;
  84.     /**
  85.      * EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 |
  86.      * EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
  87.      */
  88.     protected int clientOpenGLESVersion = 1;
  89.  
  90.     public OGLESContext() {
  91.     }
  92.  
  93.     @Override
  94.     public Type getType() {
  95.         return Type.Display;
  96.     }
  97.    
  98.     /**
  99.      * <code>createView</code> creates the GLSurfaceView that the renderer will
  100.      * draw to. <p> The result GLSurfaceView will receive input events and
  101.      * forward them to the Application. Any rendering will be done into the
  102.      * GLSurfaceView. Only one GLSurfaceView can be created at this time. The
  103.      * given configType specifies how to determine the display configuration.
  104.      *
  105.      *
  106.      * @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY |
  107.      * ConfigType.BEST
  108.      * @param eglConfigVerboseLogging if true show all found configs
  109.      * @return GLSurfaceView The newly created view
  110.      * @deprecated AndroidGLSurfaceView createView()
  111.      * and put the configType in the appSettigs with the key AndroidConfigChoose.SETTINGS_CONFIG_TYPE
  112.      */
  113.     @Deprecated
  114.     public AndroidGLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
  115.         settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, configType);
  116.         return this.createView();        
  117.     }
  118.     /**
  119.      * <code>createView</code> creates the GLSurfaceView that the renderer will
  120.      * draw to. <p> The result GLSurfaceView will receive input events and
  121.      * forward them to the Application. Any rendering will be done into the
  122.      * GLSurfaceView. Only one GLSurfaceView can be created at this time. The
  123.      * given configType specifies how to determine the display configuration.    
  124.      *
  125.      *
  126.      * @param eglConfigVerboseLogging if true show all found configs
  127.      * @return GLSurfaceView The newly created view
  128.      */
  129.     public AndroidGLSurfaceView createView() {
  130.         AndroidGLSurfaceView view;  
  131.         ConfigType configType = (ConfigType)settings.get(AndroidConfigChooser.SETTINGS_CONFIG_TYPE);
  132.  
  133.         // Start to set up the view
  134.         view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity().getApplication());
  135.         mView = view;
  136.  
  137.         if (androidInput == null) {
  138.             androidInput = new AndroidInput();
  139.         }
  140.         androidInput.setView(view);
  141.         androidInput.loadSettings(settings);
  142.  
  143.         if (configType == ConfigType.LEGACY) {
  144.             // Hardcoded egl setup
  145.             clientOpenGLESVersion = 2;
  146.             view.setEGLContextClientVersion(2);
  147.             // RGB565, Depth16
  148.             view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
  149.             logger.fine("ConfigType.LEGACY using RGB565");
  150.         } else {
  151.             EGL10 egl = (EGL10) EGLContext.getEGL();
  152.             EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
  153.  
  154.             int[] version = new int[2];
  155.             if (egl.eglInitialize(display, version) == true) {
  156.                 logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});
  157.             }
  158.  
  159.             try {
  160.                 // Create a config chooser
  161.                 AndroidConfigChooser configChooser = new AndroidConfigChooser(settings);
  162.                 // Init chooser
  163.                 if (!configChooser.findConfig(egl, display)) {
  164.                     listener.handleError("Unable to find suitable EGL config", null);
  165.                     return null;
  166.                 }
  167.  
  168.                 clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
  169.                 if (clientOpenGLESVersion < 2) {
  170.                     listener.handleError("OpenGL ES 2.0 is not supported on this device", null);
  171.                     return null;
  172.                 }
  173.  
  174.                 // Requesting client version from GLSurfaceView which is extended by
  175.                 // AndroidInput.
  176.                 view.setEGLContextClientVersion(clientOpenGLESVersion);
  177.                 view.setEGLConfigChooser(configChooser);
  178.                 view.getHolder().setFormat(configChooser.getPixelFormat());
  179.             } finally {
  180.                 if (display != null) {
  181.                     egl.eglTerminate(display);
  182.                 }
  183.             }
  184.         }
  185.  
  186.         view.setFocusableInTouchMode(true);
  187.         view.setFocusable(true);
  188.         view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
  189.         if (configType == ConfigType.BEST_TRANSLUCENT) {
  190.             //This is important to allow the GL surface to have a translucent background
  191.             view.setZOrderOnTop(true);
  192.         }
  193.         view.setRenderer(this);
  194.  
  195.         return view;
  196.     }
  197.  
  198.     // renderer:initialize
  199.     @Override
  200.     public void onSurfaceCreated(GL10 gl, EGLConfig cfg) {
  201.         if (created.get() && renderer != null) {
  202.             renderer.resetGLObjects();
  203.         } else {
  204.             if (!created.get()) {
  205.                 logger.fine("GL Surface created, doing JME3 init");
  206.                 initInThread();
  207.             } else {
  208.                 logger.warning("GL Surface already created");
  209.             }
  210.         }
  211.     }
  212.  
  213.     protected void initInThread() {
  214.         created.set(true);
  215.  
  216.         logger.fine("OGLESContext create");
  217.         logger.log(Level.FINE, "Running on thread: {0}", Thread.currentThread().getName());
  218.  
  219.         // Setup unhandled Exception Handler
  220.         Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
  221.             public void uncaughtException(Thread thread, Throwable thrown) {
  222.                 listener.handleError("Exception thrown in " + thread.toString(), thrown);
  223.             }
  224.         });
  225.  
  226.         if (clientOpenGLESVersion < 2) {
  227.             throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
  228.         }
  229.  
  230.         timer = new AndroidTimer();
  231.         renderer = new OGLESShaderRenderer();
  232.  
  233.         renderer.initialize();
  234.         listener.initialize();
  235.  
  236.         JmeSystem.setSoftTextDialogInput(this);
  237.  
  238.         needClose.set(false);
  239.         renderable.set(true);
  240.     }
  241.  
  242.     /**
  243.      * De-initialize in the OpenGL thread.
  244.      */
  245.     protected void deinitInThread() {
  246.         if (renderable.get()) {
  247.             created.set(false);
  248.             if (renderer != null) {
  249.                 renderer.cleanup();
  250.             }
  251.  
  252.             listener.destroy();
  253.  
  254.             listener = null;
  255.             renderer = null;
  256.             timer = null;
  257.  
  258.             // do android specific cleaning here
  259.             logger.fine("Display destroyed.");
  260.  
  261.             renderable.set(false);
  262.         }
  263.     }
  264.  
  265.     @Override
  266.     public void setSettings(AppSettings settings) {
  267.         this.settings.copyFrom(settings);
  268.         if (androidInput != null) {
  269.             androidInput.loadSettings(settings);
  270.         }
  271.  
  272.     }
  273.  
  274.     @Override
  275.     public void setSystemListener(SystemListener listener) {
  276.         this.listener = listener;
  277.     }
  278.  
  279.     @Override
  280.     public AppSettings getSettings() {
  281.         return settings;
  282.     }
  283.  
  284.     @Override
  285.     public com.jme3.renderer.Renderer getRenderer() {
  286.         return renderer;
  287.     }
  288.  
  289.     @Override
  290.     public MouseInput getMouseInput() {
  291.         return new DummyMouseInput();
  292.     }
  293.  
  294.     @Override
  295.     public KeyInput getKeyInput() {
  296.         return new DummyKeyInput();
  297.     }
  298.  
  299.     @Override
  300.     public JoyInput getJoyInput()
  301.     {
  302.         /**
  303.         if (androidSensorJoyInput == null) {
  304.             androidSensorJoyInput = new AndroidSensorJoyInput();
  305.         }
  306.         */
  307.        
  308.         if (joyInput == null)
  309.         {
  310.             joyInput = new GamepadJoyInput();
  311.         }
  312.        
  313.         joyInput.setView(mView);
  314.        
  315.         return joyInput;
  316.     }
  317.  
  318.     @Override
  319.     public TouchInput getTouchInput() {
  320.         return androidInput;
  321.     }
  322.  
  323.     @Override
  324.     public Timer getTimer() {
  325.         return timer;
  326.     }
  327.  
  328.     @Override
  329.     public void setTitle(String title) {
  330.     }
  331.  
  332.     @Override
  333.     public boolean isCreated() {
  334.         return created.get();
  335.     }
  336.  
  337.     @Override
  338.     public void setAutoFlushFrames(boolean enabled) {
  339.         this.autoFlush = enabled;
  340.     }
  341.  
  342.     // SystemListener:reshape
  343.     @Override
  344.     public void onSurfaceChanged(GL10 gl, int width, int height) {
  345.         logger.log(Level.FINE, "GL Surface changed, width: {0} height: {1}", new Object[]{width, height});
  346.         settings.setResolution(width, height);
  347.         listener.reshape(width, height);
  348.     }
  349.  
  350.     // SystemListener:update
  351.     @Override
  352.     public void onDrawFrame(GL10 gl) {
  353.         if (needClose.get()) {
  354.             deinitInThread();
  355.             return;
  356.         }
  357.  
  358.         if (renderable.get()) {
  359.             if (!created.get()) {
  360.                 throw new IllegalStateException("onDrawFrame without create");
  361.             }
  362.  
  363.             long milliStart = System.currentTimeMillis();
  364.  
  365.             listener.update();
  366.             if (autoFlush) {
  367.                 renderer.onFrame();
  368.             }
  369.  
  370.             long milliDelta = System.currentTimeMillis() - milliStart;
  371.  
  372.             // Enforce a FPS cap
  373.             if (milliDelta < minFrameDuration) {
  374.                 //logger.log(Level.FINE, "Time per frame {0}", milliDelta);
  375.                 try {
  376.                     Thread.sleep(minFrameDuration - milliDelta);
  377.                 } catch (InterruptedException e) {
  378.                 }
  379.             }
  380.         }
  381.     }
  382.  
  383.     @Override
  384.     public boolean isRenderable() {
  385.         return renderable.get();
  386.     }
  387.  
  388.     @Override
  389.     public void create(boolean waitFor) {
  390.         if (waitFor) {
  391.             waitFor(true);
  392.         }
  393.     }
  394.  
  395.     public void create() {
  396.         create(false);
  397.     }
  398.  
  399.     @Override
  400.     public void restart() {
  401.     }
  402.  
  403.     @Override
  404.     public void destroy(boolean waitFor) {
  405.         needClose.set(true);
  406.         if (waitFor) {
  407.             waitFor(false);
  408.         }
  409.     }
  410.  
  411.     public void destroy() {
  412.         destroy(true);
  413.     }
  414.  
  415.     protected void waitFor(boolean createdVal) {
  416.         while (renderable.get() != createdVal) {
  417.             try {
  418.                 Thread.sleep(10);
  419.             } catch (InterruptedException ex) {
  420.             }
  421.         }
  422.     }
  423.  
  424.     public int getClientOpenGLESVersion() {
  425.         return clientOpenGLESVersion;
  426.     }
  427.  
  428.     public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
  429.         logger.log(Level.FINE, "requestDialog: title: {0}, initialValue: {1}",
  430.                 new Object[]{title, initialValue});
  431.  
  432.         final Activity activity = JmeAndroidSystem.getActivity();
  433.         activity.runOnUiThread(new Runnable() {
  434.             @Override
  435.             public void run() {
  436.  
  437.                 final FrameLayout layoutTextDialogInput = new FrameLayout(activity);
  438.                 final EditText editTextDialogInput = new EditText(activity);
  439.                 editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
  440.                 editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
  441.                 editTextDialogInput.setPadding(20, 20, 20, 20);
  442.                 editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);
  443.  
  444.                 editTextDialogInput.setText(initialValue);
  445.  
  446.                 switch (id) {
  447.                     case SoftTextDialogInput.TEXT_ENTRY_DIALOG:
  448.  
  449.                         editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);
  450.                         break;
  451.  
  452.                     case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:
  453.  
  454.                         editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
  455.                         break;
  456.  
  457.                     case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:
  458.  
  459.                         editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);
  460.                         break;
  461.  
  462.                     default:
  463.                         break;
  464.                 }
  465.  
  466.                 layoutTextDialogInput.addView(editTextDialogInput);
  467.  
  468.                 AlertDialog dialogTextInput = new AlertDialog.Builder(activity).setTitle(title).setView(layoutTextDialogInput).setPositiveButton("OK",
  469.                         new DialogInterface.OnClickListener() {
  470.                             public void onClick(DialogInterface dialog, int whichButton) {
  471.                                 /* User clicked OK, send COMPLETE action
  472.                                  * and text */
  473.                                 listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());
  474.                             }
  475.                         }).setNegativeButton("Cancel",
  476.                         new DialogInterface.OnClickListener() {
  477.                             public void onClick(DialogInterface dialog, int whichButton) {
  478.                                 /* User clicked CANCEL, send CANCEL action
  479.                                  * and text */
  480.                                 listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());
  481.                             }
  482.                         }).create();
  483.  
  484.                 dialogTextInput.show();
  485.             }
  486.         });
  487.     }
  488. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement