From 7b2e47ca2cd7f690ad0ebaea8e572ec7789aba70 Mon Sep 17 00:00:00 2001 From: Talia-12 Date: Mon, 11 Dec 2023 16:24:53 +1000 Subject: [PATCH] stop active patterns on tiles jumping around all other the place, fix crash when too many patterns added to render queue at once, try and fix flickering issue. --- .../client/render/PatternTextureManager.java | 42 ++++++++++++------- .../render/be/BlockEntitySlateRenderer.java | 11 +++-- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java index 3f33bd9a4..c28116900 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java @@ -44,22 +44,22 @@ public class PatternTextureManager { public static int paddingByBlockSize = 16 * resolutionScaler; public static int circleRadiusByBlockSize = 2 * resolutionScaler; public static int scaleLimit = 4 * resolutionScaler; - public static int scrollLineWidth = 6 * resolutionScaler; - public static int otherLineWidth = 5 * resolutionScaler; + public static int scrollLineWidth = 3 * resolutionScaler; + public static int otherLineWidth = 4 * resolutionScaler; public static void setResolutionScaler(int resolutionScaler) { PatternTextureManager.resolutionScaler = resolutionScaler; - resolutionByBlockSize = 256 * resolutionScaler; - paddingByBlockSize = 32 * resolutionScaler; - circleRadiusByBlockSize = 4 * resolutionScaler; - scaleLimit = 8 * resolutionScaler; - scrollLineWidth = 7 * resolutionScaler; - otherLineWidth = 10 * resolutionScaler; + resolutionByBlockSize = 128 * resolutionScaler; + paddingByBlockSize = 16 * resolutionScaler; + circleRadiusByBlockSize = 2 * resolutionScaler; + scaleLimit = 4 * resolutionScaler; + scrollLineWidth = 3 * resolutionScaler; + otherLineWidth = 4 * resolutionScaler; } private static final ConcurrentMap patternTexturesToAdd = new ConcurrentHashMap<>(); // basically newCachedThreadPool, but with a max pool size - private static final ExecutorService executor = new ThreadPoolExecutor(0, 16, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); + private static final ExecutorService executor = new ThreadPoolExecutor(0, 16, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); private static final HashMap patternTextures = new HashMap<>(); @@ -225,20 +225,28 @@ private static void vertex(Matrix4f mat, Matrix3f normal, int light, VertexConsu } public static ResourceLocation getTexture(List points, String pointsKey, int blockSize, boolean showsStrokeOrder, float lineWidth, boolean useFullSize, Color innerColor, Color outerColor) { - if (patternTexturesToAdd.containsKey(pointsKey)) - return patternTexturesToAdd.get(pointsKey); + if (patternTexturesToAdd.containsKey(pointsKey)) { + var patternTexture = patternTexturesToAdd.remove(pointsKey); + var oldPatternTexture = patternTextures.put(pointsKey, patternTexture); + if (oldPatternTexture != null) + Minecraft.getInstance().getTextureManager().getTexture(oldPatternTexture).close(); + + return patternTexture; + } + if (patternTextures.containsKey(pointsKey)) + return patternTextures.get(pointsKey); // render a higher-resolution texture in a background thread so it eventually becomes all nice nice and pretty executor.submit(() -> { var slowTexture = createTexture(points, blockSize, showsStrokeOrder, lineWidth, useFullSize, innerColor, outerColor, false); // TextureManager#register doesn't look very thread-safe, so move back to the main thread after the slow part is done - Minecraft.getInstance().execute(() -> registerTexture(points, pointsKey, slowTexture)); + Minecraft.getInstance().execute(() -> registerTexture(points, pointsKey, slowTexture, true)); }); // quickly create and cache a low-resolution texture so the client has something to look at var fastTexture = createTexture(points, blockSize, showsStrokeOrder, lineWidth, useFullSize, innerColor, outerColor, true); - return registerTexture(points, pointsKey, fastTexture); + return registerTexture(points, pointsKey, fastTexture, false); } private static DynamicTexture createTexture(List points, int blockSize, boolean showsStrokeOrder, float lineWidth, boolean useFullSize, Color innerColor, Color outerColor, boolean fastRender) @@ -303,8 +311,11 @@ private static DynamicTexture createTexture(List points, int blockSize, bo return new DynamicTexture(nativeImage); } - private static ResourceLocation registerTexture(List points, String pointsKey, DynamicTexture dynamicTexture) { - String name = "hex_pattern_texture_" + points.hashCode() + "_" + repaintIndex + ".png"; + private static ResourceLocation registerTexture(List points, String pointsKey, DynamicTexture dynamicTexture, boolean isSlow) { + // isSlow used to register different textures for the low-resolution, fastly rendered version of each texture + // and the high-resolution, slowly rendered version (this means the slow doesn't replace the fast in the texture manager, + // which causes occasional visual stuttering for a frame). + String name = "hex_pattern_texture_" + points.hashCode() + "_" + repaintIndex + "_" + (isSlow ? "slow" : "fast") + ".png"; ResourceLocation resourceLocation = Minecraft.getInstance().getTextureManager().register(name, dynamicTexture); patternTexturesToAdd.put(pointsKey, resourceLocation); return resourceLocation; @@ -341,5 +352,6 @@ private static void drawHexagon(Graphics2D g2d, int x, int y, int radius) { public static void repaint() { repaintIndex++; patternTexturesToAdd.clear(); + patternTextures.clear(); } } \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java index b9550dbbd..37a40babc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java @@ -72,9 +72,14 @@ public void render(BlockEntitySlate tile, float pPartialTick, PoseStack ps, var lines1 = tile.pattern.toLines(1, Vec2.ZERO); var stupidHash = tile.getBlockPos().hashCode(); - var zappyPatternSpace = RenderLib.makeZappy(lines1, RenderLib.findDupIndices(tile.pattern.positions()), + var zappyPattern = RenderLib.makeZappy(lines1, RenderLib.findDupIndices(tile.pattern.positions()), 10, variance, speed, 0.2f, 0f, 1f, stupidHash); + // always do space calculations with the static version of the pattern + // so that it doesn't jump around resizing itself. + var zappyPatternSpace = RenderLib.makeZappy(lines1, RenderLib.findDupIndices(tile.pattern.positions()), + 10, 0.5f, 0f, 0.2f, 0f, 1f, stupidHash); + double minX = Double.MAX_VALUE, maxX = Double.MIN_VALUE, minY = Double.MAX_VALUE, maxY = Double.MIN_VALUE; for (Vec2 point : zappyPatternSpace) { @@ -94,7 +99,7 @@ public void render(BlockEntitySlate tile, float pPartialTick, PoseStack ps, var zappyRenderSpace = new ArrayList(); - for (Vec2 point : zappyPatternSpace) { + for (Vec2 point : zappyPattern) { zappyRenderSpace.add(new Vec2( (float) (((point.x - minX) * scale + offsetX) + padding), (float) (((point.y - minY) * scale + offsetY) + padding) @@ -115,4 +120,4 @@ public void render(BlockEntitySlate tile, float pPartialTick, PoseStack ps, ps.popPose(); RenderSystem.setShader(() -> oldShader); } -} +} \ No newline at end of file