2

i have an android fullscreen opengl es app.

when the device is rotate from portrait to landscape and back the gl context is destroyed and recreated.

is there a way to avoid this? i.e. always stay in portrait or landscape?

edit: i already have this code in my activity:

@Override
protected void onResume()
{
    super.onResume();
    mGLSurfaceView.onResume();      
}

@Override
protected void onPause()
{    
    super.onPause();
    mGLSurfaceView.onPause();
}
clamp
  • 33,000
  • 75
  • 203
  • 299

3 Answers3

5

Unfortunately until API Level 11 (3.0) GLSurfaceView will always destroy the GL context. For 11 and higher you have the ability to setPreserveEGLContextOnPause (boolean preserveOnPause).

There are ways around this by changing the source of GLSurfaceView but any problems you encounter it will be a lot harder to get help from others.

MichalisB
  • 568
  • 3
  • 14
3

It's possible to retain your GlContext when your app is rotating so it doesn't get destroyed

Instead of rewriting the whole GlSurfaceView you can just provide a EGLContextFactory to change how the GlContext are created/destroyed.

public class ConfigChangesGlSurfaceView extends GLSurfaceView {

    private static final int EGL_CONTEXT_CLIENT_VERSION_VALUE = 2;
    private static EGLContext retainedGlContext = null;
    private boolean changingConfigurations = false;

    public ConfigChangesGlSurfaceView(Context context) {
        super(context);
        init();
    }

    public ConfigChangesGlSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        changingConfigurations = false;
        setEGLContextClientVersion(EGL_CONTEXT_CLIENT_VERSION_VALUE);
        setEGLContextFactory(new GLSurfaceView.EGLContextFactory() {
            private final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

            public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
                if (retainedGlContext != null) {
                    // Return retained context
                    final EGLContext eglContext = retainedGlContext;
                    retainedGlContext = null;
                    return eglContext;
                }

                int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_VALUE, EGL10.EGL_NONE};
                return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, attrib_list);
            }

            public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
                if (changingConfigurations) {
                    // Don't destroy and retain
                    retainedGlContext = context;
                    return;
                }

                if (!egl.eglDestroyContext(display, context)) {
                    throw new RuntimeException("eglDestroyContext failed: error " + egl.eglGetError());
                }
            }
        });
    }

    @Override
    public void onPause() {
        changingConfigurations = getActivity().isChangingConfigurations();
        super.onPause();
    }

    private Activity getActivity() {
        Context context = getContext();
        while (!(context instanceof Activity) && context instanceof ContextWrapper) {
            context = ((ContextWrapper) context).getBaseContext();
        }
        if (context instanceof Activity) {
            return (Activity) context;
        }
        throw new IllegalStateException("Unable to find an activity: " + context);
    }
}
sgc_code
  • 485
  • 2
  • 7
1

If you want to keep your GL Context safe without being destroyed then you need to override the functions in your Activity class OnPause() and OnResume() by calling you GLSurfaceView().OnPause and GLSurfaceView().Resume().

@Override
protected void onPause() 
{
 super.onPause();
 GLSurfaceView_Class.OnPause();
}

//same for onResume too.

If you want to limit your app to be either in potrait or landscape then you can define that in your manifest file.

android:screenOrientation="landscape" in your activity tag.

I hope this helps

Augustus
  • 11
  • 1
  • thanks, i already call onpause and onresume on the glsurfaceview but it still recreates the glcontext every time. – clamp Aug 25 '11 at 08:40