对于仅渲染到FBO的上下文,eglMakeCurrent使用什么Surface

Pon*_*don 6 c++ android ios opengl-es-2.0 egl

我遇到以下情况:

在iOS和Android的跨平台渲染库中(用c(++)编写),我有两个线程,每个线程都需要自己的EGLContext:线程A是主线程; 它渲染到窗口.线程B是一个生成器线程,它执行各种计算并将结果呈现为稍后由线程A使用的纹理.

由于我不能在iOS上使用EGL,因此库使用静态Obj.-C函数的函数指针来创建新的上下文并将其设置为当前.这已经有效,我为线程A使用创建上下文

EAGLContext *contextA = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
Run Code Online (Sandbox Code Playgroud)

线程B的上下文是使用创建的

EAGLContext *contextB = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[contextA sharegroup]];
Run Code Online (Sandbox Code Playgroud)

然后我可以设置两个电流中的任何一个:

[EAGLContext setCurrentContext:context];
Run Code Online (Sandbox Code Playgroud)

要在Android上使用相同的逻辑(传递给库的函数指针),我想在JNI绑定的C端执行此操作,这次使用真实的EGL而不是Apple的EAGL.我可以使用WindowSurface和本机Window轻松创建contextA,我可以创建contextB并将contextA传递给eglCreateContext调用的shareContext参数.

但是当我想使contextB成为当前时,我必须将表面传递给eglMakeCurrent调用,并且我试图弄清楚要在那里传递什么样的表面.

  • 我不能使用我用于contextA的WindowSurface,因为规范在3.7节中说"每个支持的客户端API的最多一个上下文可能在给定时间对特定线程是最新的,并且最多一个上下文可能绑定到特定的在给定时间表面."
  • 我无法指定EGL_NO_SURFACE,因为这会导致eglMakeCurrent调用中出现EGL_BAD_MATCH错误.
  • 我似乎可以使用PBuffer表面,但我犹豫不决,因为我必须在创建这样的表面时指定宽度和高度,而线程B可能想要创建不同大小的纹理.除此之外,Munshi,Ginsburg和Shreiner 的"OpenGL ES 2.0编程指南"在第3.8节中指出"Pbuffers最常用于生成纹理贴图.如果您想要做的就是渲染纹理,我们建议使用framebuffer对象[...]而不是pbuffers,因为它们更有效",这正是我想要在线程B中做的.

我不明白Munshi,Ginsurg和Shreiner的意思是什么,帧缓冲对象如何替代pbuffer表面?如果我创建一个非常小的(例如1x1px)pbuffer表面以使上下文变为当前状态,那么我仍可以渲染成任意大的FBO吗?还有其他我不知道的可能性吗?

非常感谢你的帮助!

Pon*_*don 3

我最终使用了 PBuffer 表面(大小为 1x1) - 然后我创建了一个 FBO 并渲染成纹理就好了。为了显示它们(在不同的线程和不同的(共享)opengl 上下文中),我使用带有 ANativeWindow 的 windowsurface (sdk 中的某处有一个示例)。