Skip to content

Commit

Permalink
Refactor + Error Handling
Browse files Browse the repository at this point in the history
---

This refactor abstracts most of the bulk/single render logic in preparation for Entity/Structure renders.

Signed-off-by: AterAnimAvis <[email protected]>
  • Loading branch information
AterAnimAvis committed May 7, 2020
1 parent b7ba9bd commit cd03263
Show file tree
Hide file tree
Showing 12 changed files with 419 additions and 349 deletions.
12 changes: 3 additions & 9 deletions src/main/java/com/unascribed/blockrenderer/BlockRenderer.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.unascribed.blockrenderer;

import com.unascribed.blockrenderer.init.Keybindings;
import com.unascribed.blockrenderer.render.ItemStackRenderer;
import com.unascribed.blockrenderer.render.SingleRenderer;
import com.unascribed.blockrenderer.render.impl.ItemStackRenderer;
import com.unascribed.blockrenderer.render.request.IRequest;
import com.unascribed.blockrenderer.screens.EnterNamespaceScreen;
import com.unascribed.blockrenderer.screens.EnterSizeScreen;
Expand Down Expand Up @@ -46,14 +47,7 @@ public BlockRenderer() {
public void onFrameStart(TickEvent.RenderTickEvent e) {
if (e.phase != TickEvent.Phase.START) return;

/*
* Quick primer: OpenGL is double-buffered. This means, where we draw to is
* /not/ on the screen. As such, we are free to do whatever we like before
* Minecraft renders, as long as we put everything back the way it was.
*/

if (pendingRequest != null) {
// We *must* call render code in pre-render. If we don't, it won't work right.
pendingRequest.render();
pendingRequest = null;
}
Expand Down Expand Up @@ -124,7 +118,7 @@ private static void renderStack(ItemStack stack) {
return;
}

ItemStackRenderer.renderItem(512, stack, false, false);
SingleRenderer.render(new ItemStackRenderer(), stack, 512, false, false);
}

private static boolean isKeyDown() {
Expand Down
132 changes: 132 additions & 0 deletions src/main/java/com/unascribed/blockrenderer/render/BulkRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.unascribed.blockrenderer.render;

import com.mojang.blaze3d.platform.GlStateManager;
import com.unascribed.blockrenderer.utils.Rendering;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.IngameMenuScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.Util;
import net.minecraft.util.text.TranslationTextComponent;

import javax.annotation.Nullable;
import java.io.File;
import java.util.List;

import static com.unascribed.blockrenderer.render.IRenderer.DEFAULT_FOLDER;
import static com.unascribed.blockrenderer.utils.MiscUtils.isEscapePressed;
import static com.unascribed.blockrenderer.utils.StringUtils.*;

public class BulkRenderer {

private static final int WAIT = 1500;

private static final Minecraft client = Minecraft.getInstance();
private static final MainWindow window = client.mainWindow;

public static <T> void bulkRender(IRenderer<T> renderer, String spec, List<T> renders, int size, boolean useId, boolean addSize) {
if (renders.size() < 1) {
addMessage(new TranslationTextComponent("msg.blockrenderer.bulk.noItems", spec));
return;
}

client.displayGuiScreen(new IngameMenuScreen(false));

int errored = 0;
int rendered = 0;
long lastUpdate = 0;
int total = renders.size();

String sizeString = addSize ? size + "x" + size + "_" : "";
File folder = new File(DEFAULT_FOLDER, dateTime() + "_" + sizeString + sanitize(spec) + "/");
String title = I18n.format("blockrenderer.gui.rendering", total, spec);

long start = Util.milliTime();

renderer.setup(size);
for (T value : renders) {
if (isEscapePressed()) break;

String fileName = renderer.getFilename(value, useId);

try {
renderer.render(value);
renderer.saveRaw(folder, fileName);
} catch (Exception e) {
System.err.println("Rendering: " + renderer.getId(value));
e.printStackTrace();
errored++;
}

rendered++;

if (Util.milliTime() - lastUpdate > 33) {
renderer.teardown();

renderLoading(renderer, title, I18n.format("blockrenderer.gui.progress", rendered, total, (total - rendered)), value, (float)rendered/ total);

lastUpdate = Util.milliTime();
renderer.setup(size);
}
}

long elapsed = Util.milliTime() - start;

if (rendered >= total) {
renderLoading(renderer, I18n.format("blockrenderer.gui.rendered", total, spec), "", null, 1f);
addMessage(new TranslationTextComponent("msg.blockrenderer.bulk.finished", total, spec, asClickable(folder)));
} else {
renderLoading(renderer, I18n.format("blockrenderer.gui.renderCancelled"), I18n.format("blockrenderer.gui.progress", rendered, total, (total - rendered)), null, (float)rendered/ total);
addMessage(new TranslationTextComponent("msg.blockrenderer.bulk.cancelled", rendered, spec, asClickable(folder), total));
}

if (errored > 0) addMessage(I18n.format("msg.blockrenderer.bulk.errored", errored));

addMessage(new TranslationTextComponent("msg.blockrenderer.bulk.time", elapsed / 1000f));

renderer.teardown();

try { Thread.sleep(WAIT); } catch (InterruptedException ignored) {}

client.displayGuiScreen(null);
}

private static <T> void renderLoading(IRenderer<T> renderer, String title, String subtitle, @Nullable T value, float progress) {
client.getFramebuffer().unbindFramebuffer();

GlStateManager.pushMatrix();

int displayWidth = window.getScaledWidth();
int displayHeight = window.getScaledHeight();
Rendering.setupOverlayRendering();

// Draw the dirt background
Rendering.drawBackground(displayWidth, displayHeight);

// ...and the title
Rendering.drawCenteredString(client.fontRenderer, title, displayWidth / 2, displayHeight / 2 - 24, -1);

// ...and the progress bar
Rendering.drawRect(displayWidth / 2 - 50, displayHeight / 2 - 1, displayWidth / 2 + 50, displayHeight / 2 + 1, 0xFF001100);
Rendering.drawRect(displayWidth / 2 - 50, displayHeight / 2 - 1, (displayWidth / 2 - 50) + (int) (progress * 100), displayHeight / 2 + 1, 0xFF55FF55);

GlStateManager.pushMatrix();

GlStateManager.scalef(0.5f, 0.5f, 1);

// ...and the subtitle
Rendering.drawCenteredString(client.fontRenderer, subtitle, displayWidth, displayHeight - 20, -1);

// ...and the tooltip.
if (value != null) renderer.renderTooltip(value, displayWidth, displayHeight);

GlStateManager.popMatrix();

GlStateManager.popMatrix();

client.updateDisplay(false);

client.getFramebuffer().bindFramebuffer(false);
}

}
69 changes: 69 additions & 0 deletions src/main/java/com/unascribed/blockrenderer/render/IRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.unascribed.blockrenderer.render;

import com.google.common.io.Files;
import com.unascribed.blockrenderer.lib.TileRenderer;
import com.unascribed.blockrenderer.utils.ImageUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;

import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

import static com.unascribed.blockrenderer.utils.FileUtils.getFile;
import static com.unascribed.blockrenderer.utils.StringUtils.getRenderSuccess;
import static com.unascribed.blockrenderer.utils.StringUtils.sanitize;

public interface IRenderer<T> {

File DEFAULT_FOLDER = new File("renders");

void setup(int size);

void render(T value);

void teardown();

void renderTooltip(T value, int displayWidth, int displayHeight);

ResourceLocation getId(T value);

ITextComponent getName(T value);

default String getFilename(T value, boolean useId) {
return useId ? sanitize(getId(value)) : sanitize(getName(value));
}

@Nullable
TileRenderer getRenderer();

@SuppressWarnings("UnstableApiUsage")
default File saveRaw(File folder, String filename) throws Exception {
TileRenderer renderer = getRenderer();

if (renderer == null) throw new IllegalStateException("TileRenderer is null");

BufferedImage img = ImageUtils.readPixels(renderer);

File file = getFile(folder, filename);
Files.createParentDirs(file);

ImageIO.write(img, "PNG", file);

return file;
}

default ITextComponent save(T value, File folder, String filename) {
try {
File file = saveRaw(folder, filename);
return getRenderSuccess(folder, file);
} catch (Exception e) {
System.err.println("Rendering: " + getId(value));
e.printStackTrace();
return new TranslationTextComponent("msg.blockrenderer.render.fail");
}
}

}
Loading

0 comments on commit cd03263

Please sign in to comment.