【问题标题】:android: disable opengl ES context switch upon device rotationandroid:在设备旋转时禁用opengl ES上下文切换
【发布时间】:2016-05-18 19:38:59
【问题描述】:

我有一个 android 全屏 opengl es 应用程序。

当设备从纵向旋转到横向并返回时,gl 上下文被销毁并重新创建。

有没有办法避免这种情况?即始终保持纵向或横向?

编辑:我的活动中已经有此代码:

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

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

【问题讨论】:

    标签: android opengl-es fullscreen


    【解决方案1】:

    不幸的是,直到 API 级别 11 (3.0) GLSurfaceView 总是会破坏 GL 上下文。对于 11 及更高版本,您可以setPreserveEGLContextOnPause (boolean preserveOnPause)

    可以通过更改 GLSurfaceView 的来源来解决这个问题,但是您遇到的任何问题都很难从其他人那里获得帮助。

    【讨论】:

      【解决方案2】:

      可以在应用旋转时保留 GlContext,以免被破坏

      您可以只提供一个 EGLContextFactory 来更改 GlContext 的创建/销毁方式,而不是重写整个 GlSurfaceView。

      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);
          }
      }
      

      【讨论】:

      • 不应该在某个时候将changingConfigurations 设置回 false 吗?
      【解决方案3】:

      如果您想保持 GL 上下文安全而不被破坏,那么您需要通过调用 GLSurfaceView().OnPause 和 GLSurfaceView().Resume() 来覆盖 Activity 类 OnPause() 和 OnResume() 中的函数。

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

      //onResume 也一样。

      如果您想将应用限制为纵向或横向,则可以在清单文件中进行定义。

      您的活动标签中的android:screenOrientation="landscape"。

      希望对你有帮助

      【讨论】:

      • 谢谢,我已经在 glsurfaceview 上调用了 onpause 和 onresume 但它仍然每次都重新创建 glcontext。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      相关资源
      最近更新 更多