Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Libgdx获取屏幕截图的速度非常慢_Java_Android_Performance_Libgdx_Screenshot - Fatal编程技术网

Java Libgdx获取屏幕截图的速度非常慢

Java Libgdx获取屏幕截图的速度非常慢,java,android,performance,libgdx,screenshot,Java,Android,Performance,Libgdx,Screenshot,我使用libgdx为android编写了一个游戏。如果用户打开暂停菜单,我会拍摄当前游戏的屏幕截图,模糊它并将其用作选项菜单的背景。这很好,但是获取屏幕截图的代码非常慢。使用下面的代码平均需要0.8秒左右 在libgdx中有没有其他更快的截图方法? 如果没有,当用户打开选项菜单时,我可以尝试继续渲染游戏,暂停游戏逻辑,模糊屏幕并在顶部绘制选项。。如果这是唯一快速的方法,怎么能模糊屏幕?我找到了,但没能用。 如果可能的话,我更喜欢屏幕截图的解决方案,因为它更容易 获取屏幕截图的代码(从): 我使用

我使用libgdx为android编写了一个游戏。如果用户打开暂停菜单,我会拍摄当前游戏的屏幕截图,模糊它并将其用作选项菜单的背景。这很好,但是获取屏幕截图的代码非常慢。使用下面的代码平均需要0.8秒左右

在libgdx中有没有其他更快的截图方法? 如果没有,当用户打开选项菜单时,我可以尝试继续渲染游戏,暂停游戏逻辑,模糊屏幕并在顶部绘制选项。。如果这是唯一快速的方法,怎么能模糊屏幕?我找到了,但没能用。 如果可能的话,我更喜欢屏幕截图的解决方案,因为它更容易

获取屏幕截图的代码(从):

我使用生成的像素贴图绘制纹理

编辑:

我的代码现在是Deniz Yılmaz的答案,用于快速获取屏幕截图:

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();

用于跳转和拍摄屏幕

  • 启用GPUtexture类型
  • 激活以获得精确的GPUtexture
  • 调用纹理绑定方法
  • 为活动GPUtexture调用opengl函数
  • 禁用GPUtexture类型
  • 下面是代码的样子:

    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);