Opengl getFrameBufferPixels在libgdx中占用的时间太长

Opengl getFrameBufferPixels在libgdx中占用的时间太长,opengl,libgdx,Opengl,Libgdx,我基本上是在尝试使用默认的帧缓冲区pixmap。当有人暂停游戏时,我希望模糊它。我的问题是,即使我对整个模糊操作使用单独的线程,也必须在渲染线程上调用ScreenUtils.getFrameBufferPixmap方法。但即使在Nexus5上,此方法也至少需要1秒才能返回。在我的模糊处理线程上调用该方法是不可能的,因为除了渲染线程之外,任何其他线程上都没有可用的gl上下文 是否有任何解决方案可以消除暂停?您正在尝试做的是:拍摄一个屏幕截图,在CPU上修改它,然后将其上传回GPU。这种方法有三个问

我基本上是在尝试使用默认的帧缓冲区pixmap。当有人暂停游戏时,我希望模糊它。我的问题是,即使我对整个模糊操作使用单独的线程,也必须在渲染线程上调用ScreenUtils.getFrameBufferPixmap方法。但即使在Nexus5上,此方法也至少需要1秒才能返回。在我的模糊处理线程上调用该方法是不可能的,因为除了渲染线程之外,任何其他线程上都没有可用的gl上下文


是否有任何解决方案可以消除暂停?您正在尝试做的是:拍摄一个屏幕截图,在CPU上修改它,然后将其上传回GPU。这种方法有三个问题。 1.抓取像素,需要很多时间。 2.模糊可以独立地为每个像素成功执行,因此在CPU上执行模糊没有任何意义。GPU可以在一眨眼之间做到这一点。 3.上传纹理回来仍然需要一些时间

正确的方法是:不将所有内容渲染到屏幕,而是将其渲染到屏幕外纹理。(请参见屏幕外渲染教程)接下来,在屏幕大小的四边形上绘制此纹理,但在绘制时,请使用模糊着色器。有许多示例模糊着色器可用。它基本上应该对目标像素的周围环境进行采样并渲染其平均值。

在中,您可以看到
getFrameBufferPixmap
基本上是一个包装器。要改进Java或Libgdx包装器,您可以做的不多。这不是OpenGL优化的方向(它擅长将数据推送到GPU,而不是从GPU中提取数据)

您最好将当前屏幕重新渲染为一个(更小、离屏)帧缓冲区,然后将其向下拉。你也可以用GPU以这种方式进行模糊处理

我相信屏幕的格式(例如,不是RGBA8888)可能会对读取性能产生影响


这不是特定于Libgdx的,因此任何关于OpenGL的提示或建议都应该适用。

你没有明白我的意思。我不想实时模糊,因为我只是想在游戏暂停时显示一个静止的背景。另外,我想生成一个lerp模糊(这里描述了ios plus中使用的效果:。@Rahul Verma:我明白你的意思。我的意思是:抓取输出像素太慢,无法平稳运行。如果你坚持,尝试使用其他方法读取它们,但无论如何都会很慢。你不想实时模糊吗?太好了!按我说的做一次,当按下暂停时。记录模糊当暂停处于活动状态时,将其作为静态图像使用。无需再应用模糊。如果您希望模糊在一段时间内变得更强,您仍然可以使用此方法轻松实现。而且速度会非常快。您的建议似乎是正确的,事实上,对于随着时间推移而增强的模糊问题,我可以使用mix()bw实际像素和模糊像素,并逐渐将模糊像素的权重增加到最大值。但是,你会看到,软件(java代码)中的模糊可以轻松地异步执行。毫无疑问,使用着色器进行模糊将快速减轻,但它肯定不会在较旧的设备上滞后吗(功能较弱的GPU)?无论如何,它肯定会比从GPU上提取像素值要慢。模糊操作本身应该无缝执行。我不知道功能较弱的GPU处理多个过程的效果如何,但正如你所说的,功能较弱的GPU在下载/上传像素时不会表现得更好。我相信这种方法值得一试t、 它应该比在CPU上的单独线程中执行要快得多。如果我的回答帮助您解决了这个问题,请接受它;)