From 669c748bd1098127ddab305c78410c43335b7e07 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Tue, 21 May 2024 17:22:47 -0700 Subject: [PATCH] Fully fix unshaded geometry in SBBs --- build.gradle | 2 + .../render/ContraptionRenderInfo.java | 24 +--- .../schematics/client/SchematicRenderer.java | 24 +--- .../mixin/accessor/BufferBuilderAccessor.java | 12 ++ .../ponder/element/WorldSectionElement.java | 40 +++--- .../render/ShadeSeparatingVertexConsumer.java | 84 ------------ .../render/ShadedBlockSbbBuilder.java | 126 ++++++++++++++++++ .../foundation/render/SuperByteBuffer.java | 22 ++- .../render/VirtualRenderHelper.java | 62 +++------ .../debugInfo/DebugInformation.java | 3 +- src/main/resources/create.mixins.json | 1 + 11 files changed, 203 insertions(+), 197 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/accessor/BufferBuilderAccessor.java delete mode 100644 src/main/java/com/simibubi/create/foundation/render/ShadeSeparatingVertexConsumer.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/ShadedBlockSbbBuilder.java diff --git a/build.gradle b/build.gradle index 7a0efbe29..c2368d2a1 100644 --- a/build.gradle +++ b/build.gradle @@ -177,6 +177,8 @@ dependencies { // implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false } // runtimeOnly fg.deobf("maven.modrinth:aether:1.19.2-1.0.0-beta.1.1-forge") // runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge") + // runtimeOnly fg.deobf("curse.maven:xycraft-653786:4788862") + // runtimeOnly fg.deobf("curse.maven:xycraft-world-653789:4788863") // https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497 // Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings diff --git a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionRenderInfo.java b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionRenderInfo.java index 9ecb73829..470e9d86c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionRenderInfo.java +++ b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionRenderInfo.java @@ -4,18 +4,14 @@ import org.apache.commons.lang3.tuple.Pair; import com.jozufozu.flywheel.api.visualization.VisualizationManager; import com.jozufozu.flywheel.lib.model.ModelUtil; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexFormat; import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks; import com.simibubi.create.content.contraptions.ContraptionWorld; -import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer; +import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBufferCache; -import com.simibubi.create.foundation.render.VirtualRenderHelper; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import net.minecraft.client.renderer.RenderType; @@ -115,13 +111,8 @@ public class ContraptionRenderInfo { RandomSource random = objects.random; RenderedBlocks blocks = contraption.getRenderedBlocks(); - ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; - BufferBuilder shadedBuilder = objects.shadedBuilder; - BufferBuilder unshadedBuilder = objects.unshadedBuilder; - - shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder); + ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder; + sbbBuilder.begin(); ModelBlockRenderer.enableCaching(); for (BlockPos pos : blocks.positions()) { @@ -135,22 +126,19 @@ public class ContraptionRenderInfo { if (model.getRenderTypes(state, random, modelData).contains(layer)) { poseStack.pushPose(); poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); - renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer); + renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, sbbBuilder, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer); poseStack.popPose(); } } } ModelBlockRenderer.clearCache(); - shadeSeparatingWrapper.clear(); - return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder); + return sbbBuilder.end(); } private static class ThreadLocalObjects { public final PoseStack poseStack = new PoseStack(); public final RandomSource random = RandomSource.createNewThreadLocalInstance(); - public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); - public final BufferBuilder shadedBuilder = new BufferBuilder(512); - public final BufferBuilder unshadedBuilder = new BufferBuilder(512); + public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder(); } } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java index 771563a64..d21d3cd91 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java @@ -4,16 +4,12 @@ import java.util.LinkedHashMap; import java.util.Map; import com.jozufozu.flywheel.lib.model.ModelUtil; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexFormat; import com.simibubi.create.content.schematics.SchematicWorld; +import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder; import com.simibubi.create.foundation.render.BlockEntityRenderHelper; -import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.render.VirtualRenderHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; @@ -99,13 +95,8 @@ public class SchematicRenderer { SchematicWorld renderWorld = schematic; BoundingBox bounds = renderWorld.getBounds(); - ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; - BufferBuilder shadedBuilder = objects.shadedBuilder; - BufferBuilder unshadedBuilder = objects.unshadedBuilder; - - shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder); + ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder; + sbbBuilder.begin(); renderWorld.renderMode = true; ModelBlockRenderer.enableCaching(); @@ -124,7 +115,7 @@ public class SchematicRenderer { poseStack.pushPose(); poseStack.translate(localPos.getX(), localPos.getY(), localPos.getZ()); - renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, + renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, sbbBuilder, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, layer); poseStack.popPose(); @@ -134,8 +125,7 @@ public class SchematicRenderer { ModelBlockRenderer.clearCache(); renderWorld.renderMode = false; - shadeSeparatingWrapper.clear(); - return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder); + return sbbBuilder.end(); } private static int getLayerCount() { @@ -147,9 +137,7 @@ public class SchematicRenderer { public final PoseStack poseStack = new PoseStack(); public final RandomSource random = RandomSource.createNewThreadLocalInstance(); public final BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); - public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); - public final BufferBuilder shadedBuilder = new BufferBuilder(512); - public final BufferBuilder unshadedBuilder = new BufferBuilder(512); + public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder(); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/accessor/BufferBuilderAccessor.java b/src/main/java/com/simibubi/create/foundation/mixin/accessor/BufferBuilderAccessor.java new file mode 100644 index 000000000..22df2610c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/accessor/BufferBuilderAccessor.java @@ -0,0 +1,12 @@ +package com.simibubi.create.foundation.mixin.accessor; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import com.mojang.blaze3d.vertex.BufferBuilder; + +@Mixin(BufferBuilder.class) +public interface BufferBuilderAccessor { + @Accessor("vertices") + int create$getVertices(); +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/element/WorldSectionElement.java b/src/main/java/com/simibubi/create/foundation/ponder/element/WorldSectionElement.java index 395fb4c13..27eb93da9 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/element/WorldSectionElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/element/WorldSectionElement.java @@ -8,23 +8,19 @@ import java.util.function.Consumer; import com.jozufozu.flywheel.lib.model.ModelUtil; import com.jozufozu.flywheel.lib.transform.TransformStack; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator; import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.blaze3d.vertex.VertexFormat; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.outliner.AABBOutline; import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderWorld; import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder; import com.simibubi.create.foundation.render.BlockEntityRenderHelper; -import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.render.VirtualRenderHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.VecHelper; @@ -415,13 +411,8 @@ public class WorldSectionElement extends AnimatedSceneElement { PoseStack poseStack = objects.poseStack; RandomSource random = objects.random; - ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; - BufferBuilder shadedBuilder = objects.shadedBuilder; - BufferBuilder unshadedBuilder = objects.unshadedBuilder; - - shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder); + ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder; + sbbBuilder.begin(); world.setMask(this.section); ModelBlockRenderer.enableCaching(); @@ -429,8 +420,11 @@ public class WorldSectionElement extends AnimatedSceneElement { BlockState state = world.getBlockState(pos); FluidState fluidState = world.getFluidState(pos); - poseStack.pushPose(); - poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); + if (!fluidState.isEmpty() && ItemBlockRenderTypes.getRenderLayer(fluidState) == layer) { + // FIXME: The fluid renderer modulos translation to 0-15 on all axes, + // so fluids at positions outside this range will render at the wrong spot. + dispatcher.renderLiquid(pos, world, sbbBuilder.unwrap(true), state, fluidState); + } if (state.getRenderShape() == RenderShape.MODEL) { BakedModel model = dispatcher.getBlockModel(state); @@ -439,30 +433,26 @@ public class WorldSectionElement extends AnimatedSceneElement { modelData = model.getModelData(world, pos, state, modelData); long seed = state.getSeed(pos); random.setSeed(seed); + if (model.getRenderTypes(state, random, modelData).contains(layer)) { - renderer.tesselateBlock(world, model, state, pos, poseStack, shadeSeparatingWrapper, true, + poseStack.pushPose(); + poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); + renderer.tesselateBlock(world, model, state, pos, poseStack, sbbBuilder, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, layer); + poseStack.popPose(); } } - - if (!fluidState.isEmpty() && ItemBlockRenderTypes.getRenderLayer(fluidState) == layer) - dispatcher.renderLiquid(pos, world, shadedBuilder, state, fluidState); - - poseStack.popPose(); }); ModelBlockRenderer.clearCache(); world.clearMask(); - shadeSeparatingWrapper.clear(); - return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder); + return sbbBuilder.end(); } private static class ThreadLocalObjects { public final PoseStack poseStack = new PoseStack(); public final RandomSource random = RandomSource.createNewThreadLocalInstance(); - public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); - public final BufferBuilder shadedBuilder = new BufferBuilder(512); - public final BufferBuilder unshadedBuilder = new BufferBuilder(512); + public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder(); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/ShadeSeparatingVertexConsumer.java b/src/main/java/com/simibubi/create/foundation/render/ShadeSeparatingVertexConsumer.java deleted file mode 100644 index fd537ba12..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/ShadeSeparatingVertexConsumer.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.simibubi.create.foundation.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.renderer.block.model.BakedQuad; - -public class ShadeSeparatingVertexConsumer implements VertexConsumer { - protected VertexConsumer shadedConsumer; - protected VertexConsumer unshadedConsumer; - - public void prepare(VertexConsumer shadedConsumer, VertexConsumer unshadedConsumer) { - this.shadedConsumer = shadedConsumer; - this.unshadedConsumer = unshadedConsumer; - } - - public void clear() { - shadedConsumer = null; - unshadedConsumer = null; - } - - @Override - public void putBulkData(PoseStack.Pose poseEntry, BakedQuad quad, float[] colorMuls, float red, float green, float blue, int[] combinedLights, int combinedOverlay, boolean mulColor) { - if (quad.isShade()) { - shadedConsumer.putBulkData(poseEntry, quad, colorMuls, red, green, blue, combinedLights, combinedOverlay, mulColor); - } else { - unshadedConsumer.putBulkData(poseEntry, quad, colorMuls, red, green, blue, combinedLights, combinedOverlay, mulColor); - } - } - - @Override - public void putBulkData(PoseStack.Pose matrixEntry, BakedQuad bakedQuad, float[] baseBrightness, float red, float green, float blue, float alpha, int[] lightmapCoords, int overlayCoords, boolean readExistingColor) { - if (bakedQuad.isShade()) { - shadedConsumer.putBulkData(matrixEntry, bakedQuad, baseBrightness, red, green, blue, alpha, lightmapCoords, overlayCoords, readExistingColor); - } else { - unshadedConsumer.putBulkData(matrixEntry, bakedQuad, baseBrightness, red, green, blue, alpha, lightmapCoords, overlayCoords, readExistingColor); - } - } - - @Override - public VertexConsumer vertex(double x, double y, double z) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public VertexConsumer color(int red, int green, int blue, int alpha) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public VertexConsumer uv(float u, float v) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public VertexConsumer overlayCoords(int u, int v) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public VertexConsumer uv2(int u, int v) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public VertexConsumer normal(float x, float y, float z) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public void endVertex() { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public void defaultColor(int red, int green, int blue, int alpha) { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } - - @Override - public void unsetDefaultColor() { - throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!"); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/ShadedBlockSbbBuilder.java b/src/main/java/com/simibubi/create/foundation/render/ShadedBlockSbbBuilder.java new file mode 100644 index 000000000..aa212b419 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/ShadedBlockSbbBuilder.java @@ -0,0 +1,126 @@ +package com.simibubi.create.foundation.render; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.blaze3d.vertex.VertexFormat; +import com.simibubi.create.foundation.mixin.accessor.BufferBuilderAccessor; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.client.renderer.block.model.BakedQuad; + +public class ShadedBlockSbbBuilder implements VertexConsumer { + protected final BufferBuilder bufferBuilder; + protected final IntList shadeSwapVertices = new IntArrayList(); + protected boolean currentShade; + + public ShadedBlockSbbBuilder(BufferBuilder bufferBuilder) { + this.bufferBuilder = bufferBuilder; + } + + public ShadedBlockSbbBuilder() { + this(new BufferBuilder(512)); + } + + public void begin() { + bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); + shadeSwapVertices.clear(); + currentShade = true; + } + + public SuperByteBuffer end() { + RenderedBuffer data = bufferBuilder.end(); + int vertexCount = data.drawState().vertexCount(); + MutableTemplateMesh mutableMesh = new MutableTemplateMesh(vertexCount); + VirtualRenderHelper.transferBlockVertexData(data.vertexBuffer(), data.drawState().format().getVertexSize(), 0, mutableMesh, 0, vertexCount); + return new SuperByteBuffer(mutableMesh.toImmutable(), shadeSwapVertices.toIntArray()); + } + + public BufferBuilder unwrap(boolean shade) { + prepareForGeometry(shade); + return bufferBuilder; + } + + private void prepareForGeometry(boolean shade) { + if (shade != currentShade) { + shadeSwapVertices.add(((BufferBuilderAccessor) bufferBuilder).create$getVertices()); + currentShade = shade; + } + } + + private void prepareForGeometry(BakedQuad quad) { + prepareForGeometry(quad.isShade()); + } + + @Override + public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, int light, int overlay) { + prepareForGeometry(quad); + bufferBuilder.putBulkData(pose, quad, red, green, blue, light, overlay); + } + + @Override + public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int light, int overlay, boolean readExistingColor) { + prepareForGeometry(quad); + bufferBuilder.putBulkData(pose, quad, red, green, blue, alpha, light, overlay, readExistingColor); + } + + @Override + public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightnesses, float red, float green, float blue, int[] lights, int overlay, boolean readExistingColor) { + prepareForGeometry(quad); + bufferBuilder.putBulkData(pose, quad, brightnesses, red, green, blue, lights, overlay, readExistingColor); + } + + @Override + public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightnesses, float red, float green, float blue, float alpha, int[] lights, int overlay, boolean readExistingColor) { + prepareForGeometry(quad); + bufferBuilder.putBulkData(pose, quad, brightnesses, red, green, blue, alpha, lights, overlay, readExistingColor); + } + + @Override + public VertexConsumer vertex(double x, double y, double z) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public VertexConsumer color(int red, int green, int blue, int alpha) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public VertexConsumer uv(float u, float v) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public VertexConsumer overlayCoords(int u, int v) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public VertexConsumer uv2(int u, int v) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public VertexConsumer normal(float x, float y, float z) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public void endVertex() { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public void defaultColor(int red, int green, int blue, int alpha) { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } + + @Override + public void unsetDefaultColor() { + throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!"); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java b/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java index a68ec0302..c6b5472db 100644 --- a/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java @@ -25,7 +25,7 @@ import net.minecraft.world.level.Level; public class SuperByteBuffer implements TransformStack { private final TemplateMesh template; - private final int unshadedStartVertex; + private final int[] shadeSwapVertices; // Vertex Position and Normals private final PoseStack transforms = new PoseStack(); @@ -52,13 +52,17 @@ public class SuperByteBuffer implements TransformStack { // Temporary private static final Long2IntMap WORLD_LIGHT_CACHE = new Long2IntOpenHashMap(); - public SuperByteBuffer(TemplateMesh template, int unshadedStartVertex) { + public SuperByteBuffer(TemplateMesh template, int[] shadeSwapVertices) { this.template = template; - this.unshadedStartVertex = unshadedStartVertex; + this.shadeSwapVertices = shadeSwapVertices; transforms.pushPose(); } + public SuperByteBuffer(TemplateMesh template) { + this(template, new int[0]); + } + public void renderInto(PoseStack input, VertexConsumer builder) { if (isEmpty()) return; @@ -105,8 +109,18 @@ public class SuperByteBuffer implements TransformStack { } } + boolean shaded = true; + int shadeSwapIndex = 0; + int nextShadeSwapVertex = shadeSwapIndex < shadeSwapVertices.length ? shadeSwapVertices[shadeSwapIndex] : -1; + final int vertexCount = template.vertexCount(); for (int i = 0; i < vertexCount; i++) { + if (i == nextShadeSwapVertex) { + shaded = !shaded; + shadeSwapIndex++; + nextShadeSwapVertex = shadeSwapIndex < shadeSwapVertices.length ? shadeSwapVertices[shadeSwapIndex] : -1; + } + float x = template.x(i); float y = template.y(i); float z = template.z(i); @@ -139,7 +153,7 @@ public class SuperByteBuffer implements TransformStack { if (!disableDiffuseMult) { // Transformed normal is in camera space, but it is needed in world space to calculate diffuse. normal.mul(RenderSystem.getInverseViewRotationMatrix()); - float diffuse = diffuseCalculator.getDiffuse(normal.x(), normal.y(), normal.z(), i < unshadedStartVertex); + float diffuse = diffuseCalculator.getDiffuse(normal.x(), normal.y(), normal.z(), shaded); r *= diffuse; g *= diffuse; b *= diffuse; diff --git a/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java b/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java index 41c4db856..bf647fd2f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java @@ -9,11 +9,7 @@ import com.jozufozu.flywheel.lib.model.ModelCache; import com.jozufozu.flywheel.lib.model.ModelUtil; import com.jozufozu.flywheel.lib.model.baked.ForgeBakedModelBuilder; import com.jozufozu.flywheel.lib.model.baked.VirtualEmptyBlockGetter; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.block.ModelBlockRenderer; @@ -63,62 +59,34 @@ public class VirtualRenderHelper { } RandomSource random = objects.random; - ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; - BufferBuilder shadedBuilder = objects.shadedBuilder; - BufferBuilder unshadedBuilder = objects.unshadedBuilder; - - shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder); + ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder; + sbbBuilder.begin(); ModelData modelData = model.getModelData(VirtualEmptyBlockGetter.INSTANCE, BlockPos.ZERO, state, VIRTUAL_DATA); poseStack.pushPose(); - renderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, state, BlockPos.ZERO, poseStack, shadeSeparatingWrapper, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, null); + renderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, state, BlockPos.ZERO, poseStack, sbbBuilder, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, null); poseStack.popPose(); - shadeSeparatingWrapper.clear(); - return endAndCombine(shadedBuilder, unshadedBuilder); + return sbbBuilder.end(); } - public static void transferBlockVertexData(ByteBuffer vertexBuffer, int vertexCount, int stride, MutableTemplateMesh mutableMesh, int dstIndex) { + public static void transferBlockVertexData(ByteBuffer vertexBuffer, int stride, int srcIndex, MutableTemplateMesh mutableMesh, int dstIndex, int vertexCount) { for (int i = 0; i < vertexCount; i++) { - mutableMesh.x(i, vertexBuffer.getFloat(i * stride)); - mutableMesh.y(i, vertexBuffer.getFloat(i * stride + 4)); - mutableMesh.z(i, vertexBuffer.getFloat(i * stride + 8)); - mutableMesh.color(i, vertexBuffer.getInt(i * stride + 12)); - mutableMesh.u(i, vertexBuffer.getFloat(i * stride + 16)); - mutableMesh.v(i, vertexBuffer.getFloat(i * stride + 20)); - mutableMesh.overlay(i, OverlayTexture.NO_OVERLAY); - mutableMesh.light(i, vertexBuffer.getInt(i * stride + 24)); - mutableMesh.normal(i, vertexBuffer.getInt(i * stride + 28)); + mutableMesh.x(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride)); + mutableMesh.y(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 4)); + mutableMesh.z(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 8)); + mutableMesh.color(dstIndex + i, vertexBuffer.getInt(srcIndex + i * stride + 12)); + mutableMesh.u(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 16)); + mutableMesh.v(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 20)); + mutableMesh.overlay(dstIndex + i, OverlayTexture.NO_OVERLAY); + mutableMesh.light(dstIndex + i, vertexBuffer.getInt(srcIndex + i * stride + 24)); + mutableMesh.normal(dstIndex + i, vertexBuffer.getInt(srcIndex + i * stride + 28)); } } - public static SuperByteBuffer endAndCombine(BufferBuilder shadedBuilder, BufferBuilder unshadedBuilder) { - RenderedBuffer shadedData = shadedBuilder.end(); - int totalVertexCount = shadedData.drawState().vertexCount(); - int unshadedStartVertex = totalVertexCount; - RenderedBuffer unshadedData = unshadedBuilder.endOrDiscardIfEmpty(); - if (unshadedData != null) { - if (shadedData.drawState().format() != unshadedData.drawState().format()) { - throw new IllegalStateException("Buffer formats are not equal!"); - } - totalVertexCount += unshadedData.drawState().vertexCount(); - } - - MutableTemplateMesh mutableMesh = new MutableTemplateMesh(totalVertexCount); - transferBlockVertexData(shadedData.vertexBuffer(), shadedData.drawState().vertexCount(), shadedData.drawState().format().getVertexSize(), mutableMesh, 0); - if (unshadedData != null) { - transferBlockVertexData(unshadedData.vertexBuffer(), unshadedData.drawState().vertexCount(), unshadedData.drawState().format().getVertexSize(), mutableMesh, unshadedStartVertex); - } - return new SuperByteBuffer(mutableMesh.toImmutable(), unshadedStartVertex); - } - private static class ThreadLocalObjects { public final PoseStack identityPoseStack = new PoseStack(); public final RandomSource random = RandomSource.createNewThreadLocalInstance(); - public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); - public final BufferBuilder shadedBuilder = new BufferBuilder(512); - public final BufferBuilder unshadedBuilder = new BufferBuilder(512); + public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder(); } } diff --git a/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java b/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java index 3d8b27655..68f881ec2 100644 --- a/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java +++ b/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java @@ -10,6 +10,7 @@ import javax.annotation.Nullable; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.api.Flywheel; +import com.jozufozu.flywheel.api.backend.Backend; import com.jozufozu.flywheel.api.backend.BackendManager; import com.mojang.blaze3d.platform.GlUtil; import com.simibubi.create.Create; @@ -79,7 +80,7 @@ public class DebugInformation { .getVersion() .toString()) .orElse("None")) - .put("Flywheel Backend", () -> BackendManager.getBackend().toString()) + .put("Flywheel Backend", () -> Backend.REGISTRY.getIdOrThrow(BackendManager.getBackend()).toString()) .put("OpenGL Renderer", GlUtil::getRenderer) .put("OpenGL Version", GlUtil::getOpenGLVersion) .put("Graphics Mode", () -> Minecraft.getInstance().options.graphicsMode().toString()) diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 1a247911b..8bfa48c30 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -27,6 +27,7 @@ ], "client": [ "accessor.AgeableListModelAccessor", + "accessor.BufferBuilderAccessor", "accessor.GameRendererAccessor", "accessor.HumanoidArmorLayerAccessor", "accessor.ParticleEngineAccessor",