diff --git a/.gitignore b/.gitignore index e4380dee..04626193 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ whitelist.json src/main/resources/mixins.*.json *.bat layout.json +.DS_Store diff --git a/gradle.properties b/gradle.properties index b5bd7a02..887f2066 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,7 +41,7 @@ developmentEnvironmentUserName = Developer # Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8. # See https://github.com/bsideup/jabel for details on how this works. -enableModernJavaSyntax = false +enableModernJavaSyntax = true # Enables injecting missing generics into the decompiled source code for a better coding experience. # Turns most publicly visible List, Map, etc. into proper List, Map types. diff --git a/src/main/java/team/chisel/client/render/SubmapManagerVoidstone.java b/src/main/java/team/chisel/client/render/SubmapManagerVoidstone.java index 2a1f53d9..aadd2a59 100644 --- a/src/main/java/team/chisel/client/render/SubmapManagerVoidstone.java +++ b/src/main/java/team/chisel/client/render/SubmapManagerVoidstone.java @@ -21,91 +21,166 @@ public class SubmapManagerVoidstone extends SubmapManagerBase { // TODO there must be a better more generic way to do this... @SideOnly(Side.CLIENT) - private class RenderBlocksVoidstone extends RenderBlocksCTM { + private static class RenderBlocksVoidstone extends RenderBlocksCTM { @Override public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon) { - super.renderFaceXNeg(block, x, y, z, icon); - renderMinX += 0.005; + shiftBoundary(ForgeDirection.WEST); setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.WEST.ordinal())); super.renderFaceXNeg(block, x, y, z, null); clearOverrideBlockTexture(); + resetBoundary(ForgeDirection.WEST); + + super.renderFaceXNeg(block, x, y, z, icon); } @Override public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon) { - super.renderFaceXPos(block, x, y, z, icon); + shiftBoundary(ForgeDirection.EAST); setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.EAST.ordinal())); - renderMaxX -= 0.005; super.renderFaceXPos(block, x, y, z, null); clearOverrideBlockTexture(); + resetBoundary(ForgeDirection.EAST); + + super.renderFaceXPos(block, x, y, z, icon); } @Override public void renderFaceYNeg(Block block, double x, double y, double z, IIcon icon) { - super.renderFaceYNeg(block, x, y, z, icon); + shiftBoundary(ForgeDirection.DOWN); setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.DOWN.ordinal())); - renderMinY += 0.005; super.renderFaceYNeg(block, x, y, z, null); clearOverrideBlockTexture(); + resetBoundary(ForgeDirection.DOWN); + + super.renderFaceYNeg(block, x, y, z, icon); } @Override public void renderFaceYPos(Block block, double x, double y, double z, IIcon icon) { - super.renderFaceYPos(block, x, y, z, icon); + shiftBoundary(ForgeDirection.UP); setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.UP.ordinal())); - renderMaxY -= 0.005; super.renderFaceYPos(block, x, y, z, null); clearOverrideBlockTexture(); + resetBoundary(ForgeDirection.UP); + + super.renderFaceYPos(block, x, y, z, icon); } @Override public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) { - super.renderFaceZNeg(block, x, y, z, icon); + shiftBoundary(ForgeDirection.NORTH); setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.NORTH.ordinal())); - renderMinZ += 0.005; super.renderFaceZNeg(block, x, y, z, null); clearOverrideBlockTexture(); + resetBoundary(ForgeDirection.NORTH); + + super.renderFaceZNeg(block, x, y, z, icon); } @Override public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon) { - super.renderFaceZPos(block, x, y, z, icon); + shiftBoundary(ForgeDirection.SOUTH); setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.SOUTH.ordinal())); - renderMaxZ -= 0.005; super.renderFaceZPos(block, x, y, z, null); clearOverrideBlockTexture(); + resetBoundary(ForgeDirection.SOUTH); + + super.renderFaceZPos(block, x, y, z, icon); } - public void reset() { - this.submap = null; + private IIcon getBase(double x, double y, double z, int side) { + return TextureType.getVIcon( + TextureType.V4, + base, + MathHelper.floor_double(x), + MathHelper.floor_double(y), + MathHelper.floor_double(z), + side); + } + + private void shiftBoundary(ForgeDirection direction) { + // When rendering a CTM overlay texture over a base block texture the base texture starts to z-fight. + // This method makes the base texture render slightly below the overlay. + // This submap check makes sure that we only apply this hack for blocks with CTM overlays + if (submap == null) { + return; + } + + float epsilon = 0.0005F; + + switch (direction) { + case WEST -> { + renderMinX += epsilon; + renderMinX += epsilon; + } + case EAST -> { + renderMinX -= epsilon; + renderMaxX -= epsilon; + } + case DOWN -> { + renderMinY += epsilon; + renderMaxY += epsilon; + } + case UP -> { + renderMinY -= epsilon; + renderMaxY -= epsilon; + } + case NORTH -> { + renderMinZ += epsilon; + renderMaxZ += epsilon; + } + case SOUTH -> { + renderMinZ -= epsilon; + renderMaxZ -= epsilon; + } + } + } + + private void resetBoundary(ForgeDirection direction) { + if (submap == null) { + return; + } + + float epsilon = 0.0005F; + + switch (direction) { + case WEST -> { + renderMinX -= epsilon; + renderMaxX -= epsilon; + } + case EAST -> { + renderMinX += epsilon; + renderMaxX += epsilon; + } + case DOWN -> { + renderMinY -= epsilon; + renderMaxY -= epsilon; + } + case UP -> { + renderMinY += epsilon; + renderMaxY += epsilon; + } + case NORTH -> { + renderMinZ -= epsilon; + renderMaxZ -= epsilon; + } + case SOUTH -> { + renderMinZ += epsilon; + renderMaxZ += epsilon; + } + } } } @SideOnly(Side.CLIENT) private static ThreadLocal renderBlocksThreadLocal; - private static void initStatics() { - if (renderBlocksThreadLocal == null) { - renderBlocksThreadLocal = new ThreadLocal<>(); - } - } - private ISubmapManager overlay; - private TextureSubmap base; + private static TextureSubmap base; - private IIcon getBase(double x, double y, double z, int side) { - return TextureType.getVIcon( - TextureType.V4, - base, - MathHelper.floor_double(x), - MathHelper.floor_double(y), - MathHelper.floor_double(z), - side); - } - - private String texture; - private int meta; + private final String texture; + private final int meta; public SubmapManagerVoidstone(String texture, int meta) { this.texture = texture; @@ -133,18 +208,22 @@ public class SubmapManagerVoidstone extends SubmapManagerBase { @Override @SideOnly(Side.CLIENT) public RenderBlocks createRenderContext(RenderBlocks rendererOld, Block block, IBlockAccess world) { - initStatics(); + if (renderBlocksThreadLocal == null) { + renderBlocksThreadLocal = ThreadLocal.withInitial(RenderBlocksVoidstone::new); + } + RenderBlocksVoidstone rb = renderBlocksThreadLocal.get(); - if (rb == null) { - rb = new RenderBlocksVoidstone(); - renderBlocksThreadLocal.set(rb); - } else rb.reset(); RenderBlocks ctx = overlay.createRenderContext(rendererOld, block, world); rb.setRenderBoundsFromBlock(block); + if (ctx instanceof RenderBlocksCTM) { rb.submap = ((RenderBlocksCTM) ctx).submap; rb.submapSmall = ((RenderBlocksCTM) ctx).submapSmall; + } else { + rb.submap = null; + rb.submapSmall = null; } + return rb; } }