问题
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();
}
回答1:
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.
回答2:
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);
}
}
回答3:
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
来源:https://stackoverflow.com/questions/5701393/android-disable-opengl-es-context-switch-upon-device-rotation