Skip to content

Commit 6efa211

Browse files
Fix z-fighting for voidstone blocks (#71)
Co-authored-by: Martin Robertz <dream-master@gmx.net>
1 parent c3e1675 commit 6efa211

File tree

4 files changed

+100
-65
lines changed

4 files changed

+100
-65
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ whitelist.json
2828
src/main/resources/mixins.*.json
2929
*.bat
3030
layout.json
31+
.DS_Store

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ developmentEnvironmentUserName = Developer
4141

4242
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
4343
# See https://github.com/bsideup/jabel for details on how this works.
44-
enableModernJavaSyntax = false
44+
enableModernJavaSyntax = true
4545

4646
# Enables injecting missing generics into the decompiled source code for a better coding experience.
4747
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.

src/main/java/team/chisel/client/render/SubmapManagerVoidstone.java

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,91 +21,81 @@ public class SubmapManagerVoidstone extends SubmapManagerBase {
2121

2222
// TODO there must be a better more generic way to do this...
2323
@SideOnly(Side.CLIENT)
24-
private class RenderBlocksVoidstone extends RenderBlocksCTM {
24+
private static class RenderBlocksVoidstone extends RenderBlocksCTM {
2525

2626
@Override
2727
public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon) {
28-
super.renderFaceXNeg(block, x, y, z, icon);
29-
renderMinX += 0.005;
3028
setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.WEST.ordinal()));
3129
super.renderFaceXNeg(block, x, y, z, null);
3230
clearOverrideBlockTexture();
31+
32+
super.renderFaceXNeg(block, x, y, z, icon);
3333
}
3434

3535
@Override
3636
public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon) {
37-
super.renderFaceXPos(block, x, y, z, icon);
3837
setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.EAST.ordinal()));
39-
renderMaxX -= 0.005;
4038
super.renderFaceXPos(block, x, y, z, null);
4139
clearOverrideBlockTexture();
40+
41+
super.renderFaceXPos(block, x, y, z, icon);
4242
}
4343

4444
@Override
4545
public void renderFaceYNeg(Block block, double x, double y, double z, IIcon icon) {
46-
super.renderFaceYNeg(block, x, y, z, icon);
4746
setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.DOWN.ordinal()));
48-
renderMinY += 0.005;
4947
super.renderFaceYNeg(block, x, y, z, null);
5048
clearOverrideBlockTexture();
49+
50+
super.renderFaceYNeg(block, x, y, z, icon);
5151
}
5252

5353
@Override
5454
public void renderFaceYPos(Block block, double x, double y, double z, IIcon icon) {
55-
super.renderFaceYPos(block, x, y, z, icon);
5655
setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.UP.ordinal()));
57-
renderMaxY -= 0.005;
5856
super.renderFaceYPos(block, x, y, z, null);
5957
clearOverrideBlockTexture();
58+
59+
super.renderFaceYPos(block, x, y, z, icon);
6060
}
6161

6262
@Override
6363
public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) {
64-
super.renderFaceZNeg(block, x, y, z, icon);
6564
setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.NORTH.ordinal()));
66-
renderMinZ += 0.005;
6765
super.renderFaceZNeg(block, x, y, z, null);
6866
clearOverrideBlockTexture();
67+
68+
super.renderFaceZNeg(block, x, y, z, icon);
6969
}
7070

7171
@Override
7272
public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon) {
73-
super.renderFaceZPos(block, x, y, z, icon);
7473
setOverrideBlockTexture(getBase(x, y, z, ForgeDirection.SOUTH.ordinal()));
75-
renderMaxZ -= 0.005;
7674
super.renderFaceZPos(block, x, y, z, null);
7775
clearOverrideBlockTexture();
76+
77+
super.renderFaceZPos(block, x, y, z, icon);
7878
}
7979

80-
public void reset() {
81-
this.submap = null;
80+
private IIcon getBase(double x, double y, double z, int side) {
81+
return TextureType.getVIcon(
82+
TextureType.V4,
83+
base,
84+
MathHelper.floor_double(x),
85+
MathHelper.floor_double(y),
86+
MathHelper.floor_double(z),
87+
side);
8288
}
8389
}
8490

8591
@SideOnly(Side.CLIENT)
8692
private static ThreadLocal<RenderBlocksVoidstone> renderBlocksThreadLocal;
8793

88-
private static void initStatics() {
89-
if (renderBlocksThreadLocal == null) {
90-
renderBlocksThreadLocal = new ThreadLocal<>();
91-
}
92-
}
93-
9494
private ISubmapManager overlay;
95-
private TextureSubmap base;
96-
97-
private IIcon getBase(double x, double y, double z, int side) {
98-
return TextureType.getVIcon(
99-
TextureType.V4,
100-
base,
101-
MathHelper.floor_double(x),
102-
MathHelper.floor_double(y),
103-
MathHelper.floor_double(z),
104-
side);
105-
}
95+
private static TextureSubmap base;
10696

107-
private String texture;
108-
private int meta;
97+
private final String texture;
98+
private final int meta;
10999

110100
public SubmapManagerVoidstone(String texture, int meta) {
111101
this.texture = texture;
@@ -133,18 +123,22 @@ public void registerIcons(String modName, Block block, IIconRegister register) {
133123
@Override
134124
@SideOnly(Side.CLIENT)
135125
public RenderBlocks createRenderContext(RenderBlocks rendererOld, Block block, IBlockAccess world) {
136-
initStatics();
126+
if (renderBlocksThreadLocal == null) {
127+
renderBlocksThreadLocal = ThreadLocal.withInitial(RenderBlocksVoidstone::new);
128+
}
129+
137130
RenderBlocksVoidstone rb = renderBlocksThreadLocal.get();
138-
if (rb == null) {
139-
rb = new RenderBlocksVoidstone();
140-
renderBlocksThreadLocal.set(rb);
141-
} else rb.reset();
142131
RenderBlocks ctx = overlay.createRenderContext(rendererOld, block, world);
143132
rb.setRenderBoundsFromBlock(block);
133+
144134
if (ctx instanceof RenderBlocksCTM) {
145135
rb.submap = ((RenderBlocksCTM) ctx).submap;
146136
rb.submapSmall = ((RenderBlocksCTM) ctx).submapSmall;
137+
} else {
138+
rb.submap = null;
139+
rb.submapSmall = null;
147140
}
141+
148142
return rb;
149143
}
150144
}

src/main/java/team/chisel/ctmlib/RenderBlocksCTM.java

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,61 @@ private int avg(int... lightVals) {
361361

362362
protected void side(Block block, SubSide side, int iconIndex) {
363363

364+
// If we have an overridden texture when we're supposed to render a CTM texture,
365+
// we'll treat it as a normal block texture but still render it the CTM way: quarter of a texture at a time.
366+
// This way has one benefit: if an overridden texture is a base block texture and a CTM texture (that is being
367+
// rendered next) is an overlay texture above the base, we're avoiding any z-fighting issues because we
368+
// create identical vertices and now only order of rendering dictates which texture will be rendered above
369+
if (hasOverrideBlockTexture()) {
370+
IIcon icon = overrideBlockTexture;
371+
372+
double u0 = icon.getMinU();
373+
double u1 = icon.getMaxU();
374+
double v0 = icon.getMinV();
375+
double v1 = icon.getMaxV();
376+
377+
double uMid = (u0 + u1) / 2;
378+
double vMid = (v0 + v1) / 2;
379+
380+
// Map all LB-style subsides to bottom-left quarter, RB to bottom-right, RT to top-right, LT to top-left
381+
switch (side) {
382+
// bottom-left quarter
383+
case XNEG_LB, XPOS_LB, YNEG_LB, YPOS_LB, ZNEG_LB, ZPOS_LB -> {
384+
minU = u0;
385+
maxU = uMid;
386+
minV = vMid;
387+
maxV = v1;
388+
}
389+
390+
// bottom-right quarter
391+
case XNEG_RB, XPOS_RB, YNEG_RB, YPOS_RB, ZNEG_RB, ZPOS_RB -> {
392+
minU = uMid;
393+
maxU = u1;
394+
minV = vMid;
395+
maxV = v1;
396+
}
397+
398+
// top-right quarter
399+
case XNEG_RT, XPOS_RT, YNEG_RT, YPOS_RT, ZNEG_RT, ZPOS_RT -> {
400+
minU = uMid;
401+
maxU = u1;
402+
minV = v0;
403+
maxV = vMid;
404+
}
405+
406+
// top-left quarter
407+
case XNEG_LT, XPOS_LT, YNEG_LT, YPOS_LT, ZNEG_LT, ZPOS_LT -> {
408+
minU = u0;
409+
maxU = uMid;
410+
minV = v0;
411+
maxV = vMid;
412+
}
413+
}
414+
415+
side.render(this);
416+
return;
417+
}
418+
364419
IIcon icon;
365420
TextureSubmap map;
366421
if (iconIndex >= 16) {
@@ -378,33 +433,18 @@ protected void side(Block block, SubSide side, int iconIndex) {
378433
icon = map.getSubIcon(x, y);
379434
}
380435

381-
double umax = icon.getMaxU();
382-
double umin = icon.getMinU();
383-
double vmax = icon.getMaxV();
384-
double vmin = icon.getMinV();
385-
386-
minU = umin;
387-
maxU = umax;
388-
minV = vmin;
389-
maxV = vmax;
390-
391-
// uCache[0] = umin;
392-
// uCache[1] = umax;
393-
// uCache[2] = umax;
394-
// uCache[3] = umin;
395-
//
396-
// vCache[0] = vmax;
397-
// vCache[1] = vmax;
398-
// vCache[2] = vmin;
399-
// vCache[3] = vmin;
436+
minU = icon.getMinU();
437+
maxU = icon.getMaxU();
438+
minV = icon.getMinV();
439+
maxV = icon.getMaxV();
400440

401441
side.render(this);
402442
}
403443

404444
@Override
405445
public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon) {
406446
pre(ForgeDirection.WEST);
407-
if (!inWorld || hasOverrideBlockTexture() || submap == null) {
447+
if (!inWorld || submap == null) {
408448
super.renderFaceXNeg(block, 0, 0, 0, icon);
409449
} else {
410450
int tex[] = ctm.getSubmapIndices(blockAccess, bx, by, bz, 4);
@@ -429,7 +469,7 @@ public void renderFaceXNeg(Block block, double x, double y, double z, IIcon icon
429469
@Override
430470
public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon) {
431471
pre(ForgeDirection.EAST);
432-
if (!inWorld || hasOverrideBlockTexture() || submap == null) {
472+
if (!inWorld || submap == null) {
433473
super.renderFaceXPos(block, 0, 0, 0, icon);
434474
} else {
435475
int tex[] = ctm.getSubmapIndices(blockAccess, bx, by, bz, 5);
@@ -454,7 +494,7 @@ public void renderFaceXPos(Block block, double x, double y, double z, IIcon icon
454494
@Override
455495
public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon) {
456496
pre(ForgeDirection.NORTH);
457-
if (!inWorld || hasOverrideBlockTexture() || submap == null) {
497+
if (!inWorld || submap == null) {
458498
super.renderFaceZNeg(block, 0, 0, 0, icon);
459499
} else {
460500
int tex[] = ctm.getSubmapIndices(blockAccess, bx, by, bz, 2);
@@ -479,7 +519,7 @@ public void renderFaceZNeg(Block block, double x, double y, double z, IIcon icon
479519
@Override
480520
public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon) {
481521
pre(ForgeDirection.SOUTH);
482-
if (!inWorld || hasOverrideBlockTexture() || submap == null) {
522+
if (!inWorld || submap == null) {
483523
super.renderFaceZPos(block, 0, 0, 0, icon);
484524
} else {
485525
int tex[] = ctm.getSubmapIndices(blockAccess, bx, by, bz, 3);
@@ -504,7 +544,7 @@ public void renderFaceZPos(Block block, double x, double y, double z, IIcon icon
504544
@Override
505545
public void renderFaceYNeg(Block block, double x, double y, double z, IIcon icon) {
506546
pre(ForgeDirection.DOWN);
507-
if (!inWorld || hasOverrideBlockTexture() || submap == null) {
547+
if (!inWorld || submap == null) {
508548
super.renderFaceYNeg(block, 0, 0, 0, icon);
509549
} else {
510550
int tex[] = ctm.getSubmapIndices(blockAccess, bx, by, bz, 0);
@@ -529,7 +569,7 @@ public void renderFaceYNeg(Block block, double x, double y, double z, IIcon icon
529569
@Override
530570
public void renderFaceYPos(Block block, double x, double y, double z, IIcon icon) {
531571
pre(ForgeDirection.UP);
532-
if (!inWorld || hasOverrideBlockTexture() || submap == null) {
572+
if (!inWorld || submap == null) {
533573
super.renderFaceYPos(block, 0, 0, 0, icon);
534574
} else {
535575
int tex[] = ctm.getSubmapIndices(blockAccess, bx, by, bz, 1);

0 commit comments

Comments
 (0)