1

我想在我的 android 游戏中释放纹理、缓冲区和着色器,如果用户点击后退按钮,调用活动的finish()方法,导致onDestroy(),我覆盖它以清理游戏数据,关闭服务器连接等等。
我在清单中设置了 android:launchMode="singleTask",因此调用活动的 finish() 总是会导致立即销毁。
但是要使用glDeleteBuffers(...),例如,它必须从具有 EGL 上下文的线程(渲染器线程)调用,但即使从 Renderer 类设置和调用此类方法,我也会得到 - 没有 OpenGL ES 上下文错误。

我使用 NDK,所以NativeLib.*调用一个 C/C++ 函数,例如

JNIEXPORT void JNICALL /*class path*/_NativeLib_onDrawFrame(JNIEnv* env, jclass _class)
{
 glClear(GL_COLOR_BUFFER_BIT);
 ...
}

看法

public class OGLES2View extends GLSurfaceView
{

  private static class OGLES2Renderer implements GLSurfaceView.Renderer
  {
    public void onDrawFrame(GL10 unused)
    {
        NativeLib.onDrawFrame();
    }

    public void onSurfaceChanged(GL10 unused, int width, int height)
    {
        NativeLib.onSurfaceChanged(width, height);
    }

    public void onSurfaceCreated(GL10 unused, EGLConfig unusedConfig)
    {
        NativeLib.onSurfaceCreated();
    }

    public void onSurfaceDestroy()
    {
        Log.i(LOG_TAG, "Destroying Opengl objects");
        NativeLib.onGLDestroy();//Don't work - call to OpenGL API with current context
    }

}

public OGLES2Renderer renderer = null; 
public OGLES2View(Context context)
{
    super(context);
    setRenderer(renderer = new OGLES2Renderer());
}

在活动中

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    ogles2View = new OGLES2View(this);
    setContentView(ogles2View);
}

@Override
protected void onDestroy()
{
    Log.i(LOG_TAG, "Got finish request for game");
    super.onDestroy();
    ogles2View.render.onSurfaceDestroy(); // Don't not work
}
4

2 回答 2

1

一旦 EGL 上下文被破坏,所有的 GL 缓冲区等都将随之破坏,因此这是不必要的。

于 2012-08-16T14:29:45.363 回答
1

如果有人确实需要在销毁之前EGLContext(或在给定方法之外的任何执行点)在 GLThread 上运行某些东西,您可以使用 的queueEvent()方法GLSurfaceView将 a 发布Runnable到 GLThread。请注意,您必须setRenderer()在使用之前调用queueEvent()

示例(针对 OP 的问题):

...

public void onSurfaceDestroy()
{
    queueEvent(new Runnable() {
        @Override
        public void run() {
            Log.i(LOG_TAG, "Destroying Opengl objects");
            NativeLib.onGLDestroy(); //Works since it's called on the GLThread
        }
    }
}

...
于 2018-10-04T16:21:36.080 回答