Platform dependent wheeling

- Use ClientPlatform to:
  - Dispatch events
  - Create iris/oculus handler
- Move VisualizationEventHandler into forge project
This commit is contained in:
Jozufozu 2024-04-18 17:40:32 -07:00
parent 7e5b2098b1
commit e152df6769
6 changed files with 149 additions and 35 deletions

View file

@ -14,12 +14,10 @@ import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.event.RenderStageEvent;
import com.jozufozu.flywheel.impl.event.RenderContextImpl;
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
import com.jozufozu.flywheel.platform.ClientPlatform;
import com.mojang.blaze3d.vertex.PoseStack;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
@ -30,7 +28,6 @@ import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.server.level.BlockDestructionProgress;
import net.minecraftforge.common.MinecraftForge;
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium
abstract class LevelRendererMixin {
@ -54,7 +51,7 @@ abstract class LevelRendererMixin {
private void flywheel$beginRender(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, poseStack, projectionMatrix, camera, partialTick);
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(flywheel$renderContext));
ClientPlatform.getInstance().dispatchBeginFrame(flywheel$renderContext);
}
@Inject(method = "renderLevel", at = @At("RETURN"))
@ -64,7 +61,7 @@ abstract class LevelRendererMixin {
@Inject(method = "allChanged", at = @At("RETURN"))
private void flywheel$refresh(CallbackInfo ci) {
MinecraftForge.EVENT_BUS.post(new ReloadLevelRendererEvent(level));
ClientPlatform.getInstance().dispatchReloadLevelRenderer(level);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=destroyProgress"))
@ -84,7 +81,7 @@ abstract class LevelRendererMixin {
@Unique
private void flywheel$dispatch(RenderStage stage) {
if (flywheel$renderContext != null) {
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(flywheel$renderContext, stage));
ClientPlatform.getInstance().dispatchRenderStage(flywheel$renderContext, stage);
}
}

View file

@ -6,34 +6,34 @@ import java.util.function.BooleanSupplier;
import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger;
import com.jozufozu.flywheel.platform.ClientPlatform;
import com.mojang.logging.LogUtils;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraftforge.fml.ModList;
public final class ShadersModHandler {
private static final Logger LOGGER = LogUtils.getLogger();
private static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
private static final boolean IS_OCULUS_LOADED;
private static final boolean IS_IRIS_LOADED;
private static final boolean IS_OPTIFINE_INSTALLED;
private static final InternalHandler INTERNAL_HANDLER;
static {
Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
IS_OPTIFINE_INSTALLED = optifinePackage != null;
IS_OCULUS_LOADED = ModList.get()
.isLoaded("oculus");
// OptiFine and Oculus are assumed to be mutually exclusive
var irisOculusHandler = ClientPlatform.getInstance()
.createIrisOculusHandlerIfPresent();
IS_IRIS_LOADED = irisOculusHandler != null;
// OptiFine and Iris/Oculus are assumed to be mutually exclusive
if (IS_OPTIFINE_INSTALLED) {
LOGGER.info("Optifine detected.");
INTERNAL_HANDLER = new Optifine();
} else if (IS_OCULUS_LOADED) {
LOGGER.info("Oculus detected.");
INTERNAL_HANDLER = new Oculus();
} else if (IS_IRIS_LOADED) {
LOGGER.info("Iris detected.");
INTERNAL_HANDLER = irisOculusHandler;
} else {
LOGGER.info("No shaders mod detected.");
INTERNAL_HANDLER = new InternalHandler() {};
@ -43,8 +43,8 @@ public final class ShadersModHandler {
private ShadersModHandler() {
}
public static boolean isOculusLoaded() {
return IS_OCULUS_LOADED;
public static boolean isIrisLoaded() {
return IS_IRIS_LOADED;
}
public static boolean isOptifineInstalled() {
@ -63,7 +63,8 @@ public final class ShadersModHandler {
public static void init() {
}
private interface InternalHandler {
@ApiStatus.Internal
public interface InternalHandler {
default boolean isShaderPackInUse() {
return false;
};
@ -73,21 +74,6 @@ public final class ShadersModHandler {
};
}
// simple, lovely api calls
private static class Oculus implements InternalHandler {
@Override
public boolean isShaderPackInUse() {
return IrisApi.getInstance()
.isShaderPackInUse();
}
@Override
public boolean isRenderingShadowPass() {
return IrisApi.getInstance()
.isRenderingShadowPass();
}
}
// evil reflection
private static class Optifine implements InternalHandler {
private final BooleanSupplier shadersEnabledSupplier;

View file

@ -2,6 +2,14 @@ package com.jozufozu.flywheel.platform;
import java.lang.reflect.InvocationTargetException;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
import net.minecraft.client.multiplayer.ClientLevel;
public abstract class ClientPlatform {
private static final ClientPlatform INSTANCE;
@ -19,4 +27,15 @@ public abstract class ClientPlatform {
public static ClientPlatform getInstance() {
return INSTANCE;
}
public abstract void dispatchReloadLevelRenderer(ClientLevel level);
public abstract void dispatchBeginFrame(RenderContext context);
public abstract void dispatchRenderStage(RenderContext context, RenderStage stage);
public abstract boolean isModLoaded(String modid);
@Nullable
public abstract ShadersModHandler.InternalHandler createIrisOculusHandlerIfPresent();
}

View file

@ -1,4 +1,59 @@
package com.jozufozu.flywheel.platform;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.event.BeginFrameCallback;
import com.jozufozu.flywheel.api.event.ReloadLevelRendererCallback;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.event.RenderStageCallback;
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
import net.fabricmc.loader.api.FabricLoader;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.multiplayer.ClientLevel;
public class ClientPlatformImpl extends ClientPlatform {
@Override
public void dispatchReloadLevelRenderer(ClientLevel level) {
ReloadLevelRendererCallback.EVENT.invoker().onReloadLevelRenderer(level);
}
@Override
public void dispatchBeginFrame(RenderContext context) {
BeginFrameCallback.EVENT.invoker().onBeginFrame(context);
}
@Override
public void dispatchRenderStage(RenderContext context, RenderStage stage) {
RenderStageCallback.EVENT.invoker().onRenderStage(context, stage);
}
@Override
public boolean isModLoaded(String modid) {
return FabricLoader.getInstance()
.isModLoaded(modid);
}
@Nullable
@Override
public ShadersModHandler.InternalHandler createIrisOculusHandlerIfPresent() {
if (isModLoaded("iris")) {
return new ShadersModHandler.InternalHandler() {
@Override
public boolean isShaderPackInUse() {
return IrisApi.getInstance()
.isShaderPackInUse();
}
@Override
public boolean isRenderingShadowPass() {
return IrisApi.getInstance()
.isRenderingShadowPass();
}
};
} else {
return null;
}
}
}

View file

@ -12,6 +12,7 @@ import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.event.entity.EntityLeaveLevelEvent;
import net.minecraftforge.fml.LogicalSide;
// TODO: fabric event handler
public final class VisualizationEventHandler {
private VisualizationEventHandler() {
}

View file

@ -1,4 +1,60 @@
package com.jozufozu.flywheel.platform;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.event.RenderStageEvent;
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.ModList;
public class ClientPlatformImpl extends ClientPlatform {
@Override
public void dispatchReloadLevelRenderer(ClientLevel level) {
MinecraftForge.EVENT_BUS.post(new ReloadLevelRendererEvent(level));
}
@Override
public void dispatchBeginFrame(RenderContext context) {
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(context));
}
@Override
public void dispatchRenderStage(RenderContext context, RenderStage stage) {
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(context, stage));
}
@Override
public boolean isModLoaded(String modid) {
return ModList.get()
.isLoaded(modid);
}
@Nullable
@Override
public ShadersModHandler.InternalHandler createIrisOculusHandlerIfPresent() {
if (isModLoaded("oculus")) {
return new ShadersModHandler.InternalHandler() {
@Override
public boolean isShaderPackInUse() {
return IrisApi.getInstance()
.isShaderPackInUse();
}
@Override
public boolean isRenderingShadowPass() {
return IrisApi.getInstance()
.isRenderingShadowPass();
}
};
} else {
return null;
}
}
}