mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-14 00:06:12 +01:00
Add Iris compatibility
- Use the Iris API to detect shader rendering state - Remove CommandNameProviderEnum and use a Function argument instead
This commit is contained in:
parent
05c6d9d685
commit
ec97b82ed6
10 changed files with 70 additions and 174 deletions
|
@ -57,6 +57,8 @@ dependencies {
|
|||
|
||||
modCompileOnly 'curse.maven:starlight-521783:3554912'
|
||||
|
||||
modCompileOnly 'maven.modrinth:iris:1.18.x-v1.1.4'
|
||||
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
modCompileOnly 'maven.modrinth:indium:1.0.2-alpha1+mc1.18'
|
||||
modCompileOnly 'io.vram:frex-fabric-mc118:6.0.229'
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -42,8 +46,6 @@ public class Backend {
|
|||
|
||||
protected Backend() {
|
||||
loader = new Loader(this);
|
||||
|
||||
OptifineHandler.init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,8 +99,6 @@ public class Backend {
|
|||
}
|
||||
|
||||
public void refresh() {
|
||||
OptifineHandler.refresh();
|
||||
|
||||
capabilities = GL.createCapabilities();
|
||||
|
||||
compat = new GlCompat(capabilities);
|
||||
|
@ -165,7 +165,7 @@ public class Backend {
|
|||
FlwEngine preferredChoice = FlwConfig.get()
|
||||
.getEngine();
|
||||
|
||||
boolean usingShaders = OptifineHandler.usingShaders();
|
||||
boolean usingShaders = IrisShaderHandler.isShaderPackInUse();
|
||||
boolean canUseEngine = switch (preferredChoice) {
|
||||
case OFF -> true;
|
||||
case BATCHING -> !usingShaders;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
|
||||
public class IrisShaderHandler {
|
||||
public static final boolean IRIS_LOADED = FabricLoader.getInstance().isModLoaded("iris");
|
||||
|
||||
private static final InternalHandler HANDLER;
|
||||
|
||||
static {
|
||||
if (IRIS_LOADED) {
|
||||
HANDLER = new InternalHandlerImpl();
|
||||
} else {
|
||||
HANDLER = new InternalHandler() {};
|
||||
}
|
||||
}
|
||||
|
||||
private IrisShaderHandler() {
|
||||
}
|
||||
|
||||
public static boolean isShaderPackInUse() {
|
||||
return HANDLER.isShaderPackInUse();
|
||||
}
|
||||
|
||||
public static boolean isRenderingShadowPass() {
|
||||
return HANDLER.isRenderingShadowPass();
|
||||
}
|
||||
|
||||
private interface InternalHandler {
|
||||
default boolean isShaderPackInUse() {
|
||||
return false;
|
||||
};
|
||||
|
||||
default boolean isRenderingShadowPass() {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
private static class InternalHandlerImpl implements InternalHandler {
|
||||
@Override
|
||||
public boolean isShaderPackInUse() {
|
||||
return IrisApi.getInstance().isShaderPackInUse();
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean isRenderingShadowPass() {
|
||||
return IrisApi.getInstance().isRenderingShadowPass();
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
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.util.Optional;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public 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 Lazy<BooleanSupplier> isShadowPass = Lazy.of(() -> {
|
||||
try {
|
||||
Class<?> ofShaders = Class.forName("net.optifine.shaders.Shaders");
|
||||
Field field = ofShaders.getDeclaredField("isShadowPass");
|
||||
field.setAccessible(true);
|
||||
return () -> {
|
||||
try {
|
||||
return field.getBoolean(null);
|
||||
} catch (IllegalAccessException ignored) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} 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<OptifineHandler> 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() {
|
||||
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.");
|
||||
}
|
||||
return shadersOff;
|
||||
}
|
||||
|
||||
public boolean isUsingShaders() {
|
||||
return usingShaders;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -22,6 +23,7 @@ public final class ConfigCommands {
|
|||
ConfigCommandBuilder commandBuilder = new ConfigCommandBuilder("flywheel");
|
||||
|
||||
commandBuilder.addOption(config.engine, "backend", (builder, option) -> enumOptionCommand(builder, config, option,
|
||||
FlwEngine::getShortName,
|
||||
(source, value) -> {
|
||||
source.sendFeedback(getEngineMessage(value));
|
||||
},
|
||||
|
@ -67,19 +69,13 @@ public final class ConfigCommands {
|
|||
}));
|
||||
}
|
||||
|
||||
public static <E extends Enum<E>> void enumOptionCommand(LiteralArgumentBuilder<FabricClientCommandSource> builder, FlwConfig config, EnumOption<E> option, BiConsumer<FabricClientCommandSource, E> displayAction, BiConsumer<FabricClientCommandSource, E> setAction) {
|
||||
public static <E extends Enum<E>> void enumOptionCommand(LiteralArgumentBuilder<FabricClientCommandSource> builder, FlwConfig config, EnumOption<E> option, Function<E, String> nameFunc, BiConsumer<FabricClientCommandSource, E> displayAction, BiConsumer<FabricClientCommandSource, E> setAction) {
|
||||
builder.executes(context -> {
|
||||
displayAction.accept(context.getSource(), option.get());
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
for (E constant : option.getEnumType().getEnumConstants()) {
|
||||
String name;
|
||||
if (constant instanceof CommandNameProviderEnum nameProvider) {
|
||||
name = nameProvider.getCommandName();
|
||||
} else {
|
||||
name = constant.name();
|
||||
}
|
||||
builder.then(ClientCommandManager.literal(name)
|
||||
builder.then(ClientCommandManager.literal(nameFunc.apply(constant))
|
||||
.executes(context -> {
|
||||
option.set(constant);
|
||||
setAction.accept(context.getSource(), option.get());
|
||||
|
@ -132,8 +128,4 @@ public final class ConfigCommands {
|
|||
ClientCommandManager.DISPATCHER.register(command);
|
||||
}
|
||||
}
|
||||
|
||||
public interface CommandNameProviderEnum {
|
||||
String getCommandName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.Map;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public enum FlwEngine implements ConfigCommands.CommandNameProviderEnum {
|
||||
public enum FlwEngine {
|
||||
OFF("off", "Off"),
|
||||
BATCHING("batching", "Parallel Batching"),
|
||||
INSTANCING("instancing", "GL33 Instanced Arrays"),
|
||||
|
@ -29,8 +29,7 @@ public enum FlwEngine implements ConfigCommands.CommandNameProviderEnum {
|
|||
this.properName = properName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ 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 com.jozufozu.flywheel.backend.IrisShaderHandler;
|
||||
import com.jozufozu.flywheel.core.LastActiveCamera;
|
||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.fabric.event.FlywheelEvents;
|
||||
|
@ -18,7 +18,7 @@ public class FrustumMixin {
|
|||
|
||||
@Inject(method = "prepare", at = @At("TAIL"))
|
||||
private void onPrepare(double x, double y, double z, CallbackInfo ci) {
|
||||
if (OptifineHandler.isShadowPass()) {
|
||||
if (IrisShaderHandler.isRenderingShadowPass()) {
|
||||
FlywheelEvents.BEGIN_FRAME.invoker().handleEvent(new BeginFrameEvent(Minecraft.getInstance().level, LastActiveCamera.getActiveCamera(), (Frustum) (Object) this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.optifineInstalled() && screen instanceof VideoSettingsScreen) {
|
||||
Screen old = this.screen;
|
||||
if (old != null && old.getClass()
|
||||
.getName()
|
||||
.startsWith(OptifineHandler.SHADER_PACKAGE)) {
|
||||
OptifineHandler.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,5 +34,8 @@
|
|||
"fabric": "*",
|
||||
"minecraft": "1.18.x",
|
||||
"java": ">=17"
|
||||
},
|
||||
"breaks": {
|
||||
"iris": "<1.1.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
"LevelRendererMixin",
|
||||
"PausedPartialTickAccessor",
|
||||
"RenderTexturesMixin",
|
||||
"ShaderCloseMixin",
|
||||
"ShaderInstanceAccessor",
|
||||
"atlas.AtlasDataMixin",
|
||||
"atlas.SheetDataAccessor",
|
||||
|
|
Loading…
Reference in a new issue