在eglSwapBuffers之后保留后台缓冲区内容

Dro*_*man 6 android opengl-es double-buffering egl

我正在Android和原生C++中实现一个用于Android的场景绘图egl 1.1.目前正在使用android's glSurfaceView- 它允许我绘制一个后台缓冲区,它显示在"onDrawFrame"的末尾 - 当后台缓冲区和前台缓冲区交换时.

我的问题是这个 - 我需要能够显示后台缓冲区并继续写入,就像我没有交换一样.这种需求背后的原因是场景非常大,并且每帧构建它是不可能的,也不等待绘图的结束 - 因为用户将不得不等待太长时间.

换句话说-我需要建立现场递增.在渲染过程中的某个时刻,我决定它的时间,我调用eglSwapBuffers哪个显示从后台缓冲区中绘制的内容,但是当我继续写入时,显然我正在写入不同步的"前前缓冲区". (不包含我到目前为止所绘制的内容).

据我所知,我唯一的选择是在交换之前复制后台缓冲区.伪:

  1. 画回到缓冲区
  2. Back Buffer 复制到temp Buffer
  3. 交换
  4. 临时缓冲区复制到(新)后台缓冲区
  5. 在缓冲区中绘制更多内容
  6. 等等...

我的问题 - 有没有办法做2,4步骤?

  • 就是glCopyPixels在这种情况下,有用吗?例?
  • glBlitFramebuffer吗?

或者我接近这一切都错了?

我已经做过的事情:

  • 我试着设置EGL_SWAP_BEHAVIOREGL_BUFFER_PRESERVED,但它似乎只在某些设备上(如在描述工作Khronos的笔记):

某些表面允许应用程序控制是否保留颜色缓冲区内容

  • 在每个帧中重新渲染场景 - 不可能.我已多次读到这是推荐的.

der*_*ass 3

您的总体方法是正确的。使用glBlitFramebuffer()可能会更有帮助,因为glCopyPixels只需将缓冲区的某些子矩形复制到同一缓冲区中的另一个位置。

但是,我可以想到一种可能更好的方法,至少如果OES_framebuffer_object可用的话:

  1. 绘制到纹理或用户定义的渲染缓冲区
  2. 将纹理渲染到 BACK 缓冲区/blit 渲染缓冲区到 BACK 缓冲区
  3. 交换
  4. 更新纹理/渲染缓冲区
  5. 将纹理渲染到 BACK 缓冲区/blit 渲染缓冲区到 BACK 缓冲区
  6. 交换
  7. [... 等等 ...]

这样,您就没有每帧 2 个副本的复制/更新/复制/交换周期,而只有一个额外副本的更新/复制/交换。