From 0c74be53f6feef64a41c73ece5332e85e1967924 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 18 Feb 2022 20:39:19 -0800 Subject: [PATCH] Add partial support for non-shaded quads - Add ShadeSeparatedBufferBuilder and other code to allow separating all non-shaded vertices to the end of the buffer - Add ShadedVertexList to allow defining if a certain vertex is shaded or not - Add new methods to ModelUtil with arguments for more flexibility - Refactor VirtualEmptyBlockGetter to allow defining arbitrary light values - Add shaded argument to DiffuseLightCalculator --- .../flywheel/api/vertex/ShadedVertexList.java | 5 + .../backend/model/BufferBuilderExtension.java | 10 ++ .../jozufozu/flywheel/core/model/Model.java | 2 +- .../flywheel/core/model/ModelTransformer.java | 11 +- .../flywheel/core/model/ModelUtil.java | 62 +++++-- .../model/ShadeSeparatedBufferBuilder.java | 25 +++ .../model/ShadeSeparatingVertexConsumer.java | 84 +++++++++ .../flywheel/core/vertex/BlockVertex.java | 11 +- .../flywheel/core/vertex/BlockVertexList.java | 18 ++ .../core/vertex/BlockVertexListUnsafe.java | 18 ++ .../core/virtual/VirtualEmptyBlockGetter.java | 162 +++++++++--------- .../flywheel/mixin/BufferBuilderMixin.java | 52 +++++- .../flywheel/util/DiffuseLightCalculator.java | 5 +- .../jozufozu/flywheel/util/RenderMath.java | 14 +- 14 files changed, 371 insertions(+), 108 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/vertex/ShadedVertexList.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatingVertexConsumer.java diff --git a/src/main/java/com/jozufozu/flywheel/api/vertex/ShadedVertexList.java b/src/main/java/com/jozufozu/flywheel/api/vertex/ShadedVertexList.java new file mode 100644 index 000000000..227879b3a --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/vertex/ShadedVertexList.java @@ -0,0 +1,5 @@ +package com.jozufozu.flywheel.api.vertex; + +public interface ShadedVertexList extends VertexList { + boolean isShaded(int index); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java b/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java index 87d840792..4aec62268 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java @@ -12,6 +12,8 @@ import com.mojang.blaze3d.vertex.VertexFormat; */ public interface BufferBuilderExtension { + int flywheel$getVertices(); + /** * Frees the internal ByteBuffer, if it exists. */ @@ -24,4 +26,12 @@ public interface BufferBuilderExtension { * @param vertexCount The number of vertices in the buffer. */ void flywheel$injectForRender(ByteBuffer buffer, VertexFormat format, int vertexCount); + + /** + * Appends the remaining bytes from the given buffer to this BufferBuilder. + * @param buffer The buffer from which to copy bytes. + * @throws IllegalStateException If this BufferBuilder is not started or is the process of writing a vertex + * @throws IllegalArgumentException If the given buffer does not contain a whole number of vertices + */ + void flywheel$appendBufferUnsafe(ByteBuffer buffer); } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java index 6d1c2c0c5..eacfd3394 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java @@ -16,7 +16,7 @@ import com.jozufozu.flywheel.core.QuadConverter; *
* *{@code - * IModel model = ...; + * Model model = ...; * VecBuffer into = ...; * * int initial = VecBuffer.unwrap().position(); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java index 10eafd1c4..52e542ec7 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java @@ -1,5 +1,8 @@ package com.jozufozu.flywheel.core.model; +import java.util.function.IntPredicate; + +import com.jozufozu.flywheel.api.vertex.ShadedVertexList; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.DiffuseLightCalculator; import com.jozufozu.flywheel.util.transform.Transform; @@ -19,12 +22,18 @@ public class ModelTransformer { private final Model model; private final VertexList reader; + private final IntPredicate shadedPredicate; public final Context context = new Context(); public ModelTransformer(Model model) { this.model = model; reader = model.getReader(); + if (reader instanceof ShadedVertexList shaded) { + shadedPredicate = shaded::isShaded; + } else { + shadedPredicate = index -> true; + } } public void renderInto(Params params, PoseStack input, VertexConsumer builder) { @@ -82,7 +91,7 @@ public class ModelTransformer { a = reader.getA(i); } if (context.outputColorDiffuse) { - float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz); + float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz, shadedPredicate.test(i)); int colorR = transformColor(r, instanceDiffuse); int colorG = transformColor(g, instanceDiffuse); int colorB = transformColor(b, instanceDiffuse); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index c839e4093..0815adf28 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -38,6 +38,8 @@ public class ModelUtil { */ public static final BlockRenderDispatcher VANILLA_RENDERER = createVanillaRenderer(); + private static final ThreadLocalTHREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); + private static BlockRenderDispatcher createVanillaRenderer() { BlockRenderDispatcher defaultDispatcher = Minecraft.getInstance().getBlockRenderer(); BlockRenderDispatcher dispatcher = new BlockRenderDispatcher(null, null, null); @@ -54,23 +56,47 @@ public class ModelUtil { return dispatcher; } - public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) { + public static ShadeSeparatedBufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) { + return getBufferBuilder(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, poseStack); + } + + public static ShadeSeparatedBufferBuilder getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) { ModelBlockRenderer blockRenderer = VANILLA_RENDERER.getModelRenderer(); - BufferBuilder builder = new BufferBuilder(512); + ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); + + ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; + ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512); + BufferBuilder unshadedBuilder = objects.unshadedBuilder; + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); - blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder, - false, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE); + unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); + shadeSeparatingWrapper.prepare(builder, unshadedBuilder); + blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, shadeSeparatingWrapper, + false, objects.random, 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE); + shadeSeparatingWrapper.clear(); + unshadedBuilder.end(); + builder.appendUnshadedVertices(unshadedBuilder); builder.end(); + return builder; } - public static BufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks) { - ModelBlockRenderer modelRenderer = VANILLA_RENDERER.getModelRenderer(); + public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks) { + return getBufferBuilderFromTemplate(renderWorld, layer, blocks, new PoseStack()); + } + + public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, PoseStack poseStack) { + ModelBlockRenderer modelRenderer = VANILLA_RENDERER.getModelRenderer(); + ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); + + Random random = objects.random; + ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper; + ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512); + BufferBuilder unshadedBuilder = objects.unshadedBuilder; - PoseStack ms = new PoseStack(); - Random random = new Random(); - BufferBuilder builder = new BufferBuilder(512); builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); + unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); + shadeSeparatingWrapper.prepare(builder, unshadedBuilder); ForgeHooksClient.setRenderType(layer); ModelBlockRenderer.enableCaching(); @@ -84,16 +110,20 @@ public class ModelUtil { BlockPos pos = info.pos; - ms.pushPose(); - ms.translate(pos.getX(), pos.getY(), pos.getZ()); - modelRenderer.tesselateBlock(renderWorld, VANILLA_RENDERER.getBlockModel(state), state, pos, ms, builder, + poseStack.pushPose(); + poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); + modelRenderer.tesselateBlock(renderWorld, VANILLA_RENDERER.getBlockModel(state), state, pos, poseStack, shadeSeparatingWrapper, true, random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE); - ms.popPose(); + poseStack.popPose(); } ModelBlockRenderer.clearCache(); ForgeHooksClient.setRenderType(null); + shadeSeparatingWrapper.clear(); + unshadedBuilder.end(); + builder.appendUnshadedVertices(unshadedBuilder); builder.end(); + return builder; } @@ -107,4 +137,10 @@ public class ModelUtil { return stack; }; } + + private static class ThreadLocalObjects { + public final Random random = new Random(); + public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer(); + public final BufferBuilder unshadedBuilder = new BufferBuilder(512); + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java b/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java new file mode 100644 index 000000000..38043702b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java @@ -0,0 +1,25 @@ +package com.jozufozu.flywheel.core.model; + +import java.nio.ByteBuffer; + +import com.jozufozu.flywheel.backend.model.BufferBuilderExtension; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.datafixers.util.Pair; + +public class ShadeSeparatedBufferBuilder extends BufferBuilder { + protected int unshadedStartVertex; + + public ShadeSeparatedBufferBuilder(int capacity) { + super(capacity); + } + + public void appendUnshadedVertices(BufferBuilder unshadedBuilder) { + Pair data = unshadedBuilder.popNextBuffer(); + unshadedStartVertex = ((BufferBuilderExtension) this).flywheel$getVertices(); + ((BufferBuilderExtension) this).flywheel$appendBufferUnsafe(data.getSecond()); + } + + public int getUnshadedStartVertex() { + return unshadedStartVertex; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatingVertexConsumer.java b/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatingVertexConsumer.java new file mode 100644 index 000000000..ea50184a7 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatingVertexConsumer.java @@ -0,0 +1,84 @@ +package com.jozufozu.flywheel.core.model; + +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/jozufozu/flywheel/core/vertex/BlockVertex.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java index e382d0ab7..d74dde894 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java @@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; +import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.datafixers.util.Pair; @@ -57,6 +58,10 @@ Vertex FLWCreateVertex() { """; } + public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) { + return new BlockVertexListUnsafe.Shaded(buffer, vertexCount, unshadedStartVertex); + } + public VertexList createReader(BufferBuilder bufferBuilder) { // TODO: try to avoid virtual model rendering Pair pair = bufferBuilder.popNextBuffer(); @@ -66,6 +71,10 @@ Vertex FLWCreateVertex() { throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format()); } - return new BlockVertexListUnsafe(pair.getSecond(), drawState.vertexCount()); + if (bufferBuilder instanceof ShadeSeparatedBufferBuilder separated) { + return createReader(pair.getSecond(), drawState.vertexCount(), separated.getUnshadedStartVertex()); + } else { + return createReader(pair.getSecond(), drawState.vertexCount()); + } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java index ff4c98126..eaac02cee 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java @@ -2,7 +2,9 @@ package com.jozufozu.flywheel.core.vertex; import java.nio.ByteBuffer; +import com.jozufozu.flywheel.api.vertex.ShadedVertexList; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder; import com.jozufozu.flywheel.util.RenderMath; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.datafixers.util.Pair; @@ -104,4 +106,20 @@ public class BlockVertexList implements VertexList { return vertexCount; } + public static class Shaded extends BlockVertexList implements ShadedVertexList { + + private final int unshadedStartVertex; + + public Shaded(ShadeSeparatedBufferBuilder builder) { + super(builder); + unshadedStartVertex = builder.getUnshadedStartVertex(); + } + + @Override + public boolean isShaded(int index) { + return index < unshadedStartVertex; + } + + } + } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java index 7c93b29d6..0993f29e5 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java @@ -4,6 +4,7 @@ import java.nio.ByteBuffer; import org.lwjgl.system.MemoryUtil; +import com.jozufozu.flywheel.api.vertex.ShadedVertexList; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.util.RenderMath; @@ -97,4 +98,21 @@ public class BlockVertexListUnsafe implements VertexList { public int getVertexCount() { return vertexCount; } + + public static class Shaded extends BlockVertexListUnsafe implements ShadedVertexList { + + private final int unshadedStartVertex; + + public Shaded(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) { + super(buffer, vertexCount); + this.unshadedStartVertex = unshadedStartVertex; + } + + @Override + public boolean isShaded(int index) { + return index < unshadedStartVertex; + } + + } + } diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java index 8058bcf68..ebfbe9389 100644 --- a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java @@ -22,115 +22,119 @@ import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; -public enum VirtualEmptyBlockGetter implements BlockAndTintGetter { - INSTANCE; - - private final LevelLightEngine lightEngine = new LevelLightEngine(new LightChunkGetter() { - @Override - public BlockGetter getChunkForLighting(int p_63023_, int p_63024_) { - return VirtualEmptyBlockGetter.this; - } - - @Override - public BlockGetter getLevel() { - return VirtualEmptyBlockGetter.this; - } - }, false, false) { - private static final LayerLightEventListener SKY_DUMMY_LISTENER = new LayerLightEventListener() { - @Override - public void checkBlock(BlockPos pos) { - } - - @Override - public void onBlockEmissionIncrease(BlockPos pos, int p_164456_) { - } - - @Override - public boolean hasLightWork() { - return false; - } - - @Override - public int runUpdates(int p_164449_, boolean p_164450_, boolean p_164451_) { - return p_164449_; - } - - @Override - public void updateSectionStatus(SectionPos pos, boolean p_75838_) { - } - - @Override - public void enableLightSources(ChunkPos pos, boolean p_164453_) { - } - - @Override - public DataLayer getDataLayerData(SectionPos pos) { - return null; - } - - @Override - public int getLightValue(BlockPos pos) { - return 15; - } - }; - - @Override - public LayerLightEventListener getLayerListener(LightLayer layer) { - if (layer == LightLayer.BLOCK) { - return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE; - } else { - return SKY_DUMMY_LISTENER; - } - } - - @Override - public int getRawBrightness(BlockPos pos, int skyDarken) { - return 15 - skyDarken; - } - }; +public interface VirtualEmptyBlockGetter extends BlockAndTintGetter { + public static final VirtualEmptyBlockGetter INSTANCE = new StaticLightImpl(0, 15); + public static final VirtualEmptyBlockGetter FULL_BRIGHT = new StaticLightImpl(15, 15); + public static final VirtualEmptyBlockGetter FULL_DARK = new StaticLightImpl(0, 0); public static boolean is(BlockAndTintGetter blockGetter) { - return blockGetter == INSTANCE; + return blockGetter instanceof VirtualEmptyBlockGetter; } @Override - public BlockEntity getBlockEntity(BlockPos pos) { + default BlockEntity getBlockEntity(BlockPos pos) { return null; } @Override - public BlockState getBlockState(BlockPos pos) { + default BlockState getBlockState(BlockPos pos) { return Blocks.AIR.defaultBlockState(); } @Override - public FluidState getFluidState(BlockPos pos) { + default FluidState getFluidState(BlockPos pos) { return Fluids.EMPTY.defaultFluidState(); } @Override - public int getHeight() { + default int getHeight() { return 1; } @Override - public int getMinBuildHeight() { + default int getMinBuildHeight() { return 0; } @Override - public float getShade(Direction direction, boolean bool) { + default float getShade(Direction direction, boolean shaded) { return 1f; } @Override - public LevelLightEngine getLightEngine() { - return lightEngine; - } - - @Override - public int getBlockTint(BlockPos pos, ColorResolver resolver) { + default int getBlockTint(BlockPos pos, ColorResolver resolver) { Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(Biomes.PLAINS); return resolver.getColor(plainsBiome, pos.getX(), pos.getZ()); } + + public static class StaticLightImpl implements VirtualEmptyBlockGetter { + private final LevelLightEngine lightEngine; + + public StaticLightImpl(int blockLight, int skyLight) { + lightEngine = new LevelLightEngine(new LightChunkGetter() { + @Override + public BlockGetter getChunkForLighting(int p_63023_, int p_63024_) { + return StaticLightImpl.this; + } + + @Override + public BlockGetter getLevel() { + return StaticLightImpl.this; + } + }, false, false) { + private final LayerLightEventListener blockListener = createStaticListener(blockLight); + private final LayerLightEventListener skyListener = createStaticListener(skyLight); + + @Override + public LayerLightEventListener getLayerListener(LightLayer layer) { + return layer == LightLayer.BLOCK ? blockListener : skyListener; + } + }; + } + + private static LayerLightEventListener createStaticListener(int light) { + return new LayerLightEventListener() { + @Override + public void checkBlock(BlockPos pos) { + } + + @Override + public void onBlockEmissionIncrease(BlockPos pos, int p_164456_) { + } + + @Override + public boolean hasLightWork() { + return false; + } + + @Override + public int runUpdates(int p_164449_, boolean p_164450_, boolean p_164451_) { + return p_164449_; + } + + @Override + public void updateSectionStatus(SectionPos pos, boolean p_75838_) { + } + + @Override + public void enableLightSources(ChunkPos pos, boolean p_164453_) { + } + + @Override + public DataLayer getDataLayerData(SectionPos pos) { + return null; + } + + @Override + public int getLightValue(BlockPos pos) { + return light; + } + }; + } + + @Override + public LevelLightEngine getLightEngine() { + return lightEngine; + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java index 6b13b9a92..bc82deaf8 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java @@ -20,16 +20,10 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension { private ByteBuffer buffer; @Shadow - private boolean building; + private int nextElementByte; @Shadow - public abstract void begin(VertexFormat.Mode p_166780_, VertexFormat p_166781_); - - @Shadow - private VertexFormat.Mode mode; - - @Shadow - private VertexFormat format; + private int vertices; @Shadow @Nullable @@ -39,7 +33,22 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension { private int elementIndex; @Shadow - private int vertices; + private VertexFormat format; + + @Shadow + private VertexFormat.Mode mode; + + @Shadow + private boolean building; + + @Shadow + private void ensureCapacity(int increaseAmount) { + } + + @Override + public int flywheel$getVertices() { + return vertices; + } @Override public void flywheel$freeBuffer() { @@ -61,4 +70,29 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension { this.currentElement = this.format.getElements().get(0); this.elementIndex = 0; } + + @Override + public void flywheel$appendBufferUnsafe(ByteBuffer buffer) { + if (!building) { + throw new IllegalStateException("BufferBuilder not started"); + } + if (elementIndex != 0) { + throw new IllegalStateException("Cannot append buffer while building vertex"); + } + + int numBytes = buffer.remaining(); + if (numBytes % format.getVertexSize() != 0) { + throw new IllegalArgumentException("Cannot append buffer with non-whole number of vertices"); + } + int numVertices = numBytes / format.getVertexSize(); + + ensureCapacity(numBytes + format.getVertexSize()); + int originalPosition = this.buffer.position(); + this.buffer.position(nextElementByte); + MemoryUtil.memCopy(buffer, this.buffer); + this.buffer.position(originalPosition); + + nextElementByte += numBytes; + vertices += numVertices; + } } diff --git a/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java b/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java index d7f712582..4f1ac0557 100644 --- a/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java +++ b/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java @@ -2,10 +2,9 @@ package com.jozufozu.flywheel.util; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraftforge.client.model.pipeline.LightUtil; public interface DiffuseLightCalculator { - DiffuseLightCalculator DEFAULT = LightUtil::diffuseLight; + DiffuseLightCalculator DEFAULT = RenderMath::diffuseLight; DiffuseLightCalculator NETHER = RenderMath::diffuseLightNether; static DiffuseLightCalculator forCurrentLevel() { @@ -16,5 +15,5 @@ public interface DiffuseLightCalculator { return level.effects().constantAmbientLight() ? NETHER : DEFAULT; } - float getDiffuse(float normalX, float normalY, float normalZ); + float getDiffuse(float normalX, float normalY, float normalZ, boolean shaded); } diff --git a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java b/src/main/java/com/jozufozu/flywheel/util/RenderMath.java index f280c2064..9ee9ecddc 100644 --- a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java +++ b/src/main/java/com/jozufozu/flywheel/util/RenderMath.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.util; +import net.minecraftforge.client.model.pipeline.LightUtil; + public class RenderMath { /** @@ -68,7 +70,17 @@ public class RenderMath { return (float) (((((target - current) % 360) + 540) % 360) - 180); } - public static float diffuseLightNether(float x, float y, float z) { + public static float diffuseLight(float x, float y, float z, boolean shaded) { + if (!shaded) { + return 1f; + } + return LightUtil.diffuseLight(x, y, z); + } + + public static float diffuseLightNether(float x, float y, float z, boolean shaded) { + if (!shaded) { + return 0.9f; + } return Math.min(x * x * 0.6f + y * y * 0.9f + z * z * 0.8f, 1f); } }