Java Libgdx获取截图非常慢

时间:2016-08-07 20:03:41

标签: java android performance libgdx screenshot

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

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

获取屏幕截图的代码(来自official wiki):

public static Pixmap getScreenshot(){
    long start = TimeUtils.millis();

    byte[] pixels = ScreenUtils.getFrameBufferPixels(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);
    Pixmap pixmap = new Pixmap(Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), Pixmap.Format.RGBA8888);
    BufferUtils.copy(pixels, 0, pixmap.getPixels(), pixels.length);

    long time = TimeUtils.millis()-start;
    Gdx.app.log("INFO", "Time for screenshot in sec.: " + time);  // about 0.8 seconds

    return pixmap;
}

我使用生成的Pixmap来绘制纹理。

修改

我的代码现在使用DenizYı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;
}

1 个答案:

答案 0 :(得分:3)

实际拍摄截图并不慢。 慢速部分是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.glBindTexture(Opengltexture, texture.getTextureObjectHandle());

用于边界和拍摄屏幕

  1. 启用GPUtexture类型。
  2. 激活精确的GPUtexture
  3. 调用纹理绑定方法
  4. 调用有效GPUtexture的opengl函数
  5. 禁用GPUtexture类型。
  6. 以下是代码:

    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中有效。我的错是在这里,因为我试图在create方法中绑定纹理并且有黑屏。

    BE AWARE !!!

    • 在android上,它需要opengl es 2.0。您可以编辑清单以确保不受支持的设备无法下载您的游戏。
        

      < uses-feature android:glEsVersion =" 0x00020000"   机器人:需要="真" >

    • 不支持RGBA格式颜色空间。所以一定要确保你 使用Format.RGB进行opengl函数和纹理创建。

    • 由于openGl矩阵,结果纹理将垂直翻转 系统。所以你必须手动修复它。

    我还建议您查看片段和着色器。 看起来很难但实际上很有乐趣。