diff --git a/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java b/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java index 4e891b67..a3e7b36b 100644 --- a/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java +++ b/src/main/java/com/replaymod/extras/advancedscreenshots/AdvancedScreenshots.java @@ -2,24 +2,12 @@ package com.replaymod.extras.advancedscreenshots; import com.replaymod.core.ReplayMod; import com.replaymod.extras.Extra; -import com.replaymod.render.RenderSettings; -import com.replaymod.render.capturer.RenderInfo; -import com.replaymod.render.hooks.ChunkLoadingRenderGlobal; -import com.replaymod.render.rendering.Pipelines; -import com.replaymod.replay.ReplayModReplay; import com.replaymod.replay.events.ReplayDispatchKeypressesEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiControls; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.crash.CrashReport; -import net.minecraft.util.ScreenShotHelper; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.input.Keyboard; -import org.lwjgl.util.Dimension; -import org.lwjgl.util.ReadableDimension; - -import java.io.File; public class AdvancedScreenshots implements Extra { @@ -43,66 +31,11 @@ public class AdvancedScreenshots implements Extra { && Keyboard.getEventKeyState() && keyCode == mc.gameSettings.keyBindScreenshot.getKeyCode()) { - if (GuiScreen.isCtrlKeyDown()) { - ReplayMod.instance.runLater(this::createEquirectangularScreenshot); + ReplayMod.instance.runLater(() -> { + new GuiCreateScreenshot(mod).display(); + }); - event.setCanceled(true); - } - } - } - - private void createEquirectangularScreenshot() { - try { - // take 360° screenshot - File screenshotFolder = new File(mc.mcDataDir, "screenshots"); - screenshotFolder.mkdir(); - File screenshotFile = ScreenShotHelper.getTimestampedPNGFileForDirectory(screenshotFolder); - - int height = 4 * 4320; - int width = 2 * height; - - int displayWidthBefore = mc.displayWidth; - int displayHeightBefore = mc.displayHeight; - - ChunkLoadingRenderGlobal clrg = new ChunkLoadingRenderGlobal(mc.renderGlobal); - - Pipelines.newEquirectangularPipeline(new RenderInfo() { - @Override - public ReadableDimension getFrameSize() { - return new Dimension(width, height); - } - - @Override - public int getTotalFrames() { - return 1; - } - - @Override - public float updateForNextFrame() { - return mc.timer.renderPartialTicks; - } - - @Override - public RenderSettings getRenderSettings() { - return new RenderSettings( - null, null, width, height, 0, 0, null, - true, true, true, true, null, - false, RenderSettings.AntiAliasing.NONE, null, null, false - ); - } - }, new ScreenshotWriter(screenshotFile)).run(); - - clrg.uninstall(); - - // the Equirectangular rendering changes mc.displayWidth and mc.displayHeight, - // so we have to reset it to the previous value - mc.resize(displayWidthBefore, displayHeightBefore); - - new GuiUploadScreenshot(ReplayModReplay.instance.getReplayHandler().getOverlay(), mod, screenshotFile).open(); - } catch (OutOfMemoryError e) { - e.printStackTrace(); - CrashReport report = CrashReport.makeCrashReport(e, "Creating Equirectangular Screenshot"); - Minecraft.getMinecraft().crashed(report); + event.setCanceled(true); } } } diff --git a/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java b/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java new file mode 100644 index 00000000..d4512d98 --- /dev/null +++ b/src/main/java/com/replaymod/extras/advancedscreenshots/GuiCreateScreenshot.java @@ -0,0 +1,87 @@ +package com.replaymod.extras.advancedscreenshots; + +import com.replaymod.core.ReplayMod; +import com.replaymod.render.RenderSettings; +import com.replaymod.render.gui.GuiRenderSettings; +import com.replaymod.replay.ReplayModReplay; +import de.johni0702.minecraft.gui.container.GuiContainer; +import de.johni0702.minecraft.gui.container.GuiPanel; +import de.johni0702.minecraft.gui.element.GuiLabel; +import de.johni0702.minecraft.gui.layout.GridLayout; +import de.johni0702.minecraft.gui.layout.VerticalLayout; +import net.minecraft.crash.CrashReport; +import net.minecraft.util.ScreenShotHelper; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import java.io.File; +import java.util.ArrayList; + +import static com.replaymod.core.utils.Utils.error; +import static com.replaymod.render.ReplayModRender.LOGGER; + +public class GuiCreateScreenshot extends GuiRenderSettings { + + private final ReplayMod mod; + + public GuiCreateScreenshot(ReplayMod mod) { + super(null, null); + + this.mod = mod; + + resetChildren(settingsList.getListPanel()).addElements(new VerticalLayout.Data(0.5), + new GuiLabel().setI18nText("replaymod.gui.advancedscreenshots.title"), mainPanel, new GuiPanel(), + new GuiLabel().setI18nText("replaymod.gui.rendersettings.advanced"), advancedPanel, new GuiPanel()); + + resetChildren(mainPanel).addElements(new GridLayout.Data(1, 0.5), + new GuiLabel().setI18nText("replaymod.gui.rendersettings.renderer"), renderMethodDropdown, + new GuiLabel().setI18nText("replaymod.gui.advancedscreenshots.resolution"), videoResolutionPanel, + new GuiLabel().setI18nText("replaymod.gui.rendersettings.outputfile"), outputFileButton); + + resetChildren(advancedPanel).addElements(null, nametagCheckbox, new GuiPanel().setLayout( + new GridLayout().setCellsEqualSize(false).setColumns(2).setSpacingX(5).setSpacingY(15)) + .addElements(new GridLayout.Data(0, 0.5), + new GuiLabel().setI18nText("replaymod.gui.rendersettings.stabilizecamera"), stabilizePanel, + chromaKeyingCheckbox, chromaKeyingColor)); + + exportArguments.setText(""); // To disable any preset-based checks + buttonPanel.removeElement(queueButton); + renderButton.setI18nLabel("replaymod.gui.advancedscreenshots.create").onClick(() -> { + // Closing this GUI ensures that settings are saved + getMinecraft().displayGuiScreen(null); + + mod.runLater(() -> { + try { + RenderSettings settings = save(false); + + boolean success = new ScreenshotRenderer(settings).renderScreenshot(); + if (success) { + new GuiUploadScreenshot(ReplayModReplay.instance.getReplayHandler().getOverlay(), mod, + settings).open(); + } + + } catch (Throwable t) { + error(LOGGER, GuiCreateScreenshot.this, CrashReport.makeCrashReport(t, "Rendering video"), () -> {}); + display(); // Re-show the render settings gui and the new error popup + } + }); + }); + } + + private > T resetChildren(T container) { + new ArrayList<>(container.getChildren()).forEach(container::removeElement); + return container; + } + + @Override + protected File generateOutputFile(RenderSettings.EncodingPreset encodingPreset) { + File screenshotFolder = new File(getMinecraft().mcDataDir, "screenshots"); + return ScreenShotHelper.getTimestampedPNGFileForDirectory(screenshotFolder); + } + + @Override + protected Property getConfigProperty(Configuration configuration) { + return configuration.get("screenshotsettings", "settings", "{}", + "Last state of the screenshot settings GUI. Internal use only."); + } +} \ No newline at end of file diff --git a/src/main/java/com/replaymod/extras/advancedscreenshots/GuiUploadScreenshot.java b/src/main/java/com/replaymod/extras/advancedscreenshots/GuiUploadScreenshot.java index 828d7f65..e2168da5 100644 --- a/src/main/java/com/replaymod/extras/advancedscreenshots/GuiUploadScreenshot.java +++ b/src/main/java/com/replaymod/extras/advancedscreenshots/GuiUploadScreenshot.java @@ -3,6 +3,7 @@ package com.replaymod.extras.advancedscreenshots; import com.replaymod.core.ReplayMod; import com.replaymod.core.SettingsRegistry; import com.replaymod.extras.Setting; +import com.replaymod.render.RenderSettings; import de.johni0702.minecraft.gui.container.GuiContainer; import de.johni0702.minecraft.gui.container.GuiPanel; import de.johni0702.minecraft.gui.element.GuiButton; @@ -14,7 +15,6 @@ import de.johni0702.minecraft.gui.popup.AbstractGuiPopup; import org.lwjgl.util.ReadableColor; import java.awt.*; -import java.io.File; import java.io.IOException; import java.net.URI; @@ -22,10 +22,10 @@ public class GuiUploadScreenshot extends AbstractGuiPopup { public final ReplayMod mod; - public final File screenshotFile; + public final RenderSettings renderSettings; public final GuiLabel successLabel = new GuiLabel() - .setI18nText("replaymod.gui.advancedscreenshots.finished.description.360") + .setI18nText("replaymod.gui.advancedscreenshots.finished.description") .setColor(ReadableColor.BLACK); public final GuiLabel veerLabel = new GuiLabel() @@ -56,22 +56,30 @@ public class GuiUploadScreenshot extends AbstractGuiPopup { .with(neverOpenLabel, new HorizontalLayout.Data(0.5)) .build(); - public GuiUploadScreenshot(GuiContainer container, ReplayMod mod, File screenshotFile) { + public GuiUploadScreenshot(GuiContainer container, ReplayMod mod, RenderSettings renderSettings) { super(container); this.mod = mod; - this.screenshotFile = screenshotFile; + this.renderSettings = renderSettings; - veerUploadButton.onClick(() -> { - try { - Desktop.getDesktop().browse(URI.create("https://veer.tv/upload")); - } catch (IOException e) { - e.printStackTrace(); - } - }); + boolean veer = renderSettings.getRenderMethod() == RenderSettings.RenderMethod.EQUIRECTANGULAR; + + if (renderSettings.getRenderMethod() == RenderSettings.RenderMethod.EQUIRECTANGULAR) { + successLabel.setI18nText("replaymod.gui.advancedscreenshots.finished.description.360"); + } + + if (veer) { + veerUploadButton.onClick(() -> { + try { + Desktop.getDesktop().browse(URI.create("https://veer.tv/upload")); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } showOnDiskButton.onClick(() -> { try { - Desktop.getDesktop().browse(URI.create("file://" + screenshotFile.getAbsolutePath())); + Desktop.getDesktop().browse(URI.create("file://" + renderSettings.getOutputFile().getAbsolutePath())); } catch (IOException e) { e.printStackTrace(); } @@ -86,10 +94,16 @@ public class GuiUploadScreenshot extends AbstractGuiPopup { close(); }); + popup.addElements(new VerticalLayout.Data(0.5), successLabel); + + if (veer) { + popup.addElements(new VerticalLayout.Data(0.5), + veerLabel, + veerUploadButton); + } + popup.addElements(new VerticalLayout.Data(0.5), successLabel, - veerLabel, - veerUploadButton, showOnDiskButton, closeButton); diff --git a/src/main/java/com/replaymod/extras/advancedscreenshots/ScreenshotRenderer.java b/src/main/java/com/replaymod/extras/advancedscreenshots/ScreenshotRenderer.java new file mode 100644 index 00000000..72aad0ac --- /dev/null +++ b/src/main/java/com/replaymod/extras/advancedscreenshots/ScreenshotRenderer.java @@ -0,0 +1,65 @@ +package com.replaymod.extras.advancedscreenshots; + +import com.replaymod.render.RenderSettings; +import com.replaymod.render.capturer.RenderInfo; +import com.replaymod.render.hooks.ChunkLoadingRenderGlobal; +import com.replaymod.render.rendering.Pipelines; +import lombok.RequiredArgsConstructor; +import net.minecraft.client.Minecraft; +import net.minecraft.crash.CrashReport; +import org.lwjgl.util.Dimension; +import org.lwjgl.util.ReadableDimension; + +@RequiredArgsConstructor +public class ScreenshotRenderer implements RenderInfo { + + private final Minecraft mc = Minecraft.getMinecraft(); + + private final RenderSettings settings; + + public boolean renderScreenshot() throws Throwable { + try { + int displayWidthBefore = mc.displayWidth; + int displayHeightBefore = mc.displayHeight; + + ChunkLoadingRenderGlobal clrg = new ChunkLoadingRenderGlobal(mc.renderGlobal); + + Pipelines.newPipeline(settings.getRenderMethod(),this, + new ScreenshotWriter(settings.getOutputFile())).run(); + + clrg.uninstall(); + + mc.resize(displayWidthBefore, displayHeightBefore); + return true; + } catch (OutOfMemoryError e) { + e.printStackTrace(); + CrashReport report = CrashReport.makeCrashReport(e, "Creating Equirectangular Screenshot"); + Minecraft.getMinecraft().crashed(report); + } + return false; + } + + @Override + public ReadableDimension getFrameSize() { + return new Dimension(settings.getVideoWidth(), settings.getVideoHeight()); + } + + @Override + public int getTotalFrames() { + return 1; + } + + @Override + public float updateForNextFrame() { + return mc.timer.renderPartialTicks; + } + + @Override + public RenderSettings getRenderSettings() { + return new RenderSettings( + null, null, settings.getVideoWidth(), settings.getVideoHeight(), 0, 0, null, + true, true, true, true, null, + false, RenderSettings.AntiAliasing.NONE, null, null, false + ); + } +} diff --git a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java index f712dd0d..a07f801e 100644 --- a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java +++ b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java @@ -427,7 +427,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { ); } - private File generateOutputFile(RenderSettings.EncodingPreset encodingPreset) { + protected File generateOutputFile(RenderSettings.EncodingPreset encodingPreset) { String fileName = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss").format(new Date()); File folder = ReplayModRender.instance.getVideoFolder(); return new File(folder, fileName + "." + encodingPreset.getFileExtension()); @@ -447,7 +447,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { config.save(); } - private Property getConfigProperty(Configuration configuration) { + protected Property getConfigProperty(Configuration configuration) { return configuration.get("rendersettings", "settings", "{}", "Last state of the render settings GUI. Internal use only."); }