|
|
@@ -1,148 +1,158 @@
|
|
|
-package com.jme3.app.state;
|
|
|
-
|
|
|
-import com.jme3.app.Application;
|
|
|
-import com.jme3.input.InputManager;
|
|
|
-import com.jme3.input.KeyInput;
|
|
|
-import com.jme3.input.controls.ActionListener;
|
|
|
-import com.jme3.input.controls.KeyTrigger;
|
|
|
-import com.jme3.post.SceneProcessor;
|
|
|
-import com.jme3.renderer.RenderManager;
|
|
|
-import com.jme3.renderer.Renderer;
|
|
|
-import com.jme3.renderer.ViewPort;
|
|
|
-import com.jme3.renderer.queue.RenderQueue;
|
|
|
-import com.jme3.system.JmeSystem;
|
|
|
-import com.jme3.texture.FrameBuffer;
|
|
|
-import com.jme3.util.BufferUtils;
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.OutputStream;
|
|
|
-import java.nio.ByteBuffer;
|
|
|
-import java.util.List;
|
|
|
-import java.util.logging.Level;
|
|
|
-import java.util.logging.Logger;
|
|
|
-
|
|
|
-public class ScreenshotAppState extends AbstractAppState implements ActionListener, SceneProcessor {
|
|
|
-
|
|
|
- private static final Logger logger = Logger.getLogger(ScreenshotAppState.class.getName());
|
|
|
- private String filePath = null;
|
|
|
- private boolean capture = false;
|
|
|
- private Renderer renderer;
|
|
|
- private ByteBuffer outBuf;
|
|
|
- private String appName;
|
|
|
- private int shotIndex = 0;
|
|
|
- private int width, height;
|
|
|
-
|
|
|
- /**
|
|
|
- * Using this constructor, the screenshot files will be written sequentially to the system
|
|
|
- * default storage folder.
|
|
|
- */
|
|
|
- public ScreenshotAppState() {
|
|
|
- this(null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This constructor allows you to specify the output file path of the screenshot.
|
|
|
- * Include the seperator at the end of the path.
|
|
|
- * Use an emptry string to use the application folder. Use NULL to use the system
|
|
|
- * default storage folder.
|
|
|
- * @param file The screenshot file path to use. Include the seperator at the end of the path.
|
|
|
- */
|
|
|
- public ScreenshotAppState(String filePath) {
|
|
|
- this.filePath = filePath;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the file path to store the screenshot.
|
|
|
- * Include the seperator at the end of the path.
|
|
|
- * Use an emptry string to use the application folder. Use NULL to use the system
|
|
|
- * default storage folder.
|
|
|
- * @param file File path to use to store the screenshot. Include the seperator at the end of the path.
|
|
|
- */
|
|
|
- public void setFilePath(String filePath) {
|
|
|
- this.filePath = filePath;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void initialize(AppStateManager stateManager, Application app) {
|
|
|
- if (!super.isInitialized()){
|
|
|
- InputManager inputManager = app.getInputManager();
|
|
|
- inputManager.addMapping("ScreenShot", new KeyTrigger(KeyInput.KEY_SYSRQ));
|
|
|
- inputManager.addListener(this, "ScreenShot");
|
|
|
-
|
|
|
- List<ViewPort> vps = app.getRenderManager().getPostViews();
|
|
|
- ViewPort last = vps.get(vps.size()-1);
|
|
|
- last.addProcessor(this);
|
|
|
-
|
|
|
- appName = app.getClass().getSimpleName();
|
|
|
- }
|
|
|
-
|
|
|
- super.initialize(stateManager, app);
|
|
|
- }
|
|
|
-
|
|
|
- public void onAction(String name, boolean value, float tpf) {
|
|
|
- if (value){
|
|
|
- capture = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void takeScreenshot() {
|
|
|
- capture = true;
|
|
|
- }
|
|
|
-
|
|
|
- public void initialize(RenderManager rm, ViewPort vp) {
|
|
|
- renderer = rm.getRenderer();
|
|
|
- reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean isInitialized() {
|
|
|
- return super.isInitialized() && renderer != null;
|
|
|
- }
|
|
|
-
|
|
|
- public void reshape(ViewPort vp, int w, int h) {
|
|
|
- outBuf = BufferUtils.createByteBuffer(w * h * 4);
|
|
|
- width = w;
|
|
|
- height = h;
|
|
|
- }
|
|
|
-
|
|
|
- public void preFrame(float tpf) {
|
|
|
- }
|
|
|
-
|
|
|
- public void postQueue(RenderQueue rq) {
|
|
|
- }
|
|
|
-
|
|
|
- public void postFrame(FrameBuffer out) {
|
|
|
- if (capture){
|
|
|
- capture = false;
|
|
|
- shotIndex++;
|
|
|
-
|
|
|
- renderer.setViewPort(0, 0, width, height);
|
|
|
- renderer.readFrameBuffer(out, outBuf);
|
|
|
-
|
|
|
- File file;
|
|
|
- if (filePath == null) {
|
|
|
- file = new File(JmeSystem.getStorageFolder() + File.separator + appName + shotIndex + ".png").getAbsoluteFile();
|
|
|
- } else {
|
|
|
- file = new File(filePath + appName + shotIndex + ".png").getAbsoluteFile();
|
|
|
- }
|
|
|
- logger.log(Level.INFO, "Saving ScreenShot to: {0}", file.getAbsolutePath());
|
|
|
-
|
|
|
- OutputStream outStream = null;
|
|
|
- try {
|
|
|
- outStream = new FileOutputStream(file);
|
|
|
- JmeSystem.writeImageFile(outStream, "png", outBuf, width, height);
|
|
|
- } catch (IOException ex) {
|
|
|
- logger.log(Level.SEVERE, "Error while saving screenshot", ex);
|
|
|
- } finally {
|
|
|
- if (outStream != null){
|
|
|
- try {
|
|
|
- outStream.close();
|
|
|
- } catch (IOException ex) {
|
|
|
- logger.log(Level.SEVERE, "Error while saving screenshot", ex);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+package com.jme3.app.state;
|
|
|
+
|
|
|
+import com.jme3.app.Application;
|
|
|
+import com.jme3.input.InputManager;
|
|
|
+import com.jme3.input.KeyInput;
|
|
|
+import com.jme3.input.controls.ActionListener;
|
|
|
+import com.jme3.input.controls.KeyTrigger;
|
|
|
+import com.jme3.post.SceneProcessor;
|
|
|
+import com.jme3.renderer.Camera;
|
|
|
+import com.jme3.renderer.RenderManager;
|
|
|
+import com.jme3.renderer.Renderer;
|
|
|
+import com.jme3.renderer.ViewPort;
|
|
|
+import com.jme3.renderer.queue.RenderQueue;
|
|
|
+import com.jme3.system.JmeSystem;
|
|
|
+import com.jme3.texture.FrameBuffer;
|
|
|
+import com.jme3.util.BufferUtils;
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.nio.ByteBuffer;
|
|
|
+import java.util.List;
|
|
|
+import java.util.logging.Level;
|
|
|
+import java.util.logging.Logger;
|
|
|
+
|
|
|
+public class ScreenshotAppState extends AbstractAppState implements ActionListener, SceneProcessor {
|
|
|
+
|
|
|
+ private static final Logger logger = Logger.getLogger(ScreenshotAppState.class.getName());
|
|
|
+ private String filePath = null;
|
|
|
+ private boolean capture = false;
|
|
|
+ private Renderer renderer;
|
|
|
+ private RenderManager rm;
|
|
|
+ private ByteBuffer outBuf;
|
|
|
+ private String appName;
|
|
|
+ private int shotIndex = 0;
|
|
|
+ private int width, height;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Using this constructor, the screenshot files will be written sequentially to the system
|
|
|
+ * default storage folder.
|
|
|
+ */
|
|
|
+ public ScreenshotAppState() {
|
|
|
+ this(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This constructor allows you to specify the output file path of the screenshot.
|
|
|
+ * Include the seperator at the end of the path.
|
|
|
+ * Use an emptry string to use the application folder. Use NULL to use the system
|
|
|
+ * default storage folder.
|
|
|
+ * @param file The screenshot file path to use. Include the seperator at the end of the path.
|
|
|
+ */
|
|
|
+ public ScreenshotAppState(String filePath) {
|
|
|
+ this.filePath = filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the file path to store the screenshot.
|
|
|
+ * Include the seperator at the end of the path.
|
|
|
+ * Use an emptry string to use the application folder. Use NULL to use the system
|
|
|
+ * default storage folder.
|
|
|
+ * @param file File path to use to store the screenshot. Include the seperator at the end of the path.
|
|
|
+ */
|
|
|
+ public void setFilePath(String filePath) {
|
|
|
+ this.filePath = filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void initialize(AppStateManager stateManager, Application app) {
|
|
|
+ if (!super.isInitialized()){
|
|
|
+ InputManager inputManager = app.getInputManager();
|
|
|
+ inputManager.addMapping("ScreenShot", new KeyTrigger(KeyInput.KEY_SYSRQ));
|
|
|
+ inputManager.addListener(this, "ScreenShot");
|
|
|
+
|
|
|
+ List<ViewPort> vps = app.getRenderManager().getPostViews();
|
|
|
+ ViewPort last = vps.get(vps.size()-1);
|
|
|
+ last.addProcessor(this);
|
|
|
+
|
|
|
+ appName = app.getClass().getSimpleName();
|
|
|
+ }
|
|
|
+
|
|
|
+ super.initialize(stateManager, app);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void onAction(String name, boolean value, float tpf) {
|
|
|
+ if (value){
|
|
|
+ capture = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void takeScreenshot() {
|
|
|
+ capture = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void initialize(RenderManager rm, ViewPort vp) {
|
|
|
+ renderer = rm.getRenderer();
|
|
|
+ this.rm = rm;
|
|
|
+ reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isInitialized() {
|
|
|
+ return super.isInitialized() && renderer != null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void reshape(ViewPort vp, int w, int h) {
|
|
|
+ outBuf = BufferUtils.createByteBuffer(w * h * 4);
|
|
|
+ width = w;
|
|
|
+ height = h;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void preFrame(float tpf) {
|
|
|
+ }
|
|
|
+
|
|
|
+ public void postQueue(RenderQueue rq) {
|
|
|
+ }
|
|
|
+
|
|
|
+ public void postFrame(FrameBuffer out) {
|
|
|
+ if (capture){
|
|
|
+ capture = false;
|
|
|
+ shotIndex++;
|
|
|
+
|
|
|
+ Camera curCamera = rm.getCurrentCamera();
|
|
|
+ int viewX = (int) (curCamera.getViewPortLeft() * curCamera.getWidth());
|
|
|
+ int viewY = (int) (curCamera.getViewPortBottom() * curCamera.getHeight());
|
|
|
+ int viewWidth = (int) ((curCamera.getViewPortRight() - curCamera.getViewPortLeft()) * curCamera.getWidth());
|
|
|
+ int viewHeight = (int) ((curCamera.getViewPortTop() - curCamera.getViewPortBottom()) * curCamera.getHeight());
|
|
|
+
|
|
|
+ renderer.setViewPort(0, 0, width, height);
|
|
|
+ renderer.readFrameBuffer(out, outBuf);
|
|
|
+ renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
|
|
|
+
|
|
|
+ File file;
|
|
|
+ if (filePath == null) {
|
|
|
+ file = new File(JmeSystem.getStorageFolder() + File.separator + appName + shotIndex + ".png").getAbsoluteFile();
|
|
|
+ } else {
|
|
|
+ file = new File(filePath + appName + shotIndex + ".png").getAbsoluteFile();
|
|
|
+ }
|
|
|
+ logger.log(Level.INFO, "Saving ScreenShot to: {0}", file.getAbsolutePath());
|
|
|
+
|
|
|
+ OutputStream outStream = null;
|
|
|
+ try {
|
|
|
+ outStream = new FileOutputStream(file);
|
|
|
+ JmeSystem.writeImageFile(outStream, "png", outBuf, width, height);
|
|
|
+ } catch (IOException ex) {
|
|
|
+ logger.log(Level.SEVERE, "Error while saving screenshot", ex);
|
|
|
+ } finally {
|
|
|
+ if (outStream != null){
|
|
|
+ try {
|
|
|
+ outStream.close();
|
|
|
+ } catch (IOException ex) {
|
|
|
+ logger.log(Level.SEVERE, "Error while saving screenshot", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|