2016-08-07 53 views
2

Ich schreibe ein Spiel für Android mit libgdx. Wenn der Benutzer das Pausenmenü öffnet, mache ich einen Screenshot des aktuellen Spiels, verwische es und verwende es als Hintergrund für das Optionsmenü. Dies funktioniert gut, aber der Code für den Screenshot ist sehr langsam. Es dauert etwa 0,8 Sekunden im Durchschnitt mit dem folgenden Code ...Java Libgdx bekommen Screenshot sehr langsam

Gibt es eine andere Möglichkeit, einen Screenshot in libgdx zu machen, die viel schneller ist? Wenn nicht, wenn der Benutzer das Optionsmenü öffnet, könnte ich versuchen, einfach das Spiel zu rendern, die Spiellogik anzuhalten und den Bildschirm zu verwischen und die Optionen oben zu zeichnen .. Wenn das der einzige schnelle Weg ist, wie könnte man verwischen der Bildschirm? Ich habe this link gefunden, aber ich habe es nicht zum Laufen gebracht. Wenn es möglich ist, ziehe ich die Lösung mit dem Screenshot, weil es viel einfacher ...

ist

-Code den Screenshot zu erhalten (von 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; 
} 

ich die resultierenden Pixmap verwende meine Textur zu zeichnen .

EDIT:

Mein Code jetzt mit der Antwort von Deniz Yilmaz für das Erhalten des Screenshot schnell:

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; 
} 
+0

Zeichnen Sie Ihre Szene zu einem FrameBuffer und verwenden Sie diese. – Tenfour04

+0

@ Tenfour04 könnten Sie etwas genauer sein? Ich würde gerne eine klare und gründliche Antwort sehen, die eine bessere Möglichkeit beschreibt, einen Screenshot als die Dokumentation zu erstellen. – Madmenyo

+0

@ Tenfour04 Danke, kannst du ein kurzes Beispiel geben, wie man (eine Textur?) Zu einem Framebuffer zeichnet und (mit einem Shader ??) es unscharf macht? – trinity420

Antwort

2

Eigentlich nimmt Screenshot ist nicht langsam. Langsamer Teil ist die Datenübertragung zwischen GPU und CPU, also wird jede andere Möglichkeit, Pixel zu bekommen, nicht so schnell sein.

Aber auch hier helfen openGl-Codes. Sie können OpenGL-Codes über die Gdx.gl-Klasse verwenden.

Diese Funktion kopiert Pixel in ein 2D-Texturbild, bringt sie aber nicht zur CPU. Sie gehören nur ein FBO bei GPU. In libgdx müssen Sie zuerst die Textur an die Textur von openGl mit einer Methode binden. Diese Textur kann leere Bildschirmgröße Textur sein oder Sie können alte Textur verwenden Sie nicht wieder verwenden.

Texture.bind(); 

oder

Gdx.gl.glBindTexture(Opengltexture, texture.getTextureObjectHandle()); 

zur Begrenzung und unter Bildschirm

  1. GPUtexture Typ aktivieren.
  2. Aktivieren für genaue GPUtexture
  3. Aufruf Textur bind-Methode
  4. Anruf opengl Funktion für aktive GPUtexture
  5. Disable GPUtexture Typ. Hier

ist, was Code wie folgt aussehen:

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

bewusst verbindlich ist nur aktiv, in 1 und 5. Mein Fehler war hier, weil ich versuchte, Textur zu binden in der Methode erstellen und hatte schwarzen Bildschirm einsehen.

BEACHTEN SIE !!!

  • Auf Android benötigt es Opengles 2.0. Sie können das Manifest bearbeiten, um sicherzustellen, dass nicht unterstützte Geräte Ihr Spiel nicht herunterladen können.

    < verwendet-Funktion android: glEsVersion = "0x00020000" android: required = "true">

  • RGBA-Format Farbraum doesnt unterstützt. Stellen Sie also sicher, dass Sie mit Format.RGB für OpenGL-Funktion und Textur erstellen.

  • Ergebnis Textur wird vertikal wegen openGl Matrix System gekippt werden. Also müssen Sie es manuell beheben.

Ich empfehle Ihnen auch, Fragmente und Shader zu betrachten. Es scheint hart, aber tatsächlich angenehm.

+0

Vielen Dank !! Das bedeutet, dass 'Texture.bind()' nimmt einen Screenshot, der ho ist ld in der GPU? Haben Sie ein kurzes Beispiel, wie Sie einen Weichzeichnungsfilter auf diese Textur anwenden können? Ich habe eine leere Textur in der Bildschirmgröße erstellt und '' genannt.bind() 'und zeichne es, aber das Ergebnis war nur ein weißer Bildschirm anstelle eines Screenshots ...? – trinity420

+0

Nein, du hast mich nicht verstanden. Ich werde versuchen zu erklären, aber ich bin kein Experte auf opengl. Zuerst nehme ich an, dass Sie über GPU wissen. Sein Grafikprozessor speichert alle Daten über Ihre Sprites. Wenn Sie eine Textur-CPU zeichnen, die Texturdaten an GPU und GPU sendet, zeichnen Sie diese. Wenn Sie eine Textur an OpenGL-Textur binden. Öffnen Sie Ihre Texturdaten mit einem Adresswert. Sie können diese Adresse in libgdx über GL20 wie GL20.GL_TEXTURE0 aufrufen. Wenn Sie eine gebundene Textur in der GPU haben, können Sie jetzt openGl-Funktionen verwenden. –

+0

Vielleicht können Sie diesen Link sehen https://open.gl/textures Es kann für opengl Teil nützlich sein. Sie können OpenGL-Funktionen über die Gdx.gl-Klasse verwenden. Gdx.gl.anyopenglunction like. –