我正在 Android 和 native C++ 中使用 EGL 1.1 为 android 实现场景绘制。
当前使用 Android 的 glSurfaceView
- 当后台缓冲区和前台缓冲区交换时,它允许我绘制到显示在“onDrawFrame”末尾的后台缓冲区。
我的问题是:我需要能够显示后台缓冲区并继续写入,就好像我没有交换一样。这种需求背后的原因是场景非常大,不可能每一帧都构建它,也不可能等待绘图结束 - 因为用户将不得不等待太久。
换句话说 - 我需要增量构建场景。
在渲染过程中的某个时刻,我决定是时候调用 eglSwapBuffers
来显示后台缓冲区中绘制的内容,但是当我继续写入时,显然我正在写入“前者” -front-buffer' 不同步..(不包含我目前绘制的内容)。
据我所知,我唯一的选择是在交换之前复制后台缓冲区。伪:
- 绘制到后台缓冲区
- 复制后台缓冲区到临时缓冲区
- 交换
- 复制临时缓冲区到(新的)后台缓冲区
- 绘制更多东西到后台缓冲区
- 等等...
有办法完成第 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
可用:
- 绘制到纹理或用户定义的渲染缓冲区
- 将纹理渲染到 BACK 缓冲区/blit 渲染缓冲区到 BACK 缓冲区
- 交换
- 更新纹理/渲染缓冲区
- 将纹理渲染到 BACK 缓冲区/blit 渲染缓冲区到 BACK 缓冲区
- 交换
- [...等等...]
这样一来,您就没有每帧 2 个拷贝的复制/更新/复制/交换循环,而只有一个额外拷贝的更新/复制/交换。
关于android - 在 eglSwapBuffers 之后保留后台缓冲区内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23928737/