Skip to content

Commit

Permalink
Real time shader settings
Browse files Browse the repository at this point in the history
  • Loading branch information
IMS212 committed Oct 30, 2024
1 parent f9c974b commit 2aac792
Show file tree
Hide file tree
Showing 12 changed files with 610 additions and 7 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ val FABRIC_API_VERSION by extra { "0.103.0+1.21.1" }
val PARCHMENT_VERSION by extra { null }

// https://semver.org/
val MOD_VERSION by extra { "1.8.0-beta.5" }
val MOD_VERSION by extra { "1.9.0-alpha.1" }

allprojects {
apply(plugin = "java")
Expand Down
7 changes: 5 additions & 2 deletions common/src/main/java/net/irisshaders/iris/Iris.java
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,9 @@ private static boolean loadExternalShaderpack(String name) {
return false;
}

Map<String, String> changedConfigs = tryReadConfigProperties(shaderPackConfigTxt)
Optional<Properties> configProperties = tryReadConfigProperties(shaderPackConfigTxt);

Map<String, String> changedConfigs = configProperties
.map(properties -> (Map<String, String>) (Object) properties)
.orElse(new HashMap<>());

Expand All @@ -319,14 +321,15 @@ private static boolean loadExternalShaderpack(String name) {
resetShaderPackOptions = false;

try {
currentPack = new ShaderPack(shaderPackPath, changedConfigs, StandardMacros.createStandardEnvironmentDefines(), isZip);
currentPack = new ShaderPack(shaderPackPath, shaderPackConfigTxt, changedConfigs, StandardMacros.createStandardEnvironmentDefines(), isZip);

MutableOptionValues changedConfigsValues = currentPack.getShaderPackOptions().getOptionValues().mutableCopy();

// Store changed values from those currently in use by the shader pack
Properties configsToSave = new Properties();
changedConfigsValues.getBooleanValues().forEach((k, v) -> configsToSave.setProperty(k, Boolean.toString(v)));
changedConfigsValues.getStringValues().forEach(configsToSave::setProperty);
currentPack.getShaderUniformList().forAllUniforms(configsToSave::setProperty);

tryUpdateConfigPropertiesFile(shaderPackConfigTxt, configsToSave);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package net.irisshaders.iris.helpers;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import net.irisshaders.iris.Iris;
import net.irisshaders.iris.shaderpack.RTUniforms;
import net.minecraft.client.Minecraft;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;

import java.io.IOException;

public class IrisCommands {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("iris")
.then(Commands.argument("name", StringArgumentType.word()).suggests((s, t) -> SharedSuggestionProvider.suggest(Iris.getCurrentPack().get().getShaderUniformList().getUniformNames(), t)).then(Commands.argument("value", StringArgumentType.word())
.suggests((cc, b) -> {
RTUniforms<?> uniform = Iris.getCurrentPack().get().getShaderUniformList().getUniformByName(StringArgumentType.getString(cc, "name"));
if (uniform instanceof RTUniforms.BooleanUniform) {
b.suggest("true");
b.suggest("false");
} else if (uniform instanceof RTUniforms.FloatUniform fu) {
for (Float v : fu.getValues()) {
b.suggest(String.valueOf(v));
}
} else if (uniform instanceof RTUniforms.IntUniform iu) {
for (Integer i : iu.getValues()) {
b.suggest(String.valueOf(i));
}
}

return b.buildFuture();
})
.executes(cc -> {
try {
Iris.logger.warn("Setting " + StringArgumentType.getString(cc, "name") + " to " + StringArgumentType.getString(cc, "value"));
Iris.getCurrentPack().get().getShaderUniformList().getUniformByName(StringArgumentType.getString(cc, "name"))
.setValueFromString(StringArgumentType.getString(cc, "value"));
Iris.getCurrentPack().get().getShaderUniformList().save();
Minecraft.getInstance().player.displayClientMessage(Component.literal("Saved option " + StringArgumentType.getString(cc, "name") + "."), true);
} catch (IOException e) {
Iris.logger.error("Failed to save uniforms!", e);
Minecraft.getInstance().player.displayClientMessage(Component.literal("Failed to save option!"), false);
}

return 1;
}))));
}
}
25 changes: 25 additions & 0 deletions common/src/main/java/net/irisshaders/iris/mixin/MixinCommands.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.irisshaders.iris.mixin;

import com.mojang.brigadier.CommandDispatcher;
import net.irisshaders.iris.helpers.IrisCommands;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import org.spongepowered.asm.mixin.Final;
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;

@Mixin(Commands.class)
public class MixinCommands {
@Shadow
@Final
private CommandDispatcher<CommandSourceStack> dispatcher;

@Inject(method = "<init>", at = @At("TAIL"))
private void reg(Commands.CommandSelection commandSelection, CommandBuildContext commandBuildContext, CallbackInfo ci) {
IrisCommands.register(this.dispatcher);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
import net.irisshaders.iris.uniforms.CapturedRenderingState;
import net.irisshaders.iris.uniforms.CommonUniforms;
import net.irisshaders.iris.uniforms.FrameUpdateNotifier;
import net.irisshaders.iris.uniforms.ShaderUniforms;
import net.irisshaders.iris.uniforms.custom.CustomUniforms;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -271,7 +272,10 @@ public IrisRenderingPipeline(ProgramSet programSet) {
}

this.customUniforms = programSet.getPack().customUniforms.build(
holder -> CommonUniforms.addNonDynamicUniforms(holder, programSet.getPack().getIdMap(), programSet.getPackDirectives(), this.updateNotifier)
holder -> {
CommonUniforms.addNonDynamicUniforms(holder, programSet.getPack().getIdMap(), programSet.getPackDirectives(), this.updateNotifier);
ShaderUniforms.add(holder, programSet.getPack().getShaderUniformList());
}
);

// Don't clobber anything in texture unit 0. It probably won't cause issues, but we're just being cautious here.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package net.irisshaders.iris.shaderpack;

import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.irisshaders.iris.Iris;
import net.irisshaders.iris.shaderpack.option.values.MutableOptionValues;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.function.BiConsumer;

public class RTUniformHolder implements Iterable<RTUniforms<?>> {
private final ShaderPack pack;
private Path propertyPath;
private Map<String, String> changed;

private List<RTUniforms<?>> uniformList;

private Object2ObjectMap<String, RTUniforms<?>> uniformMap = new Object2ObjectOpenHashMap<>();
private Path shaderPackConfigFile;

public RTUniformHolder(ShaderPack pack, Path shaderPackConfigFile, Map<String, String> properties, List<UniformContainer.Uniform<?>> uniforms) throws IOException {
this.pack = pack;
uniformList = new ArrayList<>();
this.shaderPackConfigFile = shaderPackConfigFile;

System.out.println(properties);

this.changed = new Object2ObjectOpenHashMap<>();
for (UniformContainer.Uniform<?> uniform : uniforms) {
if (uniform.type.equals(Boolean.class)) {
RTUniforms.BooleanUniform booleanUniform = new RTUniforms.BooleanUniform(uniform.uniformName, uniform.settingName, Boolean.parseBoolean((String) properties.getOrDefault(uniform.settingName, Boolean.toString((boolean) uniform.defaultValue))));
uniformMap.put(uniform.settingName, booleanUniform);
uniformList.add(booleanUniform);

if (!properties.containsKey(uniform.settingName)) changed.put(uniform.settingName, String.valueOf(booleanUniform.getCurrentValue()));
} else if (uniform.type.equals(Float.class)) {
RTUniforms.FloatUniform floatUniform = new RTUniforms.FloatUniform(uniform.uniformName, uniform.settingName, Float.parseFloat((String) properties.getOrDefault(uniform.settingName, Float.toString((float) uniform.defaultValue))), (Float[]) uniform.values);
uniformMap.put(uniform.settingName, floatUniform);
uniformList.add(floatUniform);

if (!properties.containsKey(uniform.settingName)) changed.put(uniform.settingName, String.valueOf(floatUniform.getCurrentValue()));
} else if (uniform.type.equals(Integer.class)) {
RTUniforms.IntUniform intUniform = new RTUniforms.IntUniform(uniform.uniformName, uniform.settingName, Integer.parseInt((String) properties.getOrDefault(uniform.settingName, Integer.toString((int) uniform.defaultValue))), (Integer[]) uniform.values);
uniformMap.put(uniform.settingName, intUniform);
uniformList.add(intUniform);

if (!properties.containsKey(uniform.settingName)) changed.put(uniform.settingName, String.valueOf(intUniform.getCurrentValue()));
}
}

uniformList.forEach(s -> System.out.println(s.toString()));
}

public List<RTUniforms<?>> getUniformList() {
return uniformList;
}

public void save() throws IOException {
MutableOptionValues changedConfigsValues = pack.getShaderPackOptions().getOptionValues().mutableCopy();

// Store changed values from those currently in use by the shader pack
Properties configsToSave = new Properties();
changedConfigsValues.getBooleanValues().forEach((k, v) -> configsToSave.setProperty(k, Boolean.toString(v)));
changedConfigsValues.getStringValues().forEach(configsToSave::setProperty);
forAllUniforms(configsToSave::setProperty);

tryUpdateConfigPropertiesFile(shaderPackConfigFile, configsToSave);
}

private static void tryUpdateConfigPropertiesFile(Path path, Properties properties) {
try {
if (properties.isEmpty()) {
// Delete the file or don't create it if there are no changed configs
if (Files.exists(path)) {
Files.delete(path);
}

return;
}

try (OutputStream out = Files.newOutputStream(path)) {
properties.store(out, null);
}
} catch (IOException e) {
Iris.logger.error("Tried to update config but failed!", e);
}
}

private static Properties readProperties(Path shaderPath, String name) {
try {
// ID maps should be encoded in ISO_8859_1.
Properties props = new Properties();
props.load(new StringReader(Files.readString(shaderPath.resolve(name), StandardCharsets.ISO_8859_1)));
return props;
} catch (NoSuchFileException e) {
Iris.logger.debug("An " + name + " file was not found in the current shaderpack");

return new Properties();
} catch (IOException e) {
Iris.logger.error("An IOException occurred reading " + name + " from the current shaderpack", e);

return new Properties();
}
}

@Override
public @NotNull Iterator<RTUniforms<?>> iterator() {
return this.uniformList.iterator();
}

public RTUniforms<?> getUniformByName(String name) {
return uniformMap.get(name);
}

public Iterable<String> getUniformNames() {
return uniformMap.keySet();
}

public void forAllUniforms(BiConsumer<String, String> saveFunction) {
for (RTUniforms<?> uniform : uniformList) {
uniform.save(saveFunction);
}
}
}
Loading

0 comments on commit 2aac792

Please sign in to comment.