package net.fourbytes.shadow.utils; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.PixmapIO; import com.badlogic.gdx.utils.BufferUtils; import net.fourbytes.shadow.Shadow; import java.nio.ByteBuffer; public final class ScreenshotUtil { private ScreenshotUtil() { } private static byte[][] datas = new byte[32][]; private static int indexData = 0; private static byte[] getData(int length) { byte[] data = datas[indexData]; if (data == null || data.length != length) { data = new byte[length]; datas[indexData] = data; } indexData++; if (indexData >= datas.length) { indexData = 0; } return data; } private static ByteBuffer[] pixelBuffers = new ByteBuffer[32]; private static int indexPixelBuffer = 0; private static ByteBuffer getPixelBuffer(int capacity) { ByteBuffer pixels = pixelBuffers[indexPixelBuffer]; if (pixels == null || pixels.capacity() != capacity) { pixels = BufferUtils.newByteBuffer(capacity); pixelBuffers[indexPixelBuffer] = pixels; } indexPixelBuffer++; if (indexPixelBuffer >= pixelBuffers.length) { indexPixelBuffer = 0; } return pixels; } public static byte[] getScreenData(int x, int y, int w, int h) { Gdx.gl.glPixelStorei(GL20.GL_PACK_ALIGNMENT, 1); int numBytes = w * h * 3; ByteBuffer pixels = getPixelBuffer(numBytes); Gdx.gl.glReadPixels(x, y, w, h, GL20.GL_RGB, GL20.GL_UNSIGNED_BYTE, pixels); byte[] data = getData(numBytes); pixels.clear(); pixels.get(data); return data; } private static Pixmap[] pixmaps = new Pixmap[32]; private static int indexPixmap = 0; private static Pixmap getPixmap(int w, int h) { Pixmap pixmap = pixmaps[indexPixmap]; if (pixmap == null || (pixmap.getWidth() != w || pixmap.getHeight() != h)) { if (pixmap != null) { pixmap.dispose(); } pixmap = new Pixmap(w, h, Pixmap.Format.RGB888); pixmaps[indexPixmap] = pixmap; } indexPixmap++; if (indexPixmap >= pixmaps.length) { indexPixmap = 0; } return pixmap; } public static void fillPixmap(Pixmap pixmap, byte[] data) { int w = pixmap.getWidth(); int h = pixmap.getHeight(); int x = 0; int y = h-1; for (int i = 0; i < data.length; i += 3) { byte r = data[i]; byte g = data[i+1]; byte b = data[i+2]; pixmap.setColor((r & 0xFF) / 255f, (g & 0xFF) / 255f, (b & 0xFF) / 255f, 1f); pixmap.drawPixel(x, y); x++; if (x >= w) { y--; x = 0; } } } public static void frameSave() { frameSave(Shadow.getDir("screenshots").child("screen_"+Garbage.dateCurrent()+".png")); } public static void frameSave(final FileHandle fh) { final int w = (int) Shadow.dispw; final int h = (int) Shadow.disph; final byte[] data = getScreenData(0, 0, w, h); Thread thread = new Thread("Screenshot_"+Shadow.rand.nextInt(1024)) { @Override public void run() { Pixmap pixmap = getPixmap(w, h); fillPixmap(pixmap, data); fh.parent().mkdirs(); PixmapIO.writePNG(fh, pixmap); } }; thread.start(); } public static int tick = 0; public static int speed = 2; public static int frame = 0; public static void frameRecord() { if (tick < speed-1) { tick++; return; } tick = 0; frame++; frameSave(Shadow.getDir("gifs").child(Shadow.recordDirName).child("screen_"+frame+".png")); } public static void framesPull() { frame = 0; //TODO Bind all PNGs into one GIF } }