GodotView.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /*************************************************************************/
  2. /* GodotView.java */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. package org.godotengine.godot;
  30. import android.content.Context;
  31. import android.graphics.PixelFormat;
  32. import android.opengl.GLSurfaceView;
  33. import android.util.AttributeSet;
  34. import android.util.Log;
  35. import android.view.KeyEvent;
  36. import android.view.MotionEvent;
  37. import android.content.ContextWrapper;
  38. import android.view.InputDevice;
  39. import java.io.File;
  40. import javax.microedition.khronos.egl.EGL10;
  41. import javax.microedition.khronos.egl.EGLConfig;
  42. import javax.microedition.khronos.egl.EGLContext;
  43. import javax.microedition.khronos.egl.EGLDisplay;
  44. import javax.microedition.khronos.opengles.GL10;
  45. /**
  46. * A simple GLSurfaceView sub-class that demonstrate how to perform
  47. * OpenGL ES 2.0 rendering into a GL Surface. Note the following important
  48. * details:
  49. *
  50. * - The class must use a custom context factory to enable 2.0 rendering.
  51. * See ContextFactory class definition below.
  52. *
  53. * - The class must use a custom EGLConfigChooser to be able to select
  54. * an EGLConfig that supports 2.0. This is done by providing a config
  55. * specification to eglChooseConfig() that has the attribute
  56. * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
  57. * set. See ConfigChooser class definition below.
  58. *
  59. * - The class must select the surface's format, then choose an EGLConfig
  60. * that matches it exactly (with regards to red/green/blue/alpha channels
  61. * bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
  62. */
  63. public class GodotView extends GLSurfaceView {
  64. private static String TAG = "GodotView";
  65. private static final boolean DEBUG = false;
  66. private static Context ctx;
  67. private static GodotIO io;
  68. private static boolean firsttime=true;
  69. private static boolean use_gl2=false;
  70. private static boolean use_32=false;
  71. private Godot activity;
  72. public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, boolean p_use_32_bits, Godot p_activity) {
  73. super(context);
  74. ctx=context;
  75. io=p_io;
  76. use_gl2=p_use_gl2;
  77. use_32=p_use_32_bits;
  78. activity = p_activity;
  79. if (!p_io.needsReloadHooks()) {
  80. //will only work on SDK 11+!!
  81. setPreserveEGLContextOnPause(true);
  82. }
  83. init(false, 16, 0);
  84. }
  85. public GodotView(Context context, boolean translucent, int depth, int stencil) {
  86. super(context);
  87. init(translucent, depth, stencil);
  88. }
  89. @Override public boolean onTouchEvent (MotionEvent event) {
  90. return activity.gotTouchEvent(event);
  91. };
  92. public int get_godot_button(int keyCode) {
  93. int button = 0;
  94. switch (keyCode) {
  95. case KeyEvent.KEYCODE_BUTTON_A: // Android A is SNES B
  96. button = 0;
  97. break;
  98. case KeyEvent.KEYCODE_BUTTON_B:
  99. button = 1;
  100. break;
  101. case KeyEvent.KEYCODE_BUTTON_X: // Android X is SNES Y
  102. button = 2;
  103. break;
  104. case KeyEvent.KEYCODE_BUTTON_Y:
  105. button = 3;
  106. break;
  107. case KeyEvent.KEYCODE_BUTTON_L1:
  108. button = 4;
  109. break;
  110. case KeyEvent.KEYCODE_BUTTON_L2:
  111. button = 6;
  112. break;
  113. case KeyEvent.KEYCODE_BUTTON_R1:
  114. button = 5;
  115. break;
  116. case KeyEvent.KEYCODE_BUTTON_R2:
  117. button = 7;
  118. break;
  119. case KeyEvent.KEYCODE_BUTTON_SELECT:
  120. button = 10;
  121. break;
  122. case KeyEvent.KEYCODE_BUTTON_START:
  123. button = 11;
  124. break;
  125. case KeyEvent.KEYCODE_BUTTON_THUMBL:
  126. button = 8;
  127. break;
  128. case KeyEvent.KEYCODE_BUTTON_THUMBR:
  129. button = 9;
  130. break;
  131. case KeyEvent.KEYCODE_DPAD_UP:
  132. button = 12;
  133. break;
  134. case KeyEvent.KEYCODE_DPAD_DOWN:
  135. button = 13;
  136. break;
  137. case KeyEvent.KEYCODE_DPAD_LEFT:
  138. button = 14;
  139. break;
  140. case KeyEvent.KEYCODE_DPAD_RIGHT:
  141. button = 15;
  142. break;
  143. default:
  144. button = keyCode - KeyEvent.KEYCODE_BUTTON_1;
  145. break;
  146. };
  147. return button;
  148. };
  149. @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
  150. if (keyCode == KeyEvent.KEYCODE_BACK) {
  151. return true;
  152. }
  153. if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
  154. return super.onKeyUp(keyCode, event);
  155. };
  156. int source = event.getSource();
  157. if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) {
  158. int button = get_godot_button(keyCode);
  159. int device = event.getDeviceId();
  160. GodotLib.joybutton(device, button, false);
  161. return true;
  162. } else {
  163. GodotLib.key(keyCode, event.getUnicodeChar(0), false);
  164. };
  165. return super.onKeyUp(keyCode, event);
  166. };
  167. @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
  168. if (keyCode == KeyEvent.KEYCODE_BACK) {
  169. GodotLib.quit();
  170. // press 'back' button should not terminate program
  171. // normal handle 'back' event in game logic
  172. return true;
  173. }
  174. if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
  175. return super.onKeyDown(keyCode, event);
  176. };
  177. int source = event.getSource();
  178. //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD)));
  179. if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) {
  180. if (event.getRepeatCount() > 0) // ignore key echo
  181. return true;
  182. int button = get_godot_button(keyCode);
  183. int device = event.getDeviceId();
  184. //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device));
  185. GodotLib.joybutton(device, button, true);
  186. return true;
  187. } else {
  188. GodotLib.key(keyCode, event.getUnicodeChar(0), true);
  189. };
  190. return super.onKeyDown(keyCode, event);
  191. }
  192. public float axis_value(MotionEvent p_event, InputDevice p_device, int p_axis, int p_pos) {
  193. final InputDevice.MotionRange range = p_device.getMotionRange(p_axis, p_event.getSource());
  194. if (range == null)
  195. return 0;
  196. //Log.e(TAG, String.format("axis ranges %f, %f, %f", range.getRange(), range.getMin(), range.getMax()));
  197. final float flat = range.getFlat();
  198. final float value =
  199. p_pos < 0 ? p_event.getAxisValue(p_axis):
  200. p_event.getHistoricalAxisValue(p_axis, p_pos);
  201. final float absval = Math.abs(value);
  202. if (absval <= flat) {
  203. return 0;
  204. };
  205. final float ret = (value - range.getMin()) / range.getRange() * 2 - 1.0f;
  206. return ret;
  207. };
  208. float[] last_axis_values = { 0, 0, 0, 0, -1, -1 };
  209. boolean[] last_axis_buttons = { false, false, false, false, false, false }; // dpad up down left right, ltrigger, rtrigger
  210. public void process_axis_state(MotionEvent p_event, int p_pos) {
  211. int device_id = p_event.getDeviceId();
  212. InputDevice device = p_event.getDevice();
  213. float val;
  214. val = axis_value(p_event, device, MotionEvent.AXIS_X, p_pos);
  215. if (val != last_axis_values[0]) {
  216. last_axis_values[0] = val;
  217. //Log.e(TAG, String.format("axis moved! axis %d, value %f", 0, val));
  218. GodotLib.joyaxis(device_id, 0, val);
  219. };
  220. val = axis_value(p_event, device, MotionEvent.AXIS_Y, p_pos);
  221. if (val != last_axis_values[1]) {
  222. last_axis_values[1] = val;
  223. //Log.e(TAG, String.format("axis moved! axis %d, value %f", 1, val));
  224. GodotLib.joyaxis(device_id, 1, val);
  225. };
  226. val = axis_value(p_event, device, MotionEvent.AXIS_Z, p_pos);
  227. if (val != last_axis_values[2]) {
  228. last_axis_values[2] = val;
  229. //Log.e(TAG, String.format("axis moved! axis %d, value %f", 2, val));
  230. GodotLib.joyaxis(device_id, 2, val);
  231. };
  232. val = axis_value(p_event, device, MotionEvent.AXIS_RZ, p_pos);
  233. if (val != last_axis_values[3]) {
  234. last_axis_values[3] = val;
  235. //Log.e(TAG, String.format("axis moved! axis %d, value %f", 3, val));
  236. GodotLib.joyaxis(device_id, 3, val);
  237. };
  238. val = axis_value(p_event, device, MotionEvent.AXIS_LTRIGGER, p_pos);
  239. if (val != last_axis_values[4]) {
  240. last_axis_values[4] = val;
  241. if ((val != 0) != (last_axis_buttons[4])) {
  242. last_axis_buttons[4] = (val != 0);
  243. GodotLib.joybutton(device_id, 6, (val != 0));
  244. };
  245. };
  246. val = axis_value(p_event, device, MotionEvent.AXIS_RTRIGGER, p_pos);
  247. if (val != last_axis_values[5]) {
  248. last_axis_values[5] = val;
  249. if ((val != 0) != (last_axis_buttons[5])) {
  250. last_axis_buttons[5] = (val != 0);
  251. GodotLib.joybutton(device_id, 7, (val != 0));
  252. };
  253. };
  254. val = axis_value(p_event, device, MotionEvent.AXIS_HAT_Y, p_pos);
  255. if (last_axis_buttons[0] != (val > 0)) {
  256. last_axis_buttons[0] = val > 0;
  257. GodotLib.joybutton(device_id, 12, val > 0);
  258. };
  259. if (last_axis_buttons[1] != (val < 0)) {
  260. last_axis_buttons[1] = val < 0;
  261. GodotLib.joybutton(device_id, 13, val > 0);
  262. };
  263. val = axis_value(p_event, device, MotionEvent.AXIS_HAT_X, p_pos);
  264. if (last_axis_buttons[2] != (val < 0)) {
  265. last_axis_buttons[2] = val < 0;
  266. GodotLib.joybutton(device_id, 14, val < 0);
  267. };
  268. if (last_axis_buttons[3] != (val > 0)) {
  269. last_axis_buttons[3] = val > 0;
  270. GodotLib.joybutton(device_id, 15, val > 0);
  271. };
  272. };
  273. @Override public boolean onGenericMotionEvent(MotionEvent event) {
  274. if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
  275. // Process all historical movement samples in the batch
  276. final int historySize = event.getHistorySize();
  277. // Process the movements starting from the
  278. // earliest historical position in the batch
  279. for (int i = 0; i < historySize; i++) {
  280. // Process the event at historical position i
  281. process_axis_state(event, i);
  282. }
  283. // Process the current movement sample in the batch (position -1)
  284. process_axis_state(event, -1);
  285. return true;
  286. };
  287. return super.onGenericMotionEvent(event);
  288. };
  289. private void init(boolean translucent, int depth, int stencil) {
  290. this.setFocusableInTouchMode(true);
  291. /* By default, GLSurfaceView() creates a RGB_565 opaque surface.
  292. * If we want a translucent one, we should change the surface's
  293. * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
  294. * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
  295. */
  296. if (translucent) {
  297. this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
  298. }
  299. /* Setup the context factory for 2.0 rendering.
  300. * See ContextFactory class definition below
  301. */
  302. setEGLContextFactory(new ContextFactory());
  303. /* We need to choose an EGLConfig that matches the format of
  304. * our surface exactly. This is going to be done in our
  305. * custom config chooser. See ConfigChooser class definition
  306. * below.
  307. */
  308. if (use_32) {
  309. setEGLConfigChooser( translucent ?
  310. new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(8, 8, 8, 8, 16, stencil)) :
  311. new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(5, 6, 5, 0, 16, stencil)) );
  312. } else {
  313. setEGLConfigChooser( translucent ?
  314. new ConfigChooser(8, 8, 8, 8, 16, stencil) :
  315. new ConfigChooser(5, 6, 5, 0, 16, stencil) );
  316. }
  317. /* Set the renderer responsible for frame rendering */
  318. setRenderer(new Renderer());
  319. }
  320. private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
  321. private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
  322. public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
  323. if (use_gl2)
  324. Log.w(TAG, "creating OpenGL ES 2.0 context :");
  325. else
  326. Log.w(TAG, "creating OpenGL ES 1.1 context :");
  327. checkEglError("Before eglCreateContext", egl);
  328. int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
  329. EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null);
  330. checkEglError("After eglCreateContext", egl);
  331. return context;
  332. }
  333. public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
  334. egl.eglDestroyContext(display, context);
  335. }
  336. }
  337. private static void checkEglError(String prompt, EGL10 egl) {
  338. int error;
  339. while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
  340. Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
  341. }
  342. }
  343. /* Fallback if 32bit View is not supported*/
  344. private static class FallbackConfigChooser extends ConfigChooser {
  345. private ConfigChooser fallback;
  346. public FallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, ConfigChooser fallback) {
  347. super(r, g, b, a, depth, stencil);
  348. this.fallback = fallback;
  349. }
  350. @Override
  351. public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
  352. EGLConfig ec = super.chooseConfig(egl, display, configs);
  353. if (ec == null) {
  354. Log.w(TAG, "Trying ConfigChooser fallback");
  355. ec = fallback.chooseConfig(egl, display, configs);
  356. use_32=false;
  357. }
  358. return ec;
  359. }
  360. }
  361. private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
  362. public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
  363. mRedSize = r;
  364. mGreenSize = g;
  365. mBlueSize = b;
  366. mAlphaSize = a;
  367. mDepthSize = depth;
  368. mStencilSize = stencil;
  369. }
  370. /* This EGL config specification is used to specify 2.0 rendering.
  371. * We use a minimum size of 4 bits for red/green/blue, but will
  372. * perform actual matching in chooseConfig() below.
  373. */
  374. private static int EGL_OPENGL_ES2_BIT = 4;
  375. private static int[] s_configAttribs2 =
  376. {
  377. EGL10.EGL_RED_SIZE, 4,
  378. EGL10.EGL_GREEN_SIZE, 4,
  379. EGL10.EGL_BLUE_SIZE, 4,
  380. // EGL10.EGL_DEPTH_SIZE, 16,
  381. // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE,
  382. EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  383. EGL10.EGL_NONE
  384. };
  385. private static int[] s_configAttribs =
  386. {
  387. EGL10.EGL_RED_SIZE, 4,
  388. EGL10.EGL_GREEN_SIZE, 4,
  389. EGL10.EGL_BLUE_SIZE, 4,
  390. // EGL10.EGL_DEPTH_SIZE, 16,
  391. // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE,
  392. EGL10.EGL_NONE
  393. };
  394. public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
  395. /* Get the number of minimally matching EGL configurations
  396. */
  397. int[] num_config = new int[1];
  398. egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config);
  399. int numConfigs = num_config[0];
  400. if (numConfigs <= 0) {
  401. throw new IllegalArgumentException("No configs match configSpec");
  402. }
  403. /* Allocate then read the array of minimally matching EGL configs
  404. */
  405. EGLConfig[] configs = new EGLConfig[numConfigs];
  406. egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config);
  407. if (DEBUG) {
  408. printConfigs(egl, display, configs);
  409. }
  410. /* Now return the "best" one
  411. */
  412. return chooseConfig(egl, display, configs);
  413. }
  414. public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
  415. EGLConfig[] configs) {
  416. for(EGLConfig config : configs) {
  417. int d = findConfigAttrib(egl, display, config,
  418. EGL10.EGL_DEPTH_SIZE, 0);
  419. int s = findConfigAttrib(egl, display, config,
  420. EGL10.EGL_STENCIL_SIZE, 0);
  421. // We need at least mDepthSize and mStencilSize bits
  422. if (d < mDepthSize || s < mStencilSize)
  423. continue;
  424. // We want an *exact* match for red/green/blue/alpha
  425. int r = findConfigAttrib(egl, display, config,
  426. EGL10.EGL_RED_SIZE, 0);
  427. int g = findConfigAttrib(egl, display, config,
  428. EGL10.EGL_GREEN_SIZE, 0);
  429. int b = findConfigAttrib(egl, display, config,
  430. EGL10.EGL_BLUE_SIZE, 0);
  431. int a = findConfigAttrib(egl, display, config,
  432. EGL10.EGL_ALPHA_SIZE, 0);
  433. if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
  434. return config;
  435. }
  436. return null;
  437. }
  438. private int findConfigAttrib(EGL10 egl, EGLDisplay display,
  439. EGLConfig config, int attribute, int defaultValue) {
  440. if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
  441. return mValue[0];
  442. }
  443. return defaultValue;
  444. }
  445. private void printConfigs(EGL10 egl, EGLDisplay display,
  446. EGLConfig[] configs) {
  447. int numConfigs = configs.length;
  448. Log.w(TAG, String.format("%d configurations", numConfigs));
  449. for (int i = 0; i < numConfigs; i++) {
  450. Log.w(TAG, String.format("Configuration %d:\n", i));
  451. printConfig(egl, display, configs[i]);
  452. }
  453. }
  454. private void printConfig(EGL10 egl, EGLDisplay display,
  455. EGLConfig config) {
  456. int[] attributes = {
  457. EGL10.EGL_BUFFER_SIZE,
  458. EGL10.EGL_ALPHA_SIZE,
  459. EGL10.EGL_BLUE_SIZE,
  460. EGL10.EGL_GREEN_SIZE,
  461. EGL10.EGL_RED_SIZE,
  462. EGL10.EGL_DEPTH_SIZE,
  463. EGL10.EGL_STENCIL_SIZE,
  464. EGL10.EGL_CONFIG_CAVEAT,
  465. EGL10.EGL_CONFIG_ID,
  466. EGL10.EGL_LEVEL,
  467. EGL10.EGL_MAX_PBUFFER_HEIGHT,
  468. EGL10.EGL_MAX_PBUFFER_PIXELS,
  469. EGL10.EGL_MAX_PBUFFER_WIDTH,
  470. EGL10.EGL_NATIVE_RENDERABLE,
  471. EGL10.EGL_NATIVE_VISUAL_ID,
  472. EGL10.EGL_NATIVE_VISUAL_TYPE,
  473. 0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
  474. EGL10.EGL_SAMPLES,
  475. EGL10.EGL_SAMPLE_BUFFERS,
  476. EGL10.EGL_SURFACE_TYPE,
  477. EGL10.EGL_TRANSPARENT_TYPE,
  478. EGL10.EGL_TRANSPARENT_RED_VALUE,
  479. EGL10.EGL_TRANSPARENT_GREEN_VALUE,
  480. EGL10.EGL_TRANSPARENT_BLUE_VALUE,
  481. 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
  482. 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
  483. 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
  484. 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
  485. EGL10.EGL_LUMINANCE_SIZE,
  486. EGL10.EGL_ALPHA_MASK_SIZE,
  487. EGL10.EGL_COLOR_BUFFER_TYPE,
  488. EGL10.EGL_RENDERABLE_TYPE,
  489. 0x3042 // EGL10.EGL_CONFORMANT
  490. };
  491. String[] names = {
  492. "EGL_BUFFER_SIZE",
  493. "EGL_ALPHA_SIZE",
  494. "EGL_BLUE_SIZE",
  495. "EGL_GREEN_SIZE",
  496. "EGL_RED_SIZE",
  497. "EGL_DEPTH_SIZE",
  498. "EGL_STENCIL_SIZE",
  499. "EGL_CONFIG_CAVEAT",
  500. "EGL_CONFIG_ID",
  501. "EGL_LEVEL",
  502. "EGL_MAX_PBUFFER_HEIGHT",
  503. "EGL_MAX_PBUFFER_PIXELS",
  504. "EGL_MAX_PBUFFER_WIDTH",
  505. "EGL_NATIVE_RENDERABLE",
  506. "EGL_NATIVE_VISUAL_ID",
  507. "EGL_NATIVE_VISUAL_TYPE",
  508. "EGL_PRESERVED_RESOURCES",
  509. "EGL_SAMPLES",
  510. "EGL_SAMPLE_BUFFERS",
  511. "EGL_SURFACE_TYPE",
  512. "EGL_TRANSPARENT_TYPE",
  513. "EGL_TRANSPARENT_RED_VALUE",
  514. "EGL_TRANSPARENT_GREEN_VALUE",
  515. "EGL_TRANSPARENT_BLUE_VALUE",
  516. "EGL_BIND_TO_TEXTURE_RGB",
  517. "EGL_BIND_TO_TEXTURE_RGBA",
  518. "EGL_MIN_SWAP_INTERVAL",
  519. "EGL_MAX_SWAP_INTERVAL",
  520. "EGL_LUMINANCE_SIZE",
  521. "EGL_ALPHA_MASK_SIZE",
  522. "EGL_COLOR_BUFFER_TYPE",
  523. "EGL_RENDERABLE_TYPE",
  524. "EGL_CONFORMANT"
  525. };
  526. int[] value = new int[1];
  527. for (int i = 0; i < attributes.length; i++) {
  528. int attribute = attributes[i];
  529. String name = names[i];
  530. if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
  531. Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
  532. } else {
  533. // Log.w(TAG, String.format(" %s: failed\n", name));
  534. while (egl.eglGetError() != EGL10.EGL_SUCCESS);
  535. }
  536. }
  537. }
  538. // Subclasses can adjust these values:
  539. protected int mRedSize;
  540. protected int mGreenSize;
  541. protected int mBlueSize;
  542. protected int mAlphaSize;
  543. protected int mDepthSize;
  544. protected int mStencilSize;
  545. private int[] mValue = new int[1];
  546. }
  547. private static class Renderer implements GLSurfaceView.Renderer {
  548. public void onDrawFrame(GL10 gl) {
  549. GodotLib.step();
  550. for(int i=0;i<Godot.singleton_count;i++) {
  551. Godot.singletons[i].onGLDrawFrame(gl);
  552. }
  553. }
  554. public void onSurfaceChanged(GL10 gl, int width, int height) {
  555. GodotLib.resize(width, height,!firsttime);
  556. firsttime=false;
  557. for(int i=0;i<Godot.singleton_count;i++) {
  558. Godot.singletons[i].onGLSurfaceChanged(gl, width, height);
  559. }
  560. }
  561. public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  562. GodotLib.newcontext(use_32);
  563. }
  564. }
  565. }