diff --git a/src/main/scala/ocelot/desktop/graphics/Graphics.scala b/src/main/scala/ocelot/desktop/graphics/Graphics.scala index d2b4f93..26f3d2e 100644 --- a/src/main/scala/ocelot/desktop/graphics/Graphics.scala +++ b/src/main/scala/ocelot/desktop/graphics/Graphics.scala @@ -8,8 +8,10 @@ import ocelot.desktop.graphics.mesh.{Mesh2D, MeshInstance2D, MeshVertex2D} import ocelot.desktop.graphics.render.InstanceRenderer import ocelot.desktop.ui.UiHandler import ocelot.desktop.util.{Font, Logging, Resource, Spritesheet} +import org.lwjgl.BufferUtils import org.lwjgl.opengl.{ARBFramebufferObject, GL11, GL21, GL30} +import java.awt.image.BufferedImage import java.nio.ByteBuffer import scala.collection.mutable import scala.util.control.Breaks._ @@ -392,6 +394,27 @@ class Graphics(private var width: Int, private var height: Int, private var scal line(start.x, start.y, end.x, end.y, thickness, color) } + def screenshot(): BufferedImage = { + val buffer = BufferUtils.createByteBuffer(width * height * 4) + GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer) + val image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) + var y = 0 + while (y < height) { + var x = 0 + while (x < width) { + val i = (x + (height - y - 1) * width) * 4 + val r = buffer.get(i) & 0xFF + val g = buffer.get(i + 1) & 0xFF + val b = buffer.get(i + 2) & 0xFF + val rgb = (r << 16) | (g << 8) | b + image.setRGB(x, y, rgb) + x += 1 + } + y += 1 + } + image + } + def flush(mainTexture: Texture = Spritesheet.texture, clear: Boolean = false): Unit = { if (renderer.isEmpty && !clear) return diff --git a/src/main/scala/ocelot/desktop/ui/UiHandler.scala b/src/main/scala/ocelot/desktop/ui/UiHandler.scala index bb7de9a..8c161c1 100644 --- a/src/main/scala/ocelot/desktop/ui/UiHandler.scala +++ b/src/main/scala/ocelot/desktop/ui/UiHandler.scala @@ -18,6 +18,7 @@ import org.lwjgl.opengl._ import java.awt.Toolkit import java.awt.datatransfer.{DataFlavor, StringSelection, UnsupportedFlavorException} +import java.awt.image.BufferedImage import java.io.{File, FileOutputStream} import java.nio.ByteBuffer import java.nio.channels.Channels @@ -145,6 +146,8 @@ object UiHandler extends Logging { Settings.get.windowFullscreen = value } + def screenshot(): BufferedImage = graphics.screenshot() + private def formatRect(rect: Rect2D): String = { val Rect2D(x, y, w, h) = rect diff --git a/src/main/scala/ocelot/desktop/ui/widget/RootWidget.scala b/src/main/scala/ocelot/desktop/ui/widget/RootWidget.scala index a9000f2..e64554d 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/RootWidget.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/RootWidget.scala @@ -12,11 +12,16 @@ import ocelot.desktop.ui.widget.itemdrag.DraggedItemPool import ocelot.desktop.ui.widget.modal.ModalDialogPool import ocelot.desktop.ui.widget.statusbar.StatusBar import ocelot.desktop.ui.widget.tooltip.TooltipPool -import ocelot.desktop.util.{DrawUtils, Orientation} +import ocelot.desktop.util.{DrawUtils, Logging, Orientation} import org.lwjgl.input.Keyboard import totoro.ocelot.brain.nbt.NBTTagCompound -class RootWidget(setupDefaultWorkspace: Boolean = true) extends Widget { +import java.io.File +import javax.imageio.ImageIO +import javax.swing.JFileChooser +import scala.util.Try + +class RootWidget(setupDefaultWorkspace: Boolean = true) extends Widget with Logging { override protected val layout = new CopyLayout(this) root = Some(this) @@ -66,6 +71,18 @@ class RootWidget(setupDefaultWorkspace: Boolean = true) extends Widget { case KeyEvent(KeyEvent.State.Release, Keyboard.KEY_F11, _) => UiHandler.fullScreen = !UiHandler.fullScreen + + case KeyEvent(KeyEvent.State.Release, Keyboard.KEY_F12, _) => + val image = UiHandler.screenshot() + OcelotDesktop.showFileChooserDialog(JFileChooser.SAVE_DIALOG, JFileChooser.DIRECTORIES_ONLY) { dir => + Try { + for (dir <- dir) { + val file = new File(dir, s"ocelot-${System.currentTimeMillis()}.png") + ImageIO.write(image, "PNG", file) + logger.debug(s"Saved screenshot to: $file") + } + } + } } override def draw(g: Graphics): Unit = {