Java Libgdx获取屏幕截图的速度非常慢
我使用libgdx为android编写了一个游戏。如果用户打开暂停菜单,我会拍摄当前游戏的屏幕截图,模糊它并将其用作选项菜单的背景。这很好,但是获取屏幕截图的代码非常慢。使用下面的代码平均需要0.8秒左右 在libgdx中有没有其他更快的截图方法? 如果没有,当用户打开选项菜单时,我可以尝试继续渲染游戏,暂停游戏逻辑,模糊屏幕并在顶部绘制选项。。如果这是唯一快速的方法,怎么能模糊屏幕?我找到了,但没能用。 如果可能的话,我更喜欢屏幕截图的解决方案,因为它更容易 获取屏幕截图的代码(从): 我使用生成的像素贴图绘制纹理 编辑: 我的代码现在是Deniz Yılmaz的答案,用于快速获取屏幕截图:Java Libgdx获取屏幕截图的速度非常慢,java,android,performance,libgdx,screenshot,Java,Android,Performance,Libgdx,Screenshot,我使用libgdx为android编写了一个游戏。如果用户打开暂停菜单,我会拍摄当前游戏的屏幕截图,模糊它并将其用作选项菜单的背景。这很好,但是获取屏幕截图的代码非常慢。使用下面的代码平均需要0.8秒左右 在libgdx中有没有其他更快的截图方法? 如果没有,当用户打开选项菜单时,我可以尝试继续渲染游戏,暂停游戏逻辑,模糊屏幕并在顶部绘制选项。。如果这是唯一快速的方法,怎么能模糊屏幕?我找到了,但没能用。 如果可能的话,我更喜欢屏幕截图的解决方案,因为它更容易 获取屏幕截图的代码(从): 我使用
public Texture getScreenshot(){
Texture texture = new Texture(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Pixmap.Format.RGB888);
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D);
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
texture.bind();
Gdx.gl.glCopyTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGB, 0, 0,Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 0);
Gdx.gl.glDisable(GL20.GL_TEXTURE_2D);
return texture;
}
其实截图并不慢。 慢的部分是GPU和CPU之间的数据传输,所以任何其他获取像素的方法都不会快那么多 但这里也有openGl代码帮助我们。 您可以通过Gdx.gl类使用opengl代码
void glCopyTexImage2D(
GLenum target, //Target Opengl Texture
GLint level, //Mipmap level
GLenum internalformat, //Color format
GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLint border);
此函数用于将像素复制到2D纹理图像中,但不将其带到CPU。
你只是GPU的FBO。
在libgdx中,首先必须使用方法将纹理绑定到openGl的纹理。
此纹理可以是空屏幕大小的纹理,也可以使用不再使用的旧纹理
Texture.bind();
或
用于跳转和拍摄屏幕
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D);
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
texture.bind();
Gdx.gl.glCopyTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA,0, 0,width , height, 0);
Gdx.gl.glDisable(GL20.GL_TEXTURE_2D);
请注意,绑定仅在1和5中处于活动状态。我的错就在这里,因为我试图在创建方法中绑定纹理,结果得到了黑屏
注意强>
- 在android上,它需要opengl es 2.0。您可以编辑清单,以确保不受支持的设备无法下载您的游戏。
- 不支持RGBA格式的颜色空间。所以要确保你是 将Format.RGB用于opengl函数和纹理创建
- 由于openGl矩阵,结果纹理将垂直翻转 系统。因此,您必须手动修复它
这看起来很难,但实际上很有趣 将场景绘制到帧缓冲区并使用它。@Tenfour04您能说得更具体一点吗?我很想看到一个清晰而彻底的答案,它描述了一种比文档更好的制作屏幕截图的方法。@Tenfour04谢谢,您可以提供一个简短的示例,说明如何将(纹理?)绘制到帧缓冲区和(使用着色器??)为了模糊它?我在桌面上测试,所以它可以工作,但在安卓系统中,我和你们一样得到了白色屏幕,但我也解决了这个问题。我在gl和纹理创建中使用RGB颜色而不是RGBA。Format.RGB888 GL20.GL_RGB,它在android上也适用于我。但有些手机GPU需要2个大小的纹理。我的zenfone 2在没有它的情况下工作了。@DenizYılmaz我没有让着色器工作,但是非常感谢您的帮助!至少我原来的问题解决了!PS:我有模糊像素贴图的工作代码,但无法让它与我们的纹理一起工作…谢谢!!这意味着
Texture.bind()
拍摄了一个在GPU中保留的屏幕截图?你有一个简短的例子如何应用模糊过滤器这个纹理?我创建了一个屏幕大小的空纹理,并调用.bind()
绘制它,但结果只是一个白色屏幕而不是屏幕截图…?不,你理解错了。我会尽力解释,但我不是opengl的专家。首先,我假设您了解GPU。它的图形处理器保存有关精灵的所有数据。绘制纹理时,CPU将纹理数据发送到GPU并由GPU绘制。将纹理绑定到opengl纹理时。Opengl使用adress值存储纹理数据。您可以通过GL20在libgdx中调用此地址,如GL20.GL_TEXTURE0。当你在GPU中有一个绑定的纹理时,现在你可以使用openGl函数了。也许你可以看看这个链接,它对openGl部分很有用。您可以通过Gdx.gl类使用opengl函数。我的代码是:Gdx.gl.glCopyTexImage2D(Gdx.gl20.gl_TEXTURE0,0,Gdx.gl.gl_RGB,0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),0)代码>但它仍然只显示一个白色屏幕。。。这是正确的吗?我可以把它放在渲染方法中吗?谢谢!!我用你的答案编辑了我的帖子,你能检查一下这是否正确吗?当我画出最终的纹理时,我仍然得到一个白色的屏幕。。。?
Gdx.gl.glBindTexture(Opengltexture, texture.getTextureObjectHandle());
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D);
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
texture.bind();
Gdx.gl.glCopyTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA,0, 0,width , height, 0);
Gdx.gl.glDisable(GL20.GL_TEXTURE_2D);