6

我正在 Android 和原生 C++ 中使用egl 1.1. 当前使用android的glSurfaceView-它允许我绘制到显示在“onDrawFrame”末尾的后缓冲区-当后缓冲区和前缓冲区被交换时。

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

换句话说 - 我需要逐步构建场景。在渲染过程中的某个时刻,我决定是时候了,我调用eglSwapBuffers它来显示来自后台缓冲区的绘制内容,但是当我继续写入时,显然我正在写入不同步的“前前缓冲区”。 .(不包含我到目前为止画的东西)。

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

  1. 绘制到后台缓冲区
  2. 缓冲区复制到临时缓冲区
  3. 交换
  4. 临时缓冲区复制到(新的)后台缓冲区
  5. 绘制更多的东西到后台缓冲区
  6. 等等...

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

  • glCopyPixels在这种情况下有用吗?例子?
  • glBlitFramebuffer吗?

还是我接近这一切都错了?

我已经做过的事情:

  • 我尝试设置EGL_SWAP_BEHAVIOR为,EGL_BUFFER_PRESERVED但它似乎只适用于某些设备(如khronos 注释中所述):

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

  • 在每一帧中重新渲染场景 - 不可能。我读过很多次,这是推荐的。
4

1 回答 1

3

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

但是,我可以想到一种可能更好的方法,至少在OES_framebuffer_object可用的情况下:

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

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

于 2014-05-29T12:05:02.780 回答