diff options
Diffstat (limited to 'platform/android/java/src/org/godotengine/godot/GodotView.java')
-rw-r--r-- | platform/android/java/src/org/godotengine/godot/GodotView.java | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java new file mode 100644 index 0000000000..04b5dfa5dd --- /dev/null +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -0,0 +1,661 @@ +/*************************************************************************/ +/* GodotView.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +package org.godotengine.godot; +import android.content.Context; +import android.graphics.PixelFormat; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.content.ContextWrapper; +import android.view.InputDevice; + +import java.io.File; +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +/** + * A simple GLSurfaceView sub-class that demonstrate how to perform + * OpenGL ES 2.0 rendering into a GL Surface. Note the following important + * details: + * + * - The class must use a custom context factory to enable 2.0 rendering. + * See ContextFactory class definition below. + * + * - The class must use a custom EGLConfigChooser to be able to select + * an EGLConfig that supports 2.0. This is done by providing a config + * specification to eglChooseConfig() that has the attribute + * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag + * set. See ConfigChooser class definition below. + * + * - The class must select the surface's format, then choose an EGLConfig + * that matches it exactly (with regards to red/green/blue/alpha channels + * bit depths). Failure to do so would result in an EGL_BAD_MATCH error. + */ +public class GodotView extends GLSurfaceView { + + private static String TAG = "GodotView"; + private static final boolean DEBUG = false; + private static Context ctx; + + private static GodotIO io; + private static boolean firsttime=true; + private static boolean use_gl2=false; + private static boolean use_32=false; + + private Godot activity; + + public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, boolean p_use_32_bits, Godot p_activity) { + super(context); + ctx=context; + io=p_io; + use_gl2=p_use_gl2; + use_32=p_use_32_bits; + + activity = p_activity; + + if (!p_io.needsReloadHooks()) { + //will only work on SDK 11+!! + setPreserveEGLContextOnPause(true); + } + + init(false, 16, 0); + } + + public GodotView(Context context, boolean translucent, int depth, int stencil) { + super(context); + init(translucent, depth, stencil); + } + + @Override public boolean onTouchEvent (MotionEvent event) { + + return activity.gotTouchEvent(event); + }; + + public int get_godot_button(int keyCode) { + + int button = 0; + switch (keyCode) { + case KeyEvent.KEYCODE_BUTTON_A: // Android A is SNES B + button = 0; + break; + case KeyEvent.KEYCODE_BUTTON_B: + button = 1; + break; + case KeyEvent.KEYCODE_BUTTON_X: // Android X is SNES Y + button = 2; + break; + case KeyEvent.KEYCODE_BUTTON_Y: + button = 3; + break; + case KeyEvent.KEYCODE_BUTTON_L1: + button = 4; + break; + case KeyEvent.KEYCODE_BUTTON_L2: + button = 6; + break; + case KeyEvent.KEYCODE_BUTTON_R1: + button = 5; + break; + case KeyEvent.KEYCODE_BUTTON_R2: + button = 7; + break; + case KeyEvent.KEYCODE_BUTTON_SELECT: + button = 10; + break; + case KeyEvent.KEYCODE_BUTTON_START: + button = 11; + break; + case KeyEvent.KEYCODE_BUTTON_THUMBL: + button = 8; + break; + case KeyEvent.KEYCODE_BUTTON_THUMBR: + button = 9; + break; + case KeyEvent.KEYCODE_DPAD_UP: + button = 12; + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + button = 13; + break; + case KeyEvent.KEYCODE_DPAD_LEFT: + button = 14; + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + button = 15; + break; + + default: + button = keyCode - KeyEvent.KEYCODE_BUTTON_1; + break; + }; + + return button; + }; + + @Override public boolean onKeyUp(int keyCode, KeyEvent event) { + + if (keyCode == KeyEvent.KEYCODE_BACK) { + return true; + } + + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + return super.onKeyUp(keyCode, event); + }; + + int source = event.getSource(); + if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + + int button = get_godot_button(keyCode); + int device = event.getDeviceId(); + + GodotLib.joybutton(device, button, false); + return true; + } else { + + GodotLib.key(keyCode, event.getUnicodeChar(0), false); + }; + return super.onKeyUp(keyCode, event); + }; + + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + + if (keyCode == KeyEvent.KEYCODE_BACK) { + GodotLib.quit(); + // press 'back' button should not terminate program + // normal handle 'back' event in game logic + return true; + } + + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + return super.onKeyDown(keyCode, event); + }; + + int source = event.getSource(); + //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))); + + if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + + if (event.getRepeatCount() > 0) // ignore key echo + return true; + int button = get_godot_button(keyCode); + int device = event.getDeviceId(); + //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); + + GodotLib.joybutton(device, button, true); + return true; + + } else { + GodotLib.key(keyCode, event.getUnicodeChar(0), true); + }; + return super.onKeyDown(keyCode, event); + } + + public float axis_value(MotionEvent p_event, InputDevice p_device, int p_axis, int p_pos) { + + final InputDevice.MotionRange range = p_device.getMotionRange(p_axis, p_event.getSource()); + if (range == null) + return 0; + + //Log.e(TAG, String.format("axis ranges %f, %f, %f", range.getRange(), range.getMin(), range.getMax())); + + final float flat = range.getFlat(); + final float value = + p_pos < 0 ? p_event.getAxisValue(p_axis): + p_event.getHistoricalAxisValue(p_axis, p_pos); + + final float absval = Math.abs(value); + if (absval <= flat) { + return 0; + }; + + final float ret = (value - range.getMin()) / range.getRange() * 2 - 1.0f; + + return ret; + }; + + float[] last_axis_values = { 0, 0, 0, 0, -1, -1 }; + boolean[] last_axis_buttons = { false, false, false, false, false, false }; // dpad up down left right, ltrigger, rtrigger + + public void process_axis_state(MotionEvent p_event, int p_pos) { + + int device_id = p_event.getDeviceId(); + InputDevice device = p_event.getDevice(); + float val; + + val = axis_value(p_event, device, MotionEvent.AXIS_X, p_pos); + if (val != last_axis_values[0]) { + last_axis_values[0] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 0, val)); + GodotLib.joyaxis(device_id, 0, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_Y, p_pos); + if (val != last_axis_values[1]) { + last_axis_values[1] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 1, val)); + GodotLib.joyaxis(device_id, 1, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_Z, p_pos); + if (val != last_axis_values[2]) { + last_axis_values[2] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 2, val)); + GodotLib.joyaxis(device_id, 2, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_RZ, p_pos); + if (val != last_axis_values[3]) { + last_axis_values[3] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 3, val)); + GodotLib.joyaxis(device_id, 3, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_LTRIGGER, p_pos); + if (val != last_axis_values[4]) { + last_axis_values[4] = val; + if ((val != 0) != (last_axis_buttons[4])) { + last_axis_buttons[4] = (val != 0); + GodotLib.joybutton(device_id, 6, (val != 0)); + }; + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_RTRIGGER, p_pos); + if (val != last_axis_values[5]) { + last_axis_values[5] = val; + if ((val != 0) != (last_axis_buttons[5])) { + last_axis_buttons[5] = (val != 0); + GodotLib.joybutton(device_id, 7, (val != 0)); + }; + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_HAT_Y, p_pos); + + if (last_axis_buttons[0] != (val > 0)) { + last_axis_buttons[0] = val > 0; + GodotLib.joybutton(device_id, 12, val > 0); + }; + if (last_axis_buttons[1] != (val < 0)) { + last_axis_buttons[1] = val < 0; + GodotLib.joybutton(device_id, 13, val > 0); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_HAT_X, p_pos); + if (last_axis_buttons[2] != (val < 0)) { + last_axis_buttons[2] = val < 0; + GodotLib.joybutton(device_id, 14, val < 0); + }; + if (last_axis_buttons[3] != (val > 0)) { + last_axis_buttons[3] = val > 0; + GodotLib.joybutton(device_id, 15, val > 0); + }; + }; + + @Override public boolean onGenericMotionEvent(MotionEvent event) { + + if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { + + // Process all historical movement samples in the batch + final int historySize = event.getHistorySize(); + + // Process the movements starting from the + // earliest historical position in the batch + for (int i = 0; i < historySize; i++) { + // Process the event at historical position i + process_axis_state(event, i); + } + + // Process the current movement sample in the batch (position -1) + process_axis_state(event, -1); + return true; + + + }; + + return super.onGenericMotionEvent(event); + }; + + + private void init(boolean translucent, int depth, int stencil) { + + this.setFocusableInTouchMode(true); + /* By default, GLSurfaceView() creates a RGB_565 opaque surface. + * If we want a translucent one, we should change the surface's + * format here, using PixelFormat.TRANSLUCENT for GL Surfaces + * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. + */ + if (translucent) { + this.getHolder().setFormat(PixelFormat.TRANSLUCENT); + } + + /* Setup the context factory for 2.0 rendering. + * See ContextFactory class definition below + */ + setEGLContextFactory(new ContextFactory()); + + /* We need to choose an EGLConfig that matches the format of + * our surface exactly. This is going to be done in our + * custom config chooser. See ConfigChooser class definition + * below. + */ + + if (use_32) { + setEGLConfigChooser( translucent ? + new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(8, 8, 8, 8, 16, stencil)) : + new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(5, 6, 5, 0, 16, stencil)) ); + + } else { + setEGLConfigChooser( translucent ? + new ConfigChooser(8, 8, 8, 8, 16, stencil) : + new ConfigChooser(5, 6, 5, 0, 16, stencil) ); + } + + /* Set the renderer responsible for frame rendering */ + setRenderer(new Renderer()); + } + + private static class ContextFactory implements GLSurfaceView.EGLContextFactory { + private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { + if (use_gl2) + Log.w(TAG, "creating OpenGL ES 2.0 context :"); + else + Log.w(TAG, "creating OpenGL ES 1.1 context :"); + + checkEglError("Before eglCreateContext", egl); + int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null); + checkEglError("After eglCreateContext", egl); + return context; + } + + public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { + egl.eglDestroyContext(display, context); + } + } + + private static void checkEglError(String prompt, EGL10 egl) { + int error; + while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { + Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); + } + } + /* Fallback if 32bit View is not supported*/ + private static class FallbackConfigChooser extends ConfigChooser { + private ConfigChooser fallback; + + public FallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, ConfigChooser fallback) { + super(r, g, b, a, depth, stencil); + this.fallback = fallback; + } + + @Override + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { + EGLConfig ec = super.chooseConfig(egl, display, configs); + if (ec == null) { + Log.w(TAG, "Trying ConfigChooser fallback"); + ec = fallback.chooseConfig(egl, display, configs); + use_32=false; + } + return ec; + } + } + + private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { + + public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + mRedSize = r; + mGreenSize = g; + mBlueSize = b; + mAlphaSize = a; + mDepthSize = depth; + mStencilSize = stencil; + } + + /* This EGL config specification is used to specify 2.0 rendering. + * We use a minimum size of 4 bits for red/green/blue, but will + * perform actual matching in chooseConfig() below. + */ + private static int EGL_OPENGL_ES2_BIT = 4; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + // EGL10.EGL_DEPTH_SIZE, 16, + // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + private static int[] s_configAttribs = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + // EGL10.EGL_DEPTH_SIZE, 16, + // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, + EGL10.EGL_NONE + }; + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + + /* Get the number of minimally matching EGL configurations + */ + int[] num_config = new int[1]; + egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config); + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + + /* Allocate then read the array of minimally matching EGL configs + */ + EGLConfig[] configs = new EGLConfig[numConfigs]; + egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config); + + if (DEBUG) { + printConfigs(egl, display, configs); + } + /* Now return the "best" one + */ + return chooseConfig(egl, display, configs); + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + for(EGLConfig config : configs) { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + + // We need at least mDepthSize and mStencilSize bits + if (d < mDepthSize || s < mStencilSize) + continue; + + // We want an *exact* match for red/green/blue/alpha + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + + if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) + return config; + } + return null; + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { + + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } + + private void printConfigs(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + int numConfigs = configs.length; + Log.w(TAG, String.format("%d configurations", numConfigs)); + for (int i = 0; i < numConfigs; i++) { + Log.w(TAG, String.format("Configuration %d:\n", i)); + printConfig(egl, display, configs[i]); + } + } + + private void printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int[] attributes = { + EGL10.EGL_BUFFER_SIZE, + EGL10.EGL_ALPHA_SIZE, + EGL10.EGL_BLUE_SIZE, + EGL10.EGL_GREEN_SIZE, + EGL10.EGL_RED_SIZE, + EGL10.EGL_DEPTH_SIZE, + EGL10.EGL_STENCIL_SIZE, + EGL10.EGL_CONFIG_CAVEAT, + EGL10.EGL_CONFIG_ID, + EGL10.EGL_LEVEL, + EGL10.EGL_MAX_PBUFFER_HEIGHT, + EGL10.EGL_MAX_PBUFFER_PIXELS, + EGL10.EGL_MAX_PBUFFER_WIDTH, + EGL10.EGL_NATIVE_RENDERABLE, + EGL10.EGL_NATIVE_VISUAL_ID, + EGL10.EGL_NATIVE_VISUAL_TYPE, + 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, + EGL10.EGL_SAMPLES, + EGL10.EGL_SAMPLE_BUFFERS, + EGL10.EGL_SURFACE_TYPE, + EGL10.EGL_TRANSPARENT_TYPE, + EGL10.EGL_TRANSPARENT_RED_VALUE, + EGL10.EGL_TRANSPARENT_GREEN_VALUE, + EGL10.EGL_TRANSPARENT_BLUE_VALUE, + 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, + 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, + 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, + 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, + EGL10.EGL_LUMINANCE_SIZE, + EGL10.EGL_ALPHA_MASK_SIZE, + EGL10.EGL_COLOR_BUFFER_TYPE, + EGL10.EGL_RENDERABLE_TYPE, + 0x3042 // EGL10.EGL_CONFORMANT + }; + String[] names = { + "EGL_BUFFER_SIZE", + "EGL_ALPHA_SIZE", + "EGL_BLUE_SIZE", + "EGL_GREEN_SIZE", + "EGL_RED_SIZE", + "EGL_DEPTH_SIZE", + "EGL_STENCIL_SIZE", + "EGL_CONFIG_CAVEAT", + "EGL_CONFIG_ID", + "EGL_LEVEL", + "EGL_MAX_PBUFFER_HEIGHT", + "EGL_MAX_PBUFFER_PIXELS", + "EGL_MAX_PBUFFER_WIDTH", + "EGL_NATIVE_RENDERABLE", + "EGL_NATIVE_VISUAL_ID", + "EGL_NATIVE_VISUAL_TYPE", + "EGL_PRESERVED_RESOURCES", + "EGL_SAMPLES", + "EGL_SAMPLE_BUFFERS", + "EGL_SURFACE_TYPE", + "EGL_TRANSPARENT_TYPE", + "EGL_TRANSPARENT_RED_VALUE", + "EGL_TRANSPARENT_GREEN_VALUE", + "EGL_TRANSPARENT_BLUE_VALUE", + "EGL_BIND_TO_TEXTURE_RGB", + "EGL_BIND_TO_TEXTURE_RGBA", + "EGL_MIN_SWAP_INTERVAL", + "EGL_MAX_SWAP_INTERVAL", + "EGL_LUMINANCE_SIZE", + "EGL_ALPHA_MASK_SIZE", + "EGL_COLOR_BUFFER_TYPE", + "EGL_RENDERABLE_TYPE", + "EGL_CONFORMANT" + }; + int[] value = new int[1]; + for (int i = 0; i < attributes.length; i++) { + int attribute = attributes[i]; + String name = names[i]; + if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { + Log.w(TAG, String.format(" %s: %d\n", name, value[0])); + } else { + // Log.w(TAG, String.format(" %s: failed\n", name)); + while (egl.eglGetError() != EGL10.EGL_SUCCESS); + } + } + } + + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + private int[] mValue = new int[1]; + } + + private static class Renderer implements GLSurfaceView.Renderer { + + + public void onDrawFrame(GL10 gl) { + GodotLib.step(); + for(int i=0;i<Godot.singleton_count;i++) { + Godot.singletons[i].onGLDrawFrame(gl); + } + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + + GodotLib.resize(width, height,!firsttime); + firsttime=false; + for(int i=0;i<Godot.singleton_count;i++) { + Godot.singletons[i].onGLSurfaceChanged(gl, width, height); + } + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + GodotLib.newcontext(use_32); + } + } +} |