13

我想在与此答案类似的设置中创建一个具有我可以管理的 OpenGL 纹理的SurfaceTexture。(此处引用:)

  1. 通过OpenGL创建纹理
  2. 将此纹理传递给新 SurfaceTexture 的构造函数。
  3. 将这个新的 SurfaceTexture 赋予相机。
  4. 确保您使用的是 OES_External(有关详细信息,请参阅文档)。

但是,创建 OpenGL 纹理(如答案的步骤 1 所示)需要EGL 上下文,这需要将 EGLSurface 设为当前,这需要 SurfaceTexture。似乎创建 EGL 上下文的唯一方法是创建一个 SurfaceView(或另一个具有 SurfaceTexture 的视图),并使用它来初始化 EGLSurface,然后使 EGLContext 成为当前的。

我的目标是创建一个 EGLContext 并使其在后台线程中成为当前的,对相机预览图像进行一些屏幕外计算(主要使用 NDK)。我想创建一个库,并使其尽可能独立于 UI。两个相关问题:

在 Java 方面,是否可以在没有预先创建 SurfaceTexture 的情况下创建 EGLContext?

在 NDK 方面,曾经有一个私有 API 调用来创建本机 windows android_createDisplaySurface(),但它不再起作用了,而且,它是一个私有 API。有什么方法可以用 NDK 创建表面吗?

我对使用 EGL 还是很陌生,我不明白为什么需要 EGLSurface 才能使 EGLContext 成为最新。在 iOS 中,可以先创建 EAGLContexts,然后根据需要创建 framebuffers。使用 EGL,您似乎总是需要一个本机窗口。

4

1 回答 1

8

您可以在 Grafika 中看到许多操纵相机输出、SurfaceTexture 和 EGL 的示例。“连续捕获”活动就是其中之一,但它使用了您提到的技术:为了避免创建 EGLSurface,它只是从附近的 SurfaceView 借用了一个。

您确实需要一个 EGLSurface,但它不需要是一个窗口表面。您可以创建一个 1x1 pbuffer 表面并使用它。这是通过eglCreatePbufferSurface()调用完成的;例如,请参阅 Grafika 中的 EglCore 类。

这些示例是用 Java 编写的,但 Java 实现只是包装了本机 EGL/GLES 调用。

android_createDisplaySurface()是一个内部调用,正如您所发现的,它不适用于较新的设备。而是在 NDK 中搜索ANativeWindow

更新:对于通过搜索到达这里的任何人,android_createDisplaySurface()依赖于一个名为 的内部类,在此更改FramebufferNativeWindow中,该类在 Android 5.0 中被标记为已过时。在此更改中,使用它的内部 OpenGL ES 测试代码已更新为基于 SurfaceFlinger 的替换。测试代码的原始版本需要关闭 Android 应用程序框架,以便它可以获取帧缓冲区;较新的版本只是要求 SurfaceFlinger 提供一个覆盖屏幕并合成在其他所有内容之上的窗口。

于 2014-04-30T05:21:05.723 回答