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

标签 android c++ opengl-es egl double-buffering

我正在 Android 和 native C++ 中使用 EGL 1.1 为 android 实现场景绘制。

当前使用 Android 的 glSurfaceView - 当后台缓冲区和前台缓冲区交换时,它允许我绘制到显示在“onDrawFrame”末尾的后台缓冲区。

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

换句话说 - 我需要增量构建场景。

在渲染过程中的某个时刻,我决定是时候调用 eglSwapBuffers 来显示后台缓冲区中绘制的内容,但是当我继续写入时,显然我正在写入“前者” -front-buffer' 不同步..(不包含我目前绘制的内容)。

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

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

有办法完成第 2、4 步吗?

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

还是我的做法全错了?

我已经做过的事情:

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

    Some surfaces allow applications to control whether or not the color buffer contents are preserved

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

最佳答案

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

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

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

这样一来,您就没有每帧 2 个拷贝的复制/更新/复制/交换循环,而只有一个额外拷贝的更新/复制/交换。

关于android - 在 eglSwapBuffers 之后保留后台缓冲区内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23928737/

相关文章:

java - 在列表中添加来自 firebase 的对象的问题

java - 如何检查圆的边是否要绘制在手机之外

c++ - 什么 shared_ptr 策略用于异步方案?

c++ - 在 C++ 中逐行读取并从行中获取单词

C++ 排序 : ranking list with same value of an array

iphone - 有关如何实现平滑绘画笔触(如 Penultimate 应用程序中所示)的示例代码

android - startUsingNetworkFeature 和 requestRouteToHost Depreciated 在 6.0 替代这个

android自定义通知不适用于约束布局

Android MediaMuxer 将表面附加到编解码器输入

Android OpenGL 只渲染一半的屏幕