暂停 Android ndk 应用程序时如何保留 EGL 上下文

How to preserve EGL context when pausing Android ndk app

我正在尝试改进 openframeworks,以便在暂停和恢复我的游戏时保留 GL 上下文。这样我就不必在每次暂停后重新加载所有纹理。我不希望你了解 openframeworks 代码,我会独立于它解释我的问题。

我有 java activity 加载一个 main_layout.xml 文件,其中一个 RelativeLayout 位于另一个 RelativeLayout 中。然后我实例化一个 GLSurfaceView 并使用 glContainer.addView(glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 将它添加到内部 RelativeLayout。在 onPause 函数中,我在 GLSurfaceView 上调用 glView.onPause();,在 onResume 中,我在 GLSurfaceView 上调用 glView.onResume();

这段代码有效,但它在 onPause 中破坏了 gl 表面(GLSurfaceView.surfaceDestroyed 在我的 GLSurfaceView 上被调用,它被扩展到 OFGLSurfaceView,这样我就可以拦截这个调用)。

为了解决这个问题,我添加了对 GLSurfaceView.setPreserveEGLContextOnPause 的调用和参数 'true' 来初始化我的 GLSurfaceView。现在我在暂停和恢复游戏后只看到黑屏。我发现,我可以通过从父 RelativeLayout 中删除 GLSurfaceView 并立即将其添加回 onResume 函数来解决此问题:glContainer.removeView( glView ); glContainer.addView( glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) );。然而,这再次破坏了 gl 表面并迫使我重新加载纹理。

RelativeLayouts 或 GLSurfaceView 之一都没有重新实例化(我通过查看代码然后使用 System.identityHashCode 检查这些实例的身份来检查它)。

main_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
   <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
        <RelativeLayout android:id="@+id/of_gl_surface_container" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
        <!-- add here other views' layouts -->
    </RelativeLayout>

OFAndroidLifeCycle.java 中的代码,用于处理从 Activity 收到的事件:

public static void glCreateSurface()
{
    if(mGLView == null)
    {
        mGLView = new OFGLSurfaceView(m_activity);

        OFGLSurfaceView glView = getGLView();

        glView.setPreserveEGLContextOnPause( true );

        ViewGroup parent = (ViewGroup)glView.getParent();
        if( parent == null )
        {
            ViewGroup glContainer = getActivity().getSurfaceContainer();
            glContainer.addView(glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        }
    }
}

public static void glPause()
{
    OFGLSurfaceView glView = getGLView();
    if( glView != null )
        glView.onPause();   
}

public static void glResume(ViewGroup glContainer)
{
    OFGLSurfaceView glView = getGLView();

    if( glView != null )
    {
        glView.onResume();

        glContainer.removeView( glView );
        glContainer.addView( glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) );
    }
}

好吧,我只是很困惑。有人可以详细说明应该如何完成这项工作,有哪些陷阱或我应该尝试哪些方法?

谢谢。

我后来也在 gamedev.stackexchange.com 上创建了这个问题,今天我在那里发布了解决方案:

https://gamedev.stackexchange.com/questions/171908/how-to-preserve-egl-context-when-pausing-android-ndk-app