Add Rubidium compatibility on our side

- Move FixNormalScalingMixin from Create
- Extract some of LevelRendererMixin into InstanceUpdateMixin
This commit is contained in:
PepperCode1 2023-08-23 10:03:57 -07:00
parent 01f204eb0a
commit ecc3c2d925
16 changed files with 234 additions and 65 deletions

View file

@ -52,6 +52,7 @@ minecraft {
property 'flw.loadRenderDoc', 'true'
arg '-mixin.config=flywheel.mixins.json'
arg '-mixin.config=flywheel.sodium.mixins.json'
mods {
flywheel {
@ -67,6 +68,7 @@ minecraft {
property 'forge.logging.console.level', 'debug'
arg '-mixin.config=flywheel.mixins.json'
arg '-mixin.config=flywheel.sodium.mixins.json'
mods {
flywheel {
@ -119,7 +121,7 @@ dependencies {
// switch to implementation for debugging
compileOnly fg.deobf('maven.modrinth:starlight-forge:1.0.2+1.18.2')
compileOnly fg.deobf('maven.modrinth:rubidium:0.5.2a')
compileOnly fg.deobf('maven.modrinth:rubidium:0.5.6')
compileOnly fg.deobf('maven.modrinth:oculus:1.18.2-1.6.4')
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
@ -159,7 +161,7 @@ jar {
'Implementation-Version' : project.jar.archiveVersion,
//'Implementation-Vendor': 'flywheel authors',
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'MixinConfigs' : 'flywheel.mixins.json'
'MixinConfigs' : 'flywheel.mixins.json,flywheel.sodium.mixins.json'
])
}
}

View file

@ -15,6 +15,7 @@ import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.api.distmarker.Dist;
@ -119,6 +120,21 @@ public class InstancedRenderDispatcher {
.loadEntities(world);
}
public static <T extends BlockEntity> boolean tryAddBlockEntity(T blockEntity) {
Level level = blockEntity.getLevel();
if (!Backend.canUseInstancing(level)) {
return false;
}
if (!InstancedRenderRegistry.canInstance(blockEntity.getType())) {
return false;
}
getBlockEntities(level).queueAdd(blockEntity);
return InstancedRenderRegistry.shouldSkipRender(blockEntity);
}
public static void getDebugString(List<String> debug) {
debug.add("");
debug.add("Flywheel: " + Flywheel.getVersion());

View file

@ -1,27 +0,0 @@
package com.jozufozu.flywheel.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@Mixin(LevelRenderer.class)
public class FixFabulousDepthMixin {
@Inject(method = "renderLevel", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/renderer/PostChain;process(F)V"))
private void disableTransparencyShaderDepth(PoseStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) {
GlStateManager._depthMask(false);
}
}

View file

@ -8,7 +8,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
@ -24,8 +23,6 @@ import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
@ -33,7 +30,6 @@ import net.minecraftforge.common.MinecraftForge;
@OnlyIn(Dist.CLIENT)
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after sodium
public class LevelRendererMixin {
@Shadow
private ClientLevel level;
@ -63,17 +59,4 @@ public class LevelRendererMixin {
private void renderBlockBreaking(PoseStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) {
CrumblingRenderer.render(level, camera, stack);
}
// Instancing
/**
* This gets called when a block is marked for rerender by vanilla.
*/
@Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V")
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
if (Backend.isOn()) {
InstancedRenderDispatcher.getBlockEntities(level)
.update(level.getBlockEntity(pos));
}
}
}

View file

@ -7,7 +7,6 @@ import net.minecraft.client.Minecraft;
@Mixin(Minecraft.class)
public interface PausedPartialTickAccessor {
@Accessor("pausePartialTick")
float flywheel$getPartialTicksPaused();
float flywheel$getPausePartialTick();
}

View file

@ -0,0 +1,18 @@
package com.jozufozu.flywheel.mixin.fix;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.renderer.LevelRenderer;
@Mixin(LevelRenderer.class)
public class FixFabulousDepthMixin {
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PostChain;process(F)V", ordinal = 1))
private void flywheel$disableTransparencyShaderDepth(CallbackInfo ci) {
GlStateManager._depthMask(false);
}
}

View file

@ -0,0 +1,36 @@
package com.jozufozu.flywheel.mixin.fix;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.vertex.PoseStack;
@Mixin(PoseStack.class)
public class FixNormalScalingMixin {
/**
* Minecraft negates the normal matrix if all scales are equal and negative, but
* does not return afterward. This allows the rest of the method's logic to be
* applied, which negates the matrix again, resulting in the matrix being the
* same as in the beginning.
*/
@Inject(method = "scale(FFF)V", at = @At(value = "INVOKE", target = "Lcom/mojang/math/Matrix3f;mul(F)V", shift = Shift.AFTER), cancellable = true)
private void flywheel$returnAfterNegate(float x, float y, float z, CallbackInfo ci) {
ci.cancel();
}
/**
* Minecraft takes the inverse cube root of the product of all scales to provide a
* rough estimate for normalization so that it does not need to be done later. It
* does not make sense for this "normalization factor" to be negative though, as
* that would invert all normals. Additionally, Minecraft's fastInvCubeRoot method
* does not work for negative numbers.
*/
@ModifyArg(method = "scale(FFF)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;fastInvCubeRoot(F)F"))
private float flywheel$absInvCbrtInput(float input) {
return Math.abs(input);
}
}

View file

@ -7,27 +7,17 @@ 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.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
public class ChunkRebuildHooksMixin {
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
private <E extends BlockEntity> void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
if (Backend.canUseInstancing(be.getLevel())) {
if (InstancedRenderRegistry.canInstance(be.getType()))
InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);
if (InstancedRenderRegistry.shouldSkipRender(be))
ci.cancel();
@Inject(method = "handleBlockEntity(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$CompiledChunk;Ljava/util/Set;Lnet/minecraft/world/level/block/entity/BlockEntity;)V", at = @At("HEAD"), cancellable = true)
private void flywheel$tryAddBlockEntity(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> globalBlockEntities, BlockEntity blockEntity, CallbackInfo ci) {
if (InstancedRenderDispatcher.tryAddBlockEntity(blockEntity)) {
ci.cancel();
}
}
}

View file

@ -0,0 +1,40 @@
package com.jozufozu.flywheel.mixin.instancemanage;
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.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
@Mixin(LevelRenderer.class)
public class InstanceUpdateMixin {
@Shadow
private ClientLevel level;
/**
* This gets called when a block is marked for rerender by vanilla.
*/
@Inject(method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V", at = @At("TAIL"))
private void flywheel$checkUpdate(BlockPos pos, BlockState oldState, BlockState newState, CallbackInfo ci) {
if (!Backend.isOn()) {
return;
}
BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity == null) {
return;
}
InstancedRenderDispatcher.getBlockEntities(level)
.queueUpdate(blockEntity);
}
}

View file

@ -0,0 +1,23 @@
package com.jozufozu.flywheel.mixin.sodium;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderRebuildTask;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.world.level.block.entity.BlockEntity;
@Mixin(value = ChunkRenderRebuildTask.class, remap = false)
public class ChunkRenderRebuildTaskMixin {
@Redirect(method = "performBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher;getRenderer(Lnet/minecraft/world/level/block/entity/BlockEntity;)Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderer;"))
private BlockEntityRenderer<?> flywheel$redirectGetRenderer(BlockEntityRenderDispatcher dispatcher, BlockEntity blockEntity) {
if (InstancedRenderDispatcher.tryAddBlockEntity(blockEntity)) {
return null;
}
return dispatcher.getRenderer(blockEntity);
}
}

View file

@ -0,0 +1,24 @@
package com.jozufozu.flywheel.mixin.sodium;
import java.util.Collection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import me.jellysquid.mods.sodium.client.compat.FlywheelCompat;
import net.minecraft.world.level.block.entity.BlockEntity;
/**
* Overwrite all methods in this class with stubs. Flywheel compatibility is now added by Flywheel itself through mixins.
*/
@Mixin(value = FlywheelCompat.class, remap = false)
public class FlywheelCompatMixin {
@Overwrite
public static boolean addAndFilterBEs(BlockEntity blockEntity) {
return true;
}
@Overwrite
public static void filterBlockEntityList(Collection<BlockEntity> blockEntities) {
}
}

View file

@ -0,0 +1,48 @@
package com.jozufozu.flywheel.mixin.sodium;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import com.google.common.base.Suppliers;
import net.minecraftforge.fml.loading.LoadingModList;
public class SodiumMixinPlugin implements IMixinConfigPlugin {
private static final Supplier<Boolean> IS_SODIUM_LOADED = Suppliers.memoize(() -> LoadingModList.get().getModFileById("rubidium") != null);
@Override
public void onLoad(String mixinPackage) {
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return IS_SODIUM_LOADED.get();
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}

View file

@ -37,7 +37,7 @@ public class AnimationTickHolder {
public static float getPartialTicks() {
Minecraft mc = Minecraft.getInstance();
return (mc.isPaused() ? ((PausedPartialTickAccessor) mc).flywheel$getPartialTicksPaused() : mc.getFrameTime());
return (mc.isPaused() ? ((PausedPartialTickAccessor) mc).flywheel$getPausePartialTick() : mc.getFrameTime());
}
// Unused but might be useful for debugging.

View file

@ -11,7 +11,7 @@ displayName = "Flywheel"
logoFile = "logo.png"
displayURL = "https://www.curseforge.com/minecraft/mc-mods/flywheel"
updateJSONURL = "https://api.modrinth.com/updates/flywheel/forge_updates.json"
authors = "Jozufozu"
authors = "Jozufozu, PepperCode1"
description = '''
A modern engine for modded minecraft.'''

View file

@ -12,7 +12,6 @@
"ClientLevelMixin",
"ClientMainMixin",
"EntityTypeMixin",
"FixFabulousDepthMixin",
"FrustumMixin",
"GlStateManagerMixin",
"LevelRendererAccessor",
@ -20,9 +19,12 @@
"PausedPartialTickAccessor",
"RenderTexturesMixin",
"RenderTypeMixin",
"fix.FixFabulousDepthMixin",
"fix.FixNormalScalingMixin",
"instancemanage.ChunkRebuildHooksMixin",
"instancemanage.InstanceAddMixin",
"instancemanage.InstanceRemoveMixin",
"instancemanage.InstanceUpdateMixin",
"light.LightUpdateMixin",
"light.NetworkLightUpdateMixin",
"matrix.Matrix3fMixin",

View file

@ -0,0 +1,15 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.jozufozu.flywheel.mixin.sodium",
"compatibilityLevel": "JAVA_17",
"refmap": "flywheel.refmap.json",
"plugin": "com.jozufozu.flywheel.mixin.sodium.SodiumMixinConfigPlugin",
"client": [
"ChunkRenderRebuildTaskMixin",
"FlywheelCompatMixin"
],
"injectors": {
"defaultRequire": 1
}
}