Skip to content

Commit

Permalink
Support fogMode and fogDensity through a new dynamic uniform system
Browse files Browse the repository at this point in the history
This new dynamic uniform system allows Iris to handle uniforms that change many times per frame, and opens the door to proper support for uniforms like entityColor, entityId, blendMode, and more.
  • Loading branch information
coderbot16 committed Jul 20, 2021
1 parent 526c450 commit 425c19d
Show file tree
Hide file tree
Showing 21 changed files with 294 additions and 16 deletions.
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ archivesBaseName = project.archives_base_name
version = "${project.mod_version}+${getVersionMetadata()}"
group = project.maven_group


minecraft {
accessWidener = file("src/main/resources/iris.accesswidener")
}

dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ minecraft_version=1.16.5
yarn_mappings=1.16.5+build.6
loader_version=0.11.3
# Mod Properties
mod_version=1.1.0
mod_version=1.1.1-pre
maven_group=net.coderbot.iris_mc1_16_5
archives_base_name=iris-mc1.16.5

Expand Down
8 changes: 7 additions & 1 deletion src/main/java/net/coderbot/iris/gl/program/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.coderbot.iris.gl.GlResource;

import net.minecraft.client.gl.GlProgramManager;
import org.lwjgl.opengl.GL20C;

public final class Program extends GlResource {
Expand All @@ -16,12 +17,17 @@ public final class Program extends GlResource {
}

public void use() {
GL20C.glUseProgram(getGlId());
GlProgramManager.useProgram(getGlId());

uniforms.update();
samplers.update();
}

public static void unbind() {
ProgramUniforms.clearActiveUniforms();
GlProgramManager.useProgram(0);
}

public void destroyInternal() {
GL20C.glDeleteProgram(getGlId());
}
Expand Down
50 changes: 47 additions & 3 deletions src/main/java/net/coderbot/iris/gl/program/ProgramUniforms.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,36 @@

import com.google.common.collect.ImmutableList;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gl.uniform.DynamicLocationalUniformHolder;
import net.coderbot.iris.gl.uniform.LocationalUniformHolder;
import net.coderbot.iris.gl.uniform.Uniform;
import net.coderbot.iris.gl.uniform.UniformType;
import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
import net.coderbot.iris.gl.uniform.ValueUpdateNotifier;
import net.coderbot.iris.uniforms.SystemTimeUniforms;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL20C;

import net.minecraft.client.MinecraftClient;

public class ProgramUniforms {
private static ProgramUniforms active;
private final ImmutableList<Uniform> perTick;
private final ImmutableList<Uniform> perFrame;
private final ImmutableList<Uniform> dynamic;
private final ImmutableList<ValueUpdateNotifier> notifiersToReset;

private ImmutableList<Uniform> once;
long lastTick = -1;
int lastFrame = -1;

public ProgramUniforms(ImmutableList<Uniform> once, ImmutableList<Uniform> perTick, ImmutableList<Uniform> perFrame) {
public ProgramUniforms(ImmutableList<Uniform> once, ImmutableList<Uniform> perTick, ImmutableList<Uniform> perFrame,
ImmutableList<Uniform> dynamic, ImmutableList<ValueUpdateNotifier> notifiersToReset) {
this.once = once;
this.perTick = perTick;
this.perFrame = perFrame;
this.dynamic = dynamic;
this.notifiersToReset = notifiersToReset;
}

private void updateStage(ImmutableList<Uniform> uniforms) {
Expand All @@ -40,6 +48,14 @@ private static long getCurrentTick() {
}

public void update() {
if (active != null) {
active.removeListeners();
}

active = this;

updateStage(dynamic);

if (once != null) {
updateStage(once);
updateStage(perTick);
Expand Down Expand Up @@ -68,19 +84,35 @@ public void update() {
}
}

public void removeListeners() {
active = null;

for (ValueUpdateNotifier notifier : notifiersToReset) {
notifier.setListener(null);
}
}

public static void clearActiveUniforms() {
if (active != null) {
active.removeListeners();
}
}

public static Builder builder(String name, int program) {
return new Builder(name, program);
}

public static class Builder implements LocationalUniformHolder {
public static class Builder implements DynamicLocationalUniformHolder {
private final String name;
private final int program;

private final Map<Integer, String> locations;
private final Map<String, Uniform> once;
private final Map<String, Uniform> perTick;
private final Map<String, Uniform> perFrame;
private final Map<String, Uniform> dynamic;
private final Map<String, UniformType> uniformNames;
private final List<ValueUpdateNotifier> notifiersToReset;

protected Builder(String name, int program) {
this.name = name;
Expand All @@ -90,7 +122,9 @@ protected Builder(String name, int program) {
once = new HashMap<>();
perTick = new HashMap<>();
perFrame = new HashMap<>();
dynamic = new HashMap<>();
uniformNames = new HashMap<>();
notifiersToReset = new ArrayList<>();
}

@Override
Expand Down Expand Up @@ -170,10 +204,20 @@ public ProgramUniforms buildUniforms() {
once.remove(name);
perTick.remove(name);
perFrame.remove(name);
dynamic.remove(name);
}
}

return new ProgramUniforms(ImmutableList.copyOf(once.values()), ImmutableList.copyOf(perTick.values()), ImmutableList.copyOf(perFrame.values()));
return new ProgramUniforms(ImmutableList.copyOf(once.values()), ImmutableList.copyOf(perTick.values()), ImmutableList.copyOf(perFrame.values()),
ImmutableList.copyOf(dynamic.values()), ImmutableList.copyOf(notifiersToReset));
}

@Override
public Builder addDynamicUniform(Uniform uniform, ValueUpdateNotifier notifier) {
dynamic.put(locations.get(uniform.getLocation()), uniform);
notifiersToReset.add(notifier);

return this;
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/main/java/net/coderbot/iris/gl/state/StateUpdateNotifiers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.coderbot.iris.gl.state;

import net.coderbot.iris.gl.uniform.ValueUpdateNotifier;

/**
* Holds some standard update notifiers for various elements of GL state. Currently, this class has a few listeners for
* fog-related values.
*/
public class StateUpdateNotifiers {
public static ValueUpdateNotifier fogToggleNotifier;
public static ValueUpdateNotifier fogModeNotifier;
public static ValueUpdateNotifier fogDensityNotifier;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package net.coderbot.iris.gl.uniform;

import java.util.function.DoubleSupplier;
import java.util.function.IntSupplier;

public interface DynamicLocationalUniformHolder extends LocationalUniformHolder, DynamicUniformHolder {
DynamicLocationalUniformHolder addDynamicUniform(Uniform uniform, ValueUpdateNotifier notifier);

default DynamicLocationalUniformHolder uniform1f(String name, FloatSupplier value, ValueUpdateNotifier notifier) {
location(name, UniformType.FLOAT).ifPresent(id -> addDynamicUniform(new FloatUniform(id, value, notifier), notifier));

return this;
}

default DynamicLocationalUniformHolder uniform1f(String name, IntSupplier value, ValueUpdateNotifier notifier) {
location(name, UniformType.FLOAT).ifPresent(id -> addDynamicUniform(new FloatUniform(id, () -> (float) value.getAsInt(), notifier), notifier));

return this;
}

default DynamicLocationalUniformHolder uniform1f(String name, DoubleSupplier value, ValueUpdateNotifier notifier) {
location(name, UniformType.FLOAT).ifPresent(id -> addDynamicUniform(new FloatUniform(id, () -> (float) value.getAsDouble(), notifier), notifier));

return this;
}

default DynamicLocationalUniformHolder uniform1i(String name, IntSupplier value, ValueUpdateNotifier notifier) {
location(name, UniformType.INT).ifPresent(id -> addDynamicUniform(new IntUniform(id, value, notifier), notifier));

return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.coderbot.iris.gl.uniform;

import java.util.function.DoubleSupplier;
import java.util.function.IntSupplier;

public interface DynamicUniformHolder extends UniformHolder {
DynamicUniformHolder uniform1f(String name, FloatSupplier value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform1f(String name, IntSupplier value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform1f(String name, DoubleSupplier value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform1i(String name, IntSupplier value, ValueUpdateNotifier notifier);
}
14 changes: 13 additions & 1 deletion src/main/java/net/coderbot/iris/gl/uniform/FloatUniform.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@ public class FloatUniform extends Uniform {
private final FloatSupplier value;

FloatUniform(int location, FloatSupplier value) {
super(location);
this(location, value, null);
}

FloatUniform(int location, FloatSupplier value, ValueUpdateNotifier notifier) {
super(location, notifier);

this.cachedValue = 0;
this.value = value;
}

@Override
public void update() {
updateValue();

if (notifier != null) {
notifier.setListener(this::updateValue);
}
}

private void updateValue() {
float newValue = value.getAsFloat();

if (cachedValue != newValue) {
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/net/coderbot/iris/gl/uniform/IntUniform.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,26 @@ public class IntUniform extends Uniform {
private final IntSupplier value;

IntUniform(int location, IntSupplier value) {
super(location);
this(location, value, null);
}

IntUniform(int location, IntSupplier value, ValueUpdateNotifier notifier) {
super(location, notifier);

this.cachedValue = 0;
this.value = value;
}

@Override
public void update() {
updateValue();

if (notifier != null) {
notifier.setListener(this::updateValue);
}
}

private void updateValue() {
int newValue = value.getAsInt();

if (cachedValue != newValue) {
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/net/coderbot/iris/gl/uniform/Uniform.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@

public abstract class Uniform {
protected final int location;
protected final ValueUpdateNotifier notifier;

Uniform(int location) {
this(location, null);
}

Uniform(int location, ValueUpdateNotifier notifier) {
this.location = location;
this.notifier = notifier;
}

public abstract void update();

public int getLocation() {
public final int getLocation() {
return location;
}

public final ValueUpdateNotifier getNotifier() {
return notifier;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.coderbot.iris.gl.uniform;

/**
* A
*/
public interface ValueUpdateNotifier {
/**
* Sets up a listener with this notifier. Whenever the underlying value of
* @param listener
*/
void setListener(Runnable listener);
}
5 changes: 5 additions & 0 deletions src/main/java/net/coderbot/iris/mixin/MixinWorldRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.coderbot.iris.HorizonRenderer;
import net.coderbot.iris.Iris;
import net.coderbot.iris.fantastic.FlushableVertexConsumerProvider;
import net.coderbot.iris.gl.program.Program;
import net.coderbot.iris.layer.GbufferProgram;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.uniforms.CapturedRenderingState;
Expand Down Expand Up @@ -49,6 +50,9 @@ public class MixinWorldRenderer {
private void iris$beginWorldRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo callback) {
CapturedRenderingState.INSTANCE.setGbufferModelView(matrices.peek().getModel());
CapturedRenderingState.INSTANCE.setTickDelta(tickDelta);

Program.unbind();

pipeline = Iris.getPipelineManager().preparePipeline(Iris.getCurrentDimension());

pipeline.beginWorldRendering();
Expand All @@ -60,6 +64,7 @@ public class MixinWorldRenderer {
MinecraftClient.getInstance().getProfiler().swap("iris_final");
pipeline.finalizeWorldRendering();
pipeline = null;
Program.unbind();
}

@Inject(method = RENDER, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;updateChunks(J)V", shift = At.Shift.AFTER))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package net.coderbot.iris.mixin.statelisteners;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(targets = "com/mojang/blaze3d/platform/GlStateManager$CapabilityTracker")
public interface CapabilityTrackerAccessor {
@Accessor("state")
boolean getState();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.coderbot.iris.mixin.statelisteners;

import com.mojang.blaze3d.platform.GlStateManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(GlStateManager.class)
public interface GlStateManagerAccessor {
@Accessor("FOG")
static GlStateManager.FogState getFOG() {
throw new AssertionError();
}
}
Loading

0 comments on commit 425c19d

Please sign in to comment.