From ae5853442b0aa60f52f5515d1728044149ec1dc5 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 6 Feb 2022 00:55:49 -0800 Subject: [PATCH 1/4] Small utility functions --- .../com/jozufozu/flywheel/api/Material.java | 5 ++++ .../flywheel/core/materials/FlatLit.java | 9 +++++++ .../flywheel/util/box/GridAlignedBB.java | 25 ++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jozufozu/flywheel/api/Material.java b/src/main/java/com/jozufozu/flywheel/api/Material.java index 252c9fb33..f6a963cf7 100644 --- a/src/main/java/com/jozufozu/flywheel/api/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/Material.java @@ -10,6 +10,7 @@ import com.jozufozu.flywheel.util.Pair; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.core.Direction; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; public interface Material { @@ -26,6 +27,10 @@ public interface Material { return model(partial, () -> new BlockModel(partial.get(), referenceState)); } + default Instancer getModel(PartialModel partial) { + return model(partial, () -> new BlockModel(partial.get(), Blocks.AIR.defaultBlockState())); + } + default Instancer getModel(PartialModel partial, BlockState referenceState, Direction dir) { return getModel(partial, referenceState, dir, ModelUtil.rotateToFace(dir)); } diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java b/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java index 3829a1a84..03fc53174 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java @@ -2,6 +2,10 @@ package com.jozufozu.flywheel.core.materials; import com.jozufozu.flywheel.api.InstanceData; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.LightLayer; + /** * An interface that implementors of {@link InstanceData} should also implement * if they wish to make use of Flywheel's provided light update methods. @@ -25,5 +29,10 @@ public interface FlatLit> { */ D setSkyLight(int skyLight); + default D updateLight(BlockAndTintGetter level, BlockPos pos) { + return setBlockLight(level.getBrightness(LightLayer.BLOCK, pos)) + .setSkyLight(level.getBrightness(LightLayer.SKY, pos)); + } + int getPackedLight(); } diff --git a/src/main/java/com/jozufozu/flywheel/util/box/GridAlignedBB.java b/src/main/java/com/jozufozu/flywheel/util/box/GridAlignedBB.java index fa6925a36..279669f11 100644 --- a/src/main/java/com/jozufozu/flywheel/util/box/GridAlignedBB.java +++ b/src/main/java/com/jozufozu/flywheel/util/box/GridAlignedBB.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.util.box; +import java.util.Collection; + import com.jozufozu.flywheel.util.RenderMath; import net.minecraft.core.BlockPos; @@ -61,7 +63,28 @@ public class GridAlignedBB implements ImmutableBox { return new GridAlignedBB(startX, 0, startZ, startX + 16, 256, startZ + 16); } - public void fixMinMax() { + public static ImmutableBox containingAll(Collection positions) { + if (positions.isEmpty()) { + return new GridAlignedBB(); + } + int minX = Integer.MAX_VALUE; + int minY = Integer.MAX_VALUE; + int minZ = Integer.MAX_VALUE; + int maxX = Integer.MIN_VALUE; + int maxY = Integer.MIN_VALUE; + int maxZ = Integer.MIN_VALUE; + for (BlockPos pos : positions) { + minX = Math.min(minX, pos.getX()); + minY = Math.min(minY, pos.getY()); + minZ = Math.min(minZ, pos.getZ()); + maxX = Math.max(maxX, pos.getX()); + maxY = Math.max(maxY, pos.getY()); + maxZ = Math.max(maxZ, pos.getZ()); + } + return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ); + } + + public void fixMinMax() { int minX = Math.min(this.minX, this.maxX); int minY = Math.min(this.minY, this.maxY); int minZ = Math.min(this.minZ, this.maxZ); From f24c1fafba67ca1bc2ce92a06b83eac95b5ac42f Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Tue, 8 Feb 2022 19:26:36 -0800 Subject: [PATCH 2/4] Add, refactor, remove - Add DiffuseLightCalculator - Add ModelUtil.VANILLA_RENDERER for consistent virtual rendering - Refactor OptifineHandler - Remove MatrixTransformStack --- build.gradle | 8 +- .../jozufozu/flywheel/backend/Backend.java | 4 +- .../flywheel/backend/OptifineHandler.java | 120 +++++++++--------- .../batching/BatchedMaterialGroup.java | 2 +- .../flywheel/core/model/ModelTransformer.java | 51 +++++--- .../flywheel/core/model/ModelUtil.java | 41 +++--- .../flywheel/mixin/ShaderCloseMixin.java | 2 +- .../flywheel/util/DiffuseLightCalculator.java | 20 +++ .../jozufozu/flywheel/util/RenderMath.java | 4 + .../util/transform/MatrixTransformStack.java | 81 ------------ .../flywheel/vanilla/MinecartInstance.java | 36 +++--- .../flywheel/vanilla/ShulkerBoxInstance.java | 21 +-- 12 files changed, 186 insertions(+), 204 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java delete mode 100644 src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java diff --git a/build.gradle b/build.gradle index 12a1dbb04..370b42176 100644 --- a/build.gradle +++ b/build.gradle @@ -24,10 +24,10 @@ apply plugin: 'org.spongepowered.mixin' boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false'); -ext.buildnumber = 0 -project.buildnumber = System.getenv('BUILD_NUMBER') != null ? System.getenv('BUILD_NUMBER') : 'custom' +ext.buildNumber = System.getenv('BUILD_NUMBER') +if (buildNumber == null) buildNumber = 'custom' -version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildnumber}" : '') +version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildNumber}" : '') group = 'com.jozufozu.flywheel' archivesBaseName = 'flywheel-forge' @@ -107,7 +107,7 @@ repositories { dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - compileOnly fg.deobf("curse.maven:starlight-526854:3559934") + compileOnly fg.deobf("curse.maven:starlight-526854:3599856") // 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/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index c6c58f13b..8015949a3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -32,7 +32,7 @@ public class Backend { * (Meshlet, MDI, GL31 Draw Instanced are planned), this will name which one is in use. */ public static String getBackendDescriptor() { - return engine == null ? "" : engine.getProperName(); + return engine == null ? "Uninitialized" : engine.getProperName(); } @Nullable @@ -79,7 +79,7 @@ public class Backend { FlwEngine preferredChoice = FlwConfig.get() .getEngine(); - boolean usingShaders = OptifineHandler.usingShaders(); + boolean usingShaders = OptifineHandler.isUsingShaders(); boolean canUseEngine = switch (preferredChoice) { case OFF -> true; case BATCHING -> !usingShaders; diff --git a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java index 51e60eebe..201438ecd 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java @@ -5,21 +5,26 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Field; -import java.util.Optional; import java.util.function.BooleanSupplier; -import com.jozufozu.flywheel.util.Lazy; +import org.apache.commons.lang3.mutable.MutableInt; import net.minecraft.client.Minecraft; -public class OptifineHandler { +public final class OptifineHandler { public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine"; public static final String SHADER_PACKAGE = "net.optifine.shaders"; - private static Package optifine; - private static OptifineHandler handler; + private static final ThreadLocal FORCE_DIFFUSE = ThreadLocal.withInitial(MutableInt::new); - private static final Lazy isShadowPass = Lazy.of(() -> { + private static boolean isOptifineInstalled; + private static boolean isUsingShaders; + private static BooleanSupplier shadowPassSupplier; + + private OptifineHandler() { + } + + private static BooleanSupplier createShadowPassSupplier() { try { Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); Field field = ofShaders.getDeclaredField("isShadowPass"); @@ -34,55 +39,6 @@ public class OptifineHandler { } catch (Exception ignored) { return () -> false; } - }); - - public final boolean usingShaders; - - public OptifineHandler(boolean usingShaders) { - this.usingShaders = usingShaders; - } - - /** - * Get information about the current Optifine configuration. - * - * @return {@link Optional#empty()} if Optifine is not installed. - */ - public static Optional get() { - return Optional.ofNullable(handler); - } - - public static boolean optifineInstalled() { - return optifine != null; - } - - public static boolean usingShaders() { - return OptifineHandler.get() - .map(OptifineHandler::isUsingShaders) - .orElse(false); - } - - public static boolean isShadowPass() { - return isShadowPass.get().getAsBoolean(); - } - - public static void init() { - optifine = Package.getPackage(OPTIFINE_ROOT_PACKAGE); - - if (optifine == null) { - Backend.LOGGER.info("Optifine not detected."); - } else { - Backend.LOGGER.info("Optifine detected."); - - refresh(); - } - } - - public static void refresh() { - if (optifine == null) return; - - boolean shadersOff = areShadersDisabledInOptifineConfigFile(); - - handler = new OptifineHandler(!shadersOff); } private static boolean areShadersDisabledInOptifineConfigFile() { @@ -109,7 +65,57 @@ public class OptifineHandler { return shadersOff; } - public boolean isUsingShaders() { - return usingShaders; + public static void init() { + Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE); + isOptifineInstalled = optifinePackage != null; + + if (isOptifineInstalled) { + Backend.LOGGER.info("Optifine detected."); + + refresh(); + } else { + Backend.LOGGER.info("Optifine not detected."); + } + + shadowPassSupplier = createShadowPassSupplier(); + } + + public static void refresh() { + if (!isOptifineInstalled) return; + + boolean shadersOff = areShadersDisabledInOptifineConfigFile(); + + isUsingShaders = !shadersOff; + } + + public static boolean isOptifineInstalled() { + return isOptifineInstalled; + } + + public static boolean isUsingShaders() { + return isUsingShaders; + } + + public static boolean isShadowPass() { + return shadowPassSupplier.getAsBoolean(); + } + + public static void pushForceDiffuse() { + if (isOptifineInstalled) { + FORCE_DIFFUSE.get().increment(); + } + } + + public static void popForceDiffuse() { + if (isOptifineInstalled) { + FORCE_DIFFUSE.get().decrement(); + } + } + + public static boolean shouldApplyDiffuse() { + if (isOptifineInstalled) { + return !isUsingShaders || (FORCE_DIFFUSE.get().intValue() > 0); + } + return true; } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index fc6f242b7..f9bf34d17 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -56,7 +56,7 @@ public class BatchedMaterialGroup implements MaterialGroup { for (BatchedMaterial material : materials.values()) { for (CPUInstancer instancer : material.models.values()) { - instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.usingShaders(); + instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && OptifineHandler.shouldApplyDiffuse(); instancer.submitTasks(stack, pool, consumer); } } 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 d856b5020..75ebc8ee4 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.core.model; import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.util.RenderMath; +import com.jozufozu.flywheel.util.DiffuseLightCalculator; import com.jozufozu.flywheel.util.transform.Transform; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -14,7 +14,6 @@ import com.mojang.math.Vector4f; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.util.Mth; -import net.minecraftforge.client.model.pipeline.LightUtil; public class ModelTransformer { @@ -48,6 +47,11 @@ public class ModelTransformer { normalMat = params.normal.copy(); } + DiffuseLightCalculator diffuseCalculator = params.diffuseCalculator; + if (diffuseCalculator == null) { + diffuseCalculator = DiffuseLightCalculator.forCurrentLevel(); + } + int vertexCount = reader.getVertexCount(); for (int i = 0; i < vertexCount; i++) { float x = reader.getX(i); @@ -68,23 +72,26 @@ public class ModelTransformer { float ny = normal.y(); float nz = normal.z(); + byte r, g, b, a; if (params.useParamColor) { - if (context.outputColorDiffuse) { - float instanceDiffuse = LightUtil.diffuseLight(nx, ny, nz); - int colorR = transformColor(params.r, instanceDiffuse); - int colorG = transformColor(params.g, instanceDiffuse); - int colorB = transformColor(params.b, instanceDiffuse); - builder.color(colorR, colorG, colorB, params.a); - } else { - builder.color(params.r, params.g, params.b, params.a); - } + r = (byte) params.r; + g = (byte) params.g; + b = (byte) params.b; + a = (byte) params.a; } else { - if (context.outputColorDiffuse) { - int d = RenderMath.unb(LightUtil.diffuseLight(nx, ny, nz)); - builder.color(d, d, d, 0xFF); - } else { - builder.color(reader.getR(i), reader.getG(i), reader.getB(i), reader.getA(i)); - } + r = reader.getR(i); + g = reader.getG(i); + b = reader.getB(i); + a = reader.getA(i); + } + if (context.outputColorDiffuse) { + float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz); + int colorR = transformColor(r, instanceDiffuse); + int colorG = transformColor(g, instanceDiffuse); + int colorB = transformColor(b, instanceDiffuse); + builder.color(colorR, colorG, colorB, a); + } else { + builder.color(r, g, b, a); } //builder.color(Math.max(0, (int) (nx * 255)), Math.max(0, (int) (ny * 255)), Math.max(0, (int) (nz * 255)), 0xFF); @@ -118,6 +125,10 @@ public class ModelTransformer { return "ModelTransformer[" + model + ']'; } + public static int transformColor(byte component, float scale) { + return Mth.clamp((int) (Byte.toUnsignedInt(component) * scale), 0, 255); + } + public static int transformColor(int component, float scale) { return Mth.clamp((int) (component * scale), 0, 255); } @@ -137,7 +148,6 @@ public class ModelTransformer { * Do we need to bake diffuse lighting into the output colors? */ public boolean outputColorDiffuse = true; - } public static class Params implements Transform { @@ -163,6 +173,9 @@ public class ModelTransformer { public boolean useParamLight; public int packedLightCoords; + // Diffuse + public DiffuseLightCalculator diffuseCalculator; + public Params() { model = new Matrix4f(); normal = new Matrix3f(); @@ -180,6 +193,7 @@ public class ModelTransformer { overlay = OverlayTexture.NO_OVERLAY; useParamLight = false; packedLightCoords = LightTexture.FULL_BRIGHT; + diffuseCalculator = null; } public void load(Params from) { @@ -194,6 +208,7 @@ public class ModelTransformer { overlay = from.overlay; useParamLight = from.useParamLight; packedLightCoords = from.packedLightCoords; + diffuseCalculator = from.diffuseCalculator; } public Params color(int r, int g, int b, int a) { 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 a34d1f4d8..c839e4093 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -1,13 +1,13 @@ package com.jozufozu.flywheel.core.model; -import java.util.Arrays; +import java.lang.reflect.Field; import java.util.Collection; import java.util.Random; import java.util.function.Supplier; +import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; -import com.jozufozu.flywheel.util.Lazy; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -17,7 +17,7 @@ import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.BlockModelShaper; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.block.ModelBlockRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.BakedModel; @@ -29,21 +29,33 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.model.data.EmptyModelData; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; public class ModelUtil { - private static final Lazy MODEL_RENDERER = Lazy.of(() -> new ModelBlockRenderer(Minecraft.getInstance().getBlockColors())); + /** + * An alternative BlockRenderDispatcher that circumvents the Forge rendering pipeline to ensure consistency. + * Meant to be used for virtual rendering. + */ + public static final BlockRenderDispatcher VANILLA_RENDERER = createVanillaRenderer(); - // DOWN, UP, NORTH, SOUTH, WEST, EAST, null - private static final Direction[] CULL_FACES; - - static { - Direction[] directions = Direction.values(); - - CULL_FACES = Arrays.copyOf(directions, directions.length + 1); + private static BlockRenderDispatcher createVanillaRenderer() { + BlockRenderDispatcher defaultDispatcher = Minecraft.getInstance().getBlockRenderer(); + BlockRenderDispatcher dispatcher = new BlockRenderDispatcher(null, null, null); + try { + for (Field field : BlockRenderDispatcher.class.getDeclaredFields()) { + field.setAccessible(true); + field.set(dispatcher, field.get(defaultDispatcher)); + } + ObfuscationReflectionHelper.setPrivateValue(BlockRenderDispatcher.class, dispatcher, new ModelBlockRenderer(Minecraft.getInstance().getBlockColors()), "f_110900_"); + } catch (Exception e) { + Flywheel.LOGGER.error("Failed to initialize vanilla BlockRenderDispatcher!", e); + return defaultDispatcher; + } + return dispatcher; } public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) { - ModelBlockRenderer blockRenderer = Minecraft.getInstance().getBlockRenderer().getModelRenderer(); + ModelBlockRenderer blockRenderer = VANILLA_RENDERER.getModelRenderer(); BufferBuilder builder = new BufferBuilder(512); builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder, @@ -53,8 +65,7 @@ public class ModelUtil { } public static BufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks) { - ModelBlockRenderer modelRenderer = MODEL_RENDERER.get(); - BlockModelShaper blockModels = Minecraft.getInstance().getModelManager().getBlockModelShaper(); + ModelBlockRenderer modelRenderer = VANILLA_RENDERER.getModelRenderer(); PoseStack ms = new PoseStack(); Random random = new Random(); @@ -75,7 +86,7 @@ public class ModelUtil { ms.pushPose(); ms.translate(pos.getX(), pos.getY(), pos.getZ()); - modelRenderer.tesselateBlock(renderWorld, blockModels.getBlockModel(state), state, pos, ms, builder, + modelRenderer.tesselateBlock(renderWorld, VANILLA_RENDERER.getBlockModel(state), state, pos, ms, builder, true, random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE); ms.popPose(); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java index ea641e03f..eea2f6a0e 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java @@ -23,7 +23,7 @@ public class ShaderCloseMixin { @Inject(at = @At("HEAD"), method = "setScreen") private void whenScreenChanges(Screen screen, CallbackInfo info) { - if (OptifineHandler.optifineInstalled() && screen instanceof VideoSettingsScreen) { + if (OptifineHandler.isOptifineInstalled() && screen instanceof VideoSettingsScreen) { Screen old = this.screen; if (old != null && old.getClass() .getName() diff --git a/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java b/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java new file mode 100644 index 000000000..d7f712582 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java @@ -0,0 +1,20 @@ +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 NETHER = RenderMath::diffuseLightNether; + + static DiffuseLightCalculator forCurrentLevel() { + return forLevel(Minecraft.getInstance().level); + } + + static DiffuseLightCalculator forLevel(ClientLevel level) { + return level.effects().constantAmbientLight() ? NETHER : DEFAULT; + } + + float getDiffuse(float normalX, float normalY, float normalZ); +} diff --git a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java b/src/main/java/com/jozufozu/flywheel/util/RenderMath.java index 77321641b..f280c2064 100644 --- a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java +++ b/src/main/java/com/jozufozu/flywheel/util/RenderMath.java @@ -67,4 +67,8 @@ public class RenderMath { target = target % 360; return (float) (((((target - current) % 360) + 540) % 360) - 180); } + + public static float diffuseLightNether(float x, float y, float z) { + return Math.min(x * x * 0.6f + y * y * 0.9f + z * z * 0.8f, 1f); + } } diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java b/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java deleted file mode 100644 index 8a354c80a..000000000 --- a/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.jozufozu.flywheel.util.transform; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Matrix3f; -import com.mojang.math.Matrix4f; -import com.mojang.math.Quaternion; - -public class MatrixTransformStack implements TransformStack { - - private final PoseStack internal; - - public MatrixTransformStack() { - this(new PoseStack()); - } - - public MatrixTransformStack(PoseStack internal) { - this.internal = internal; - } - - public PoseStack unwrap() { - return internal; - } - - public MatrixTransformStack setIdentity() { - if (internal.clear()) { - PoseStack.Pose last = internal.last(); - - last.normal() - .setIdentity(); - last.pose() - .setIdentity(); - } else { - internal.popPose(); - internal.pushPose(); - } - - return this; - } - - @Override - public TransformStack translate(double x, double y, double z) { - internal.translate(x, y, z); - return this; - } - - @Override - public TransformStack multiply(Quaternion quaternion) { - internal.mulPose(quaternion); - return this; - } - - @Override - public TransformStack scale(float factorX, float factorY, float factorZ) { - internal.scale(factorX, factorY, factorZ); - return this; - } - - @Override - public TransformStack pushPose() { - internal.pushPose(); - return this; - } - - @Override - public TransformStack popPose() { - internal.popPose(); - return this; - } - - @Override - public TransformStack mulPose(Matrix4f pose) { - internal.last().pose().multiply(pose); - return this; - } - - @Override - public TransformStack mulNormal(Matrix3f normal) { - internal.last().normal().mul(normal); - return this; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index c4d06994a..c094eaf25 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -9,7 +9,8 @@ import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.model.Model; import com.jozufozu.flywheel.util.AnimationTickHolder; -import com.jozufozu.flywheel.util.transform.MatrixTransformStack; +import com.jozufozu.flywheel.util.transform.TransformStack; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; import net.minecraft.client.renderer.RenderType; @@ -25,7 +26,7 @@ public class MinecartInstance extends EntityInstance private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); - MatrixTransformStack stack = new MatrixTransformStack(); + private final PoseStack stack = new PoseStack(); private final ModelData body; private ModelData contents; @@ -53,11 +54,12 @@ public class MinecartInstance extends EntityInstance @Override public void beginFrame() { + TransformStack tstack = TransformStack.cast(stack); stack.setIdentity(); float pt = AnimationTickHolder.getPartialTicks(); Vec3i originCoordinate = materialManager.getOriginCoordinate(); - stack.translate( + tstack.translate( Mth.lerp(pt, entity.xOld, entity.getX()) - originCoordinate.getX(), Mth.lerp(pt, entity.yOld, entity.getY()) - originCoordinate.getY(), Mth.lerp(pt, entity.zOld, entity.getZ()) - originCoordinate.getZ()); @@ -69,8 +71,8 @@ public class MinecartInstance extends EntityInstance float f = (((float)(i >> 16 & 7L) + 0.5F) / 8 - 0.5F) * 0.004F; float f1 = (((float)(i >> 20 & 7L) + 0.5F) / 8 - 0.5F) * 0.004F; float f2 = (((float)(i >> 24 & 7L) + 0.5F) / 8 - 0.5F) * 0.004F; - stack.translate(f, f1, f2); - stack.nudge(entity.getId()); + tstack.translate(f, f1, f2); + tstack.nudge(entity.getId()); double d0 = Mth.lerp(pt, entity.xOld, entity.getX()); double d1 = Mth.lerp(pt, entity.yOld, entity.getY()); double d2 = Mth.lerp(pt, entity.zOld, entity.getZ()); @@ -87,7 +89,7 @@ public class MinecartInstance extends EntityInstance vector3d2 = vector3d; } - stack.translate(vector3d.x - d0, (vector3d1.y + vector3d2.y) / 2.0D - d1, vector3d.z - d2); + tstack.translate(vector3d.x - d0, (vector3d1.y + vector3d2.y) / 2.0D - d1, vector3d.z - d2); Vec3 vector3d3 = vector3d2.add(-vector3d1.x, -vector3d1.y, -vector3d1.z); if (vector3d3.length() != 0.0D) { vector3d3 = vector3d3.normalize(); @@ -96,9 +98,9 @@ public class MinecartInstance extends EntityInstance } } - stack.translate(0.0D, 0.375D, 0.0D); - stack.multiply(Vector3f.YP.rotationDegrees(180 - yaw)); - stack.multiply(Vector3f.ZP.rotationDegrees(-f3)); + tstack.translate(0.0D, 0.375D, 0.0D); + tstack.multiply(Vector3f.YP.rotationDegrees(180 - yaw)); + tstack.multiply(Vector3f.ZP.rotationDegrees(-f3)); float f5 = (float)entity.getHurtTime() - pt; float f6 = entity.getDamage() - pt; if (f6 < 0) { @@ -106,20 +108,20 @@ public class MinecartInstance extends EntityInstance } if (f5 > 0) { - stack.multiply(Vector3f.XP.rotationDegrees(Mth.sin(f5) * f5 * f6 / 10 * (float)entity.getHurtDir())); + tstack.multiply(Vector3f.XP.rotationDegrees(Mth.sin(f5) * f5 * f6 / 10 * (float)entity.getHurtDir())); } int j = entity.getDisplayOffset(); if (contents != null) { - stack.pushPose(); - stack.scale(0.75F); - stack.translate(-0.5D, (float)(j - 8) / 16, 0.5D); - stack.multiply(Vector3f.YP.rotationDegrees(90)); - contents.setTransform(stack.unwrap()); - stack.popPose(); + tstack.pushPose(); + tstack.scale(0.75F); + tstack.translate(-0.5D, (float)(j - 8) / 16, 0.5D); + tstack.multiply(Vector3f.YP.rotationDegrees(90)); + contents.setTransform(stack); + tstack.popPose(); } - body.setTransform(stack.unwrap()); + body.setTransform(stack); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index 167b2367a..a55e62eb8 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -7,7 +7,8 @@ import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.util.AnimationTickHolder; -import com.jozufozu.flywheel.util.transform.MatrixTransformStack; +import com.jozufozu.flywheel.util.transform.TransformStack; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -25,7 +26,7 @@ public class ShulkerBoxInstance extends BlockEntityInstance Date: Tue, 8 Feb 2022 21:37:09 -0800 Subject: [PATCH 3/4] Remove force diffuse - The batching engine may run in parallel, meaning the force diffuse state will not be read correctly - ModelTransformers only process vertices that will be rendered in the world - Add 0.6.1 to the issue template --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .../flywheel/backend/OptifineHandler.java | 23 ------------------- .../batching/BatchedMaterialGroup.java | 2 +- .../flywheel/core/model/ModelTransformer.java | 12 ++-------- 4 files changed, 4 insertions(+), 34 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 099e65cce..36205ebd9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,7 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.6.1" - "0.6.0" - "0.5.1" - "0.5.0a" diff --git a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java index 201438ecd..4462359da 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java @@ -7,16 +7,12 @@ import java.io.IOException; import java.lang.reflect.Field; import java.util.function.BooleanSupplier; -import org.apache.commons.lang3.mutable.MutableInt; - import net.minecraft.client.Minecraft; public final class OptifineHandler { public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine"; public static final String SHADER_PACKAGE = "net.optifine.shaders"; - private static final ThreadLocal FORCE_DIFFUSE = ThreadLocal.withInitial(MutableInt::new); - private static boolean isOptifineInstalled; private static boolean isUsingShaders; private static BooleanSupplier shadowPassSupplier; @@ -99,23 +95,4 @@ public final class OptifineHandler { public static boolean isShadowPass() { return shadowPassSupplier.getAsBoolean(); } - - public static void pushForceDiffuse() { - if (isOptifineInstalled) { - FORCE_DIFFUSE.get().increment(); - } - } - - public static void popForceDiffuse() { - if (isOptifineInstalled) { - FORCE_DIFFUSE.get().decrement(); - } - } - - public static boolean shouldApplyDiffuse() { - if (isOptifineInstalled) { - return !isUsingShaders || (FORCE_DIFFUSE.get().intValue() > 0); - } - return true; - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index f9bf34d17..14b2cd212 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -56,7 +56,7 @@ public class BatchedMaterialGroup implements MaterialGroup { for (BatchedMaterial material : materials.values()) { for (CPUInstancer instancer : material.models.values()) { - instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && OptifineHandler.shouldApplyDiffuse(); + instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.isUsingShaders(); instancer.submitTasks(stack, pool, consumer); } } 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 75ebc8ee4..10eafd1c4 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java @@ -47,12 +47,9 @@ public class ModelTransformer { normalMat = params.normal.copy(); } - DiffuseLightCalculator diffuseCalculator = params.diffuseCalculator; - if (diffuseCalculator == null) { - diffuseCalculator = DiffuseLightCalculator.forCurrentLevel(); - } + final DiffuseLightCalculator diffuseCalculator = DiffuseLightCalculator.forCurrentLevel(); - int vertexCount = reader.getVertexCount(); + final int vertexCount = reader.getVertexCount(); for (int i = 0; i < vertexCount; i++) { float x = reader.getX(i); float y = reader.getY(i); @@ -173,9 +170,6 @@ public class ModelTransformer { public boolean useParamLight; public int packedLightCoords; - // Diffuse - public DiffuseLightCalculator diffuseCalculator; - public Params() { model = new Matrix4f(); normal = new Matrix3f(); @@ -193,7 +187,6 @@ public class ModelTransformer { overlay = OverlayTexture.NO_OVERLAY; useParamLight = false; packedLightCoords = LightTexture.FULL_BRIGHT; - diffuseCalculator = null; } public void load(Params from) { @@ -208,7 +201,6 @@ public class ModelTransformer { overlay = from.overlay; useParamLight = from.useParamLight; packedLightCoords = from.packedLightCoords; - diffuseCalculator = from.diffuseCalculator; } public Params color(int r, int g, int b, int a) { From c07c6363f9b1ab51a0489c85907fca1b3fb15227 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Thu, 10 Feb 2022 21:26:56 -0800 Subject: [PATCH 4/4] Resolve redirect conflict and add more optifine hacks - Fix entitiesForRendering redirect to be compatible with carpet. - Use more reflection for dealing with optifine - Fixes issue where flywheel would still be on immediately after enabling optifine shaders --- .../jozufozu/flywheel/backend/Backend.java | 2 - .../flywheel/backend/OptifineHandler.java | 95 +++++++++++-------- .../backend/instancing/InstanceWorld.java | 4 +- .../mixin/CancelEntityRenderMixin.java | 51 ---------- .../flywheel/mixin/ClientLevelMixin.java | 42 ++++++++ .../flywheel/mixin/ShaderCloseMixin.java | 35 ------- .../flywheel/util/ClientLevelExtension.java | 22 +++++ src/main/resources/flywheel.mixins.json | 3 +- 8 files changed, 125 insertions(+), 129 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java create mode 100644 src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java delete mode 100644 src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java create mode 100644 src/main/java/com/jozufozu/flywheel/util/ClientLevelExtension.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index 8015949a3..46e602dc4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -41,8 +41,6 @@ public class Backend { } public static void refresh() { - OptifineHandler.refresh(); - engine = chooseEngine(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java index 4462359da..1e49c7270 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java @@ -1,25 +1,43 @@ package com.jozufozu.flywheel.backend; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.function.BooleanSupplier; -import net.minecraft.client.Minecraft; +import javax.annotation.Nullable; + +import net.minecraft.client.Camera; +import net.minecraft.client.renderer.culling.Frustum; public final class OptifineHandler { public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine"; public static final String SHADER_PACKAGE = "net.optifine.shaders"; private static boolean isOptifineInstalled; - private static boolean isUsingShaders; + private static BooleanSupplier shadersEnabledSupplier; private static BooleanSupplier shadowPassSupplier; + private static FrustumConstructor shadowFrustumConstructor; private OptifineHandler() { } + private static FrustumConstructor createShadowFrustumConstructor() { + try { + Class ofShaders = Class.forName("net.optifine.shaders.ShadersRender"); + Method method = ofShaders.getDeclaredMethod("makeShadowFrustum", Camera.class, Float.TYPE); + method.setAccessible(true); + return (cam, pt) -> { + try { + return (Frustum) method.invoke(null, cam, pt); + } catch (Exception ignored) { + return null; + } + }; + } catch (Exception ignored) { + return ($, $$) -> null; + } + } + private static BooleanSupplier createShadowPassSupplier() { try { Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); @@ -37,28 +55,21 @@ public final class OptifineHandler { } } - private static boolean areShadersDisabledInOptifineConfigFile() { - File dir = Minecraft.getInstance().gameDirectory; - - File shaderOptions = new File(dir, "optionsshaders.txt"); - - boolean shadersOff = true; - try (BufferedReader reader = new BufferedReader(new FileReader(shaderOptions))) { - - shadersOff = reader.lines() - .anyMatch(it -> { - String line = it.replaceAll("\\s", ""); - if (line.startsWith("shaderPack=")) { - String setting = line.substring("shaderPack=".length()); - - return setting.equals("OFF") || setting.equals("(internal)"); - } - return false; - }); - } catch (IOException e) { - Backend.LOGGER.info("No shader config found."); + private static BooleanSupplier createShadersEnabledSupplier() { + try { + Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); + Field field = ofShaders.getDeclaredField("shaderPackLoaded"); + field.setAccessible(true); + return () -> { + try { + return field.getBoolean(null); + } catch (IllegalAccessException ignored) { + return false; + } + }; + } catch (Exception ignored) { + return () -> false; } - return shadersOff; } public static void init() { @@ -67,21 +78,13 @@ public final class OptifineHandler { if (isOptifineInstalled) { Backend.LOGGER.info("Optifine detected."); - - refresh(); } else { Backend.LOGGER.info("Optifine not detected."); } + shadersEnabledSupplier = createShadersEnabledSupplier(); shadowPassSupplier = createShadowPassSupplier(); - } - - public static void refresh() { - if (!isOptifineInstalled) return; - - boolean shadersOff = areShadersDisabledInOptifineConfigFile(); - - isUsingShaders = !shadersOff; + shadowFrustumConstructor = createShadowFrustumConstructor(); } public static boolean isOptifineInstalled() { @@ -89,10 +92,26 @@ public final class OptifineHandler { } public static boolean isUsingShaders() { - return isUsingShaders; + return shadersEnabledSupplier.getAsBoolean(); } public static boolean isShadowPass() { return shadowPassSupplier.getAsBoolean(); } + + @Nullable + public static Frustum createShadowFrustum(Camera camera, float partialTicks) { + var frustum = shadowFrustumConstructor.create(camera, partialTicks); + if (frustum != null) { + var position = camera.getPosition(); + frustum.prepare(position.x, position.y, position.z); + } + return frustum; + } + + @FunctionalInterface + public interface FrustumConstructor { + @Nullable + Frustum create(Camera camera, float partialTicks); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index 02ec9ceac..23d248b8a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -12,6 +12,7 @@ import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.core.shader.WorldProgram; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.event.RenderLayerEvent; +import com.jozufozu.flywheel.util.ClientLevelExtension; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -130,7 +131,8 @@ public class InstanceWorld { public void loadEntities(ClientLevel world) { // Block entities are loaded while chunks are baked. // Entities are loaded with the world, so when chunks are reloaded they need to be re-added. - world.entitiesForRendering() + ClientLevelExtension.cast(world) + .flywheel$getAllLoadedEntities() .forEach(entityInstanceManager::add); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java deleted file mode 100644 index ed1a41e6e..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.jozufozu.flywheel.mixin; - -import java.util.ArrayList; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Group; -import org.spongepowered.asm.mixin.injection.Redirect; - -import com.google.common.collect.Lists; -import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; - -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.world.entity.Entity; - -@Mixin(LevelRenderer.class) -public class CancelEntityRenderMixin { - - // TODO: Don't use redirect - @Group(name = "entityFilter", min = 1, max = 1) - @Redirect(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientLevel;entitiesForRendering()Ljava/lang/Iterable;")) - private Iterable filterEntities(ClientLevel world) { - Iterable entities = world.entitiesForRendering(); - if (Backend.isOn()) { - ArrayList filtered = Lists.newArrayList(entities); - - filtered.removeIf(InstancedRenderRegistry::shouldSkipRender); - - return filtered; - } - return entities; - } - -// @Group(name = "entityFilter") -// @Redirect(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ClassInstanceMultiMap;iterator()Ljava/util/Iterator;")) -// private Iterator filterEntitiesOF(ClassInstanceMultiMap classInheritanceMultiMap) { -// if (Backend.getInstance() -// .canUseInstancing()) { -// -// ArrayList filtered = Lists.newArrayList(classInheritanceMultiMap); -// -// InstancedRenderRegistry r = InstancedRenderRegistry.getInstance(); -// filtered.removeIf(r::shouldSkipRender); -// -// return filtered.iterator(); -// } -// return classInheritanceMultiMap.iterator(); -// } -} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java new file mode 100644 index 000000000..ce1a9c161 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java @@ -0,0 +1,42 @@ +package com.jozufozu.flywheel.mixin; + +import java.util.ArrayList; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.google.common.collect.Lists; +import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; +import com.jozufozu.flywheel.util.ClientLevelExtension; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.entity.LevelEntityGetter; + +@Mixin(ClientLevel.class) +public abstract class ClientLevelMixin implements ClientLevelExtension { + + @Shadow + protected abstract LevelEntityGetter getEntities(); + + @Override + public Iterable flywheel$getAllLoadedEntities() { + return getEntities().getAll(); + } + + @Inject(method = "entitiesForRendering", at = @At("RETURN"), cancellable = true) + private void filterEntities(CallbackInfoReturnable> cir) { + if (Backend.isOn()) { + Iterable entities = cir.getReturnValue(); + ArrayList filtered = Lists.newArrayList(entities); + + filtered.removeIf(InstancedRenderRegistry::shouldSkipRender); + + cir.setReturnValue(filtered); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java deleted file mode 100644 index eea2f6a0e..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/ShaderCloseMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.jozufozu.flywheel.mixin; - -import javax.annotation.Nullable; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.jozufozu.flywheel.backend.OptifineHandler; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.VideoSettingsScreen; - -@Mixin(Minecraft.class) -public class ShaderCloseMixin { - - @Shadow - @Nullable - public Screen screen; - - @Inject(at = @At("HEAD"), method = "setScreen") - private void whenScreenChanges(Screen screen, CallbackInfo info) { - if (OptifineHandler.isOptifineInstalled() && screen instanceof VideoSettingsScreen) { - Screen old = this.screen; - if (old != null && old.getClass() - .getName() - .startsWith(OptifineHandler.SHADER_PACKAGE)) { - OptifineHandler.refresh(); - } - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/util/ClientLevelExtension.java b/src/main/java/com/jozufozu/flywheel/util/ClientLevelExtension.java new file mode 100644 index 000000000..c4bb29bba --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/util/ClientLevelExtension.java @@ -0,0 +1,22 @@ +package com.jozufozu.flywheel.util; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.entity.Entity; + +public interface ClientLevelExtension { + + /** + * Get an iterator over all entities in this level. + * + *

+ * Normally, this would be accomplished by {@link ClientLevel#entitiesForRendering()}, but the output of that + * method is filtered of entities that are rendered by flywheel. This interface provides a workaround. + *

+ * @return An iterator over all entities in the level, including entities that are rendered by flywheel. + */ + Iterable flywheel$getAllLoadedEntities(); + + static ClientLevelExtension cast(ClientLevel level) { + return (ClientLevelExtension) level; + } +} diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index 19f34505b..cccc7ef58 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -10,7 +10,7 @@ "BufferBuilderMixin", "BufferUploaderMixin", "CameraMixin", - "CancelEntityRenderMixin", + "ClientLevelMixin", "ChunkRebuildHooksMixin", "EntityTypeMixin", "FixFabulousDepthMixin", @@ -23,7 +23,6 @@ "PausedPartialTickAccessor", "RenderTexturesMixin", "RenderTypeMixin", - "ShaderCloseMixin", "atlas.AtlasDataMixin", "atlas.SheetDataAccessor", "light.LightUpdateMixin",