android:在设备旋转时禁用 opengl ES 上下文切换

发布于 2024-11-01 20:48:43 字数 355 浏览 4 评论 0原文

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

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

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

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月流歌 2024-11-08 20:48:43

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

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

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.

幸福不弃 2024-11-08 20:48:43

当你的应用程序旋转时,可以保留你的 GlContext,这样它就不会被破坏,

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

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

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);
    }
}
比忠 2024-11-08 20:48:43

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

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

// onResume 也一样。

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

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

我希望这有帮助

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文