diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index d3fea1c6c..a36335422 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -12,14 +12,12 @@ import com.jozufozu.flywheel.config.BackendTypeArgument; import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.core.Components; -import com.jozufozu.flywheel.core.GameStateRegistry; import com.jozufozu.flywheel.core.Models; import com.jozufozu.flywheel.core.PartialModel; import com.jozufozu.flywheel.core.QuadConverter; import com.jozufozu.flywheel.core.StitchedSprite; import com.jozufozu.flywheel.core.compile.ProgramCompiler; import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; -import com.jozufozu.flywheel.core.shader.NormalDebugStateProvider; import com.jozufozu.flywheel.event.EntityWorldHandler; import com.jozufozu.flywheel.event.ForgeEvents; import com.jozufozu.flywheel.event.ReloadRenderersEvent; @@ -111,8 +109,6 @@ public class Flywheel { Components.init(); - GameStateRegistry.register(NormalDebugStateProvider.INSTANCE); - VanillaInstances.init(); // https://github.com/Jozufozu/Flywheel/issues/69 diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java index 88a49c4fc..6cc6e89d8 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java @@ -4,4 +4,6 @@ import net.minecraft.core.BlockPos; public interface Instance { BlockPos getWorldPosition(); + + boolean isRemoved(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Material.java b/src/main/java/com/jozufozu/flywheel/api/material/Material.java index 42df89830..5db75cb12 100644 --- a/src/main/java/com/jozufozu/flywheel/api/material/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/material/Material.java @@ -4,13 +4,18 @@ import com.jozufozu.flywheel.api.RenderStage; import com.jozufozu.flywheel.core.source.FileResolution; import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; public interface Material { RenderStage getRenderStage(); - RenderType getRenderType(); + RenderType getBatchingRenderType(); FileResolution getVertexShader(); FileResolution getFragmentShader(); + + void setup(); + + void clear(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/Loader.java b/src/main/java/com/jozufozu/flywheel/backend/Loader.java index fa5864d6f..3519ace3e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Loader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Loader.java @@ -1,11 +1,18 @@ package com.jozufozu.flywheel.backend; +import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.core.ComponentRegistry; +import com.jozufozu.flywheel.core.compile.ContextShader; +import com.jozufozu.flywheel.core.compile.ProgramCompiler; import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.core.source.ShaderLoadingException; import com.jozufozu.flywheel.core.source.ShaderSources; import com.jozufozu.flywheel.core.source.error.ErrorReporter; +import com.jozufozu.flywheel.util.StringUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -40,6 +47,8 @@ public class Loader implements ResourceManagerReloadListener { var errorReporter = new ErrorReporter(); ShaderSources sources = new ShaderSources(errorReporter, manager); + Backend.LOGGER.info("Loaded all shader sources in " + sources.getLoadTime()); + FileResolution.run(errorReporter, sources); if (errorReporter.hasErrored()) { @@ -49,9 +58,28 @@ public class Loader implements ResourceManagerReloadListener { sources.postResolve(); + Backend.LOGGER.info("Successfully resolved all source files."); + FileResolution.checkAll(errorReporter); - Backend.LOGGER.info("Loaded all shader sources."); + Backend.LOGGER.info("All shaders passed checks."); + + long compileStart = System.nanoTime(); + + for (Material material : ComponentRegistry.materials) { + for (StructType structType : ComponentRegistry.structTypes) { + for (VertexType vertexType : ComponentRegistry.vertexTypes) { + for (ContextShader contextShader : ComponentRegistry.contextShaders) { + var ctx = new ProgramCompiler.Context(vertexType, material, structType.getInstanceShader(), contextShader); + ProgramCompiler.INSTANCE.getProgram(ctx); + } + } + } + } + + long compileEnd = System.nanoTime(); + + Backend.LOGGER.info("Compiled all programs in " + StringUtil.formatTime(compileEnd - compileStart)); ClientLevel world = Minecraft.getInstance().level; if (Backend.canUseInstancing(world)) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java index b0540f66f..dabf09c7f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java @@ -86,7 +86,7 @@ public class GlVertexArray extends GlObject { offsets[i] = offset; strides[i] = stride; - GL20.glVertexAttribPointer(i++, attribute.size(), attribute.type().getGlEnum(), attribute.normalized(), stride, offset); + GL32.glVertexAttribPointer(i++, attribute.size(), attribute.type().getGlEnum(), attribute.normalized(), stride, offset); offset += attribute.getByteWidth(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java index bacab4c7c..a93ec6046 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java @@ -11,7 +11,6 @@ import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlObject; import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.core.compile.ShaderCompilationException; -import com.jozufozu.flywheel.core.shader.ShaderConstants; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; @@ -20,12 +19,10 @@ public class GlShader extends GlObject { public final ShaderType type; private final List parts; - private final ShaderConstants constants; - public GlShader(String source, ShaderType type, List parts, ShaderConstants constants) throws ShaderCompilationException { + public GlShader(String source, ShaderType type, List parts) throws ShaderCompilationException { this.parts = parts; this.type = type; - this.constants = constants; int handle = GL20.glCreateShader(type.glEnum); GlCompat.safeShaderSource(handle, source); @@ -50,7 +47,7 @@ public class GlShader extends GlObject { .map(ResourceLocation::toString) .map(s -> s.replaceAll("/", "_") .replaceAll(":", "\\$")) - .collect(Collectors.joining(";")) + ';' + Integer.toHexString(constants.hashCode()); + .collect(Collectors.joining(";")); } private void dumpSource(String source, ShaderType type) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java index 38315bf87..a01577dc9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java @@ -90,6 +90,11 @@ public abstract class AbstractInstance implements Instance, LightListener { return removed; } + @Override + public boolean isRemoved() { + return removed; + } + @Override public void onLightUpdate(LightLayer type, ImmutableBox changed) { updateLight(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractStorage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractStorage.java new file mode 100644 index 000000000..b1c666bbc --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractStorage.java @@ -0,0 +1,48 @@ +package com.jozufozu.flywheel.backend.instancing; + +import java.util.ArrayList; +import java.util.List; + +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.TickableInstance; +import com.jozufozu.flywheel.api.instancer.InstancerManager; +import com.jozufozu.flywheel.light.LightUpdater; + +public abstract class AbstractStorage implements Storage { + protected final List tickableInstances; + protected final List dynamicInstances; + protected final InstancerManager instancerManager; + + protected AbstractStorage(InstancerManager instancerManager) { + this.instancerManager = instancerManager; + + this.dynamicInstances = new ArrayList<>(); + this.tickableInstances = new ArrayList<>(); + } + + @Override + public List getInstancesForTicking() { + return tickableInstances; + } + + @Override + public List getInstancesForUpdate() { + return dynamicInstances; + } + + protected void setup(AbstractInstance renderer) { + renderer.init(); + renderer.updateLight(); + LightUpdater.get(renderer.level) + .addListener(renderer); + if (renderer instanceof TickableInstance r) { + tickableInstances.add(r); + r.tick(); + } + + if (renderer instanceof DynamicInstance r) { + dynamicInstances.add(r); + r.beginFrame(); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/One2OneStorage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/One2OneStorage.java index 75ede30b6..d82858ad6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/One2OneStorage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/One2OneStorage.java @@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -12,20 +13,12 @@ import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancerManager; import com.jozufozu.flywheel.light.LightUpdater; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; - -public abstract class One2OneStorage implements Storage { +public abstract class One2OneStorage extends AbstractStorage { private final Map instances; - private final Object2ObjectOpenHashMap tickableInstances; - private final Object2ObjectOpenHashMap dynamicInstances; - protected final InstancerManager instancerManager; public One2OneStorage(InstancerManager instancerManager) { - this.instancerManager = instancerManager; + super(instancerManager); this.instances = new HashMap<>(); - - this.dynamicInstances = new Object2ObjectOpenHashMap<>(); - this.tickableInstances = new Object2ObjectOpenHashMap<>(); } @Override @@ -38,16 +31,6 @@ public abstract class One2OneStorage implements Storage { return instances.values(); } - @Override - public List getInstancesForTicking() { - return new ArrayList<>(tickableInstances.values()); - } - - @Override - public List getInstancesForUpdate() { - return new ArrayList<>(dynamicInstances.values()); - } - @Override public void invalidate() { instances.values().forEach(AbstractInstance::remove); @@ -74,8 +57,8 @@ public abstract class One2OneStorage implements Storage { } instance.remove(); - dynamicInstances.remove(obj); - tickableInstances.remove(obj); + dynamicInstances.remove(instance); + tickableInstances.remove(instance); LightUpdater.get(instance.level) .removeListener(instance); } @@ -109,7 +92,7 @@ public abstract class One2OneStorage implements Storage { AbstractInstance out = createRaw(obj); if (out != null) { - setup(obj, out); + setup(out); } return out; @@ -120,7 +103,7 @@ public abstract class One2OneStorage implements Storage { AbstractInstance renderer = createRaw(obj); if (renderer != null) { - setup(obj, renderer); + setup(renderer); instances.put(obj, renderer); } @@ -128,20 +111,4 @@ public abstract class One2OneStorage implements Storage { @Nullable protected abstract AbstractInstance createRaw(T obj); - - private void setup(T obj, AbstractInstance renderer) { - renderer.init(); - renderer.updateLight(); - LightUpdater.get(renderer.level) - .addListener(renderer); - if (renderer instanceof TickableInstance r) { - tickableInstances.put(obj, r); - r.tick(); - } - - if (renderer instanceof DynamicInstance r) { - dynamicInstances.put(obj, r); - r.beginFrame(); - } - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchLists.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchLists.java index b870acb9d..3d3be00b2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchLists.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchLists.java @@ -12,6 +12,7 @@ public class BatchLists { public final Map>> renderLists = new HashMap<>(); public void add(TransformSet set) { - renderLists.computeIfAbsent(set.material.getRenderType(), k -> new ArrayList<>()).add(set); + renderLists.computeIfAbsent(set.material.getBatchingRenderType(), k -> new ArrayList<>()) + .add(set); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java index fda91b5a7..efff6bd4e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/effect/EffectInstanceManager.java @@ -11,6 +11,7 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancerManager; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; +import com.jozufozu.flywheel.backend.instancing.AbstractStorage; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.Storage; import com.jozufozu.flywheel.light.LightUpdater; @@ -33,18 +34,13 @@ public class EffectInstanceManager extends InstanceManager { return true; } - public static class EffectStorage implements Storage { + public static class EffectStorage extends AbstractStorage { private final Multimap instances; - private final Set dynamicInstances; - private final Set tickableInstances; - private final InstancerManager manager; public EffectStorage(InstancerManager manager) { + super(manager); this.instances = HashMultimap.create(); - this.dynamicInstances = new HashSet<>(); - this.tickableInstances = new HashSet<>(); - this.manager = manager; } @Override @@ -57,16 +53,6 @@ public class EffectInstanceManager extends InstanceManager { return instances.values(); } - @Override - public List getInstancesForTicking() { - return new ArrayList<>(tickableInstances); - } - - @Override - public List getInstancesForUpdate() { - return new ArrayList<>(dynamicInstances); - } - @Override public void invalidate() { instances.values().forEach(AbstractInstance::removeAndMark); @@ -123,27 +109,11 @@ public class EffectInstanceManager extends InstanceManager { } private void create(T obj) { - var instances = obj.createInstances(manager); + var instances = obj.createInstances(instancerManager); this.instances.putAll(obj, instances); instances.forEach(this::setup); } - - private void setup(AbstractInstance renderer) { - renderer.init(); - renderer.updateLight(); - LightUpdater.get(renderer.level) - .addListener(renderer); - if (renderer instanceof TickableInstance r) { - tickableInstances.add(r); - r.tick(); - } - - if (renderer instanceof DynamicInstance r) { - dynamicInstances.add(r); - r.beginFrame(); - } - } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index b4fd04b11..b59aa562a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import org.jetbrains.annotations.NotNull; +import org.lwjgl.opengl.GL32; import com.google.common.collect.ListMultimap; import com.jozufozu.flywheel.api.RenderStage; @@ -13,23 +14,21 @@ import com.jozufozu.flywheel.api.instancer.InstancedPart; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.gl.GlTextureUnit; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.MeshPool; -import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo; -import com.jozufozu.flywheel.core.GameStateRegistry; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.core.compile.ContextShader; import com.jozufozu.flywheel.core.compile.ProgramCompiler; -import com.jozufozu.flywheel.core.shader.StateSnapshot; import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.core.uniform.UniformBuffer; -import com.jozufozu.flywheel.util.Textures; import com.jozufozu.flywheel.util.WeakHashSet; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Camera; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; import net.minecraft.util.Mth; @@ -73,20 +72,11 @@ public class InstancingEngine implements Engine { @Override public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) { - if (!renderLists.process(stage)) { - return; - } + var multimap = renderLists.get(stage); - var renderList = renderLists.get(stage); - for (var entry : renderList.entrySet()) { - var multimap = entry.getValue(); + setup(); - if (multimap.isEmpty()) { - return; - } - - render(entry.getKey(), multimap); - } + render(multimap); } // TODO: Is this useful? Should it be added to the base interface? Currently it is only used for the old CrumblingRenderer. @@ -96,27 +86,28 @@ public class InstancingEngine implements Engine { return; } - for (RenderStage stage : renderLists.stagesToProcess) { - var renderList = renderLists.get(stage); - for (var entry : renderList.entrySet()) { - var multimap = entry.getValue(); + setup(); - if (multimap.isEmpty()) { - return; - } - - render(entry.getKey(), multimap); - } + for (var multimap : renderLists.getAll()) { + render(multimap); } - - renderLists.stagesToProcess.clear(); } - protected void render(RenderType type, ListMultimap multimap) { - type.setupRenderState(); - Textures.bindActiveTextures(); - CoreShaderInfo coreShaderInfo = CoreShaderInfo.get(); - StateSnapshot state = GameStateRegistry.takeSnapshot(); + private void setup() { + GlTextureUnit.T2.makeActive(); + Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); + + RenderSystem.depthMask(true); + RenderSystem.colorMask(true, true, true, true); + RenderSystem.enableDepthTest(); + RenderSystem.depthFunc(GL32.GL_LEQUAL); + RenderSystem.enableCull(); + } + + protected void render(ListMultimap multimap) { + if (multimap.isEmpty()) { + return; + } for (var entry : multimap.asMap().entrySet()) { var shader = entry.getKey(); @@ -128,28 +119,29 @@ public class InstancingEngine implements Engine { continue; } - setup(shader, coreShaderInfo, state); + setup(shader); + + shader.material().setup(); for (var drawCall : drawCalls) { drawCall.render(); } + shader.material().clear(); } - - type.clearRenderState(); } - protected void setup(ShaderState desc, CoreShaderInfo coreShaderInfo, StateSnapshot ctx) { + protected void setup(ShaderState desc) { VertexType vertexType = desc.vertex(); FileResolution instanceShader = desc.instance() .getInstanceShader(); Material material = desc.material(); - var program = ProgramCompiler.INSTANCE.getProgram(new ProgramCompiler.Context(vertexType, material, - instanceShader, context, coreShaderInfo.getAdjustedAlphaDiscard(), coreShaderInfo.fogType(), ctx)); + var ctx = new ProgramCompiler.Context(vertexType, material, instanceShader, context); - program.bind(); + ProgramCompiler.INSTANCE.getProgram(ctx) + .bind(); UniformBuffer.getInstance().sync(); } @@ -197,8 +189,6 @@ public class InstancingEngine implements Engine { } uninitializedModels.clear(); - renderLists.prepare(); - MeshPool.getInstance() .flush(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/RenderLists.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/RenderLists.java index 34ecab81a..eef738b3f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/RenderLists.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/RenderLists.java @@ -1,28 +1,23 @@ package com.jozufozu.flywheel.backend.instancing.instancing; -import java.util.Collections; +import java.util.Collection; import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; import java.util.Map; -import java.util.Set; import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; import com.jozufozu.flywheel.api.RenderStage; import com.jozufozu.flywheel.api.material.Material; -import net.minecraft.client.renderer.RenderType; - public class RenderLists { - private final Map>> renderLists = new EnumMap<>(RenderStage.class); - public final Set stagesToProcess = EnumSet.noneOf(RenderStage.class); + public final Map> renderLists = new EnumMap<>(RenderStage.class); - public Map> get(RenderStage stage) { + public ListMultimap get(RenderStage stage) { var renderList = renderLists.get(stage); if (renderList == null) { - return Collections.emptyMap(); + return ImmutableListMultimap.of(); } return renderList; } @@ -30,28 +25,15 @@ public class RenderLists { public void add(ShaderState shaderState, DrawCall layer) { Material material = shaderState.material(); - renderLists - .computeIfAbsent(material.getRenderStage(), k -> new HashMap<>()) - .computeIfAbsent(material.getRenderType(), k -> ArrayListMultimap.create()) + renderLists.computeIfAbsent(material.getRenderStage(), k -> ArrayListMultimap.create()) .put(shaderState, layer); } - public void prepare() { - stagesToProcess.clear(); - - stagesToProcess.addAll(renderLists.keySet()); - } - - /** - * Check and mark a stage as processed. - * @param stage The stage to check. - * @return {@code true} if the stage should be processed. - */ - public boolean process(RenderStage stage) { - return stagesToProcess.remove(stage); - } - public boolean isEmpty() { - return stagesToProcess.isEmpty(); + return renderLists.isEmpty(); + } + + public Collection> getAll() { + return renderLists.values(); } } diff --git a/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java b/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java index 46b9c18bc..6200c4679 100644 --- a/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java +++ b/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java @@ -16,44 +16,55 @@ import com.jozufozu.flywheel.core.compile.ContextShader; import net.minecraft.resources.ResourceLocation; public class ComponentRegistry { + private static final Registry uniformProviders = new Registry<>(); - private static final Set uniformProviderFiles = new HashSet<>(); - private static final List uniformProviders = new ArrayList<>(); + public static final Set materials = new HashSet<>(); + public static final Set> structTypes = new HashSet<>(); + public static final Set vertexTypes = new HashSet<>(); + public static final Set contextShaders = new HashSet<>(); // TODO: fill out the rest of the registry public static T register(T material) { + materials.add(material); return material; } public static > T register(T type) { - + structTypes.add(type); return type; } public static T register(T vertexType) { + vertexTypes.add(vertexType); return vertexType; } public static ContextShader register(ContextShader contextShader) { + contextShaders.add(contextShader); return contextShader; } public static T register(T provider) { - - var file = provider.getUniformShader(); - - ResourceLocation location = file.getFileLoc(); - if (uniformProviderFiles.contains(location)) { - throw new IllegalArgumentException("UniformProvider for '" + location + "' already registered"); - } - - uniformProviderFiles.add(location); - uniformProviders.add(provider); - return provider; + return uniformProviders.register(provider.getUniformShader() + .getFileLoc(), provider); } public static Collection getAllUniformProviders() { - return Collections.unmodifiableCollection(uniformProviders); + return Collections.unmodifiableCollection(uniformProviders.objects); + } + + private static class Registry { + private final Set files = new HashSet<>(); + private final List objects = new ArrayList<>(); + + public O register(ResourceLocation loc, O object) { + if (files.contains(loc)) { + throw new IllegalArgumentException("Shader file already registered: " + loc); + } + files.add(loc); + objects.add(object); + return object; + } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/Components.java b/src/main/java/com/jozufozu/flywheel/core/Components.java index 32c35a119..3edc8496d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Components.java +++ b/src/main/java/com/jozufozu/flywheel/core/Components.java @@ -5,7 +5,6 @@ import java.util.function.BiConsumer; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.core.compile.ContextShader; import com.jozufozu.flywheel.core.crumbling.CrumblingProgram; -import com.jozufozu.flywheel.core.shader.WorldProgram; import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.core.source.SourceChecks; import com.jozufozu.flywheel.core.source.SourceFile; @@ -24,7 +23,7 @@ public class Components { public static final ViewProvider VIEW_PROVIDER = ComponentRegistry.register(new ViewProvider()); public static final FogProvider FOG_PROVIDER = ComponentRegistry.register(new FogProvider()); public static final ContextShader WORLD = ComponentRegistry.register(new ContextShader(WorldProgram::new, Files.WORLD_VERTEX, Files.WORLD_FRAGMENT)); - public static final ContextShader CRUMBLING = ComponentRegistry.register(new ContextShader(CrumblingProgram::new, Files.CRUMBLING_VERTEX, Files.CRUMBLING_FRAGMENT)); + public static final ContextShader CRUMBLING = ComponentRegistry.register(new ContextShader(CrumblingProgram::new, Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT)); public static void init() { Files.init(); @@ -42,43 +41,44 @@ public class Components { public static final FileResolution TRANSFORMED = instanceVertex(ResourceUtil.subPath(Names.TRANSFORMED, ".vert")); public static final FileResolution ORIENTED = instanceVertex(ResourceUtil.subPath(Names.ORIENTED, ".vert")); public static final FileResolution DEFAULT_VERTEX = materialVertex(ResourceUtil.subPath(Names.DEFAULT, ".vert")); - public static final FileResolution DEFAULT_FRAGMENT = materialFragment(ResourceUtil.subPath(Names.DEFAULT, ".frag")); public static final FileResolution SHADED_VERTEX = materialVertex(ResourceUtil.subPath(Names.SHADED, ".vert")); + public static final FileResolution DEFAULT_FRAGMENT = materialFragment(ResourceUtil.subPath(Names.DEFAULT, ".frag")); + public static final FileResolution CUTOUT_FRAGMENT = materialFragment(ResourceUtil.subPath(Names.CUTOUT, ".frag")); public static final FileResolution WORLD_VERTEX = contextVertex(ResourceUtil.subPath(Names.WORLD, ".vert")); public static final FileResolution WORLD_FRAGMENT = contextFragment(ResourceUtil.subPath(Names.WORLD, ".frag")); public static final FileResolution CRUMBLING_VERTEX = contextVertex(ResourceUtil.subPath(Names.CRUMBLING, ".vert")); public static final FileResolution CRUMBLING_FRAGMENT = contextFragment(ResourceUtil.subPath(Names.CRUMBLING, ".frag")); - public static FileResolution uniform(ResourceLocation location) { + private static FileResolution uniform(ResourceLocation location) { return FileResolution.get(location); } - public static FileResolution layoutVertex(ResourceLocation location) { + private static FileResolution layoutVertex(ResourceLocation location) { return FileResolution.get(location) .validateWith(Checks.LAYOUT_VERTEX); } - public static FileResolution instanceVertex(ResourceLocation location) { + private static FileResolution instanceVertex(ResourceLocation location) { return FileResolution.get(location) .validateWith(Checks.INSTANCE_VERTEX); } - public static FileResolution materialVertex(ResourceLocation location) { + private static FileResolution materialVertex(ResourceLocation location) { return FileResolution.get(location) .validateWith(Checks.MATERIAL_VERTEX); } - public static FileResolution materialFragment(ResourceLocation location) { + private static FileResolution materialFragment(ResourceLocation location) { return FileResolution.get(location) .validateWith(Checks.MATERIAL_FRAGMENT); } - public static FileResolution contextVertex(ResourceLocation location) { + private static FileResolution contextVertex(ResourceLocation location) { return FileResolution.get(location) .validateWith(Checks.CONTEXT_VERTEX); } - public static FileResolution contextFragment(ResourceLocation location) { + private static FileResolution contextFragment(ResourceLocation location) { return FileResolution.get(location) .validateWith(Checks.CONTEXT_FRAGMENT); } @@ -106,6 +106,7 @@ public class Components { public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented"); public static final ResourceLocation DEFAULT = Flywheel.rl("material/default"); + public static final ResourceLocation CUTOUT = Flywheel.rl("material/cutout"); public static final ResourceLocation SHADED = Flywheel.rl("material/shaded"); public static final ResourceLocation WORLD = Flywheel.rl("context/world"); public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling"); diff --git a/src/main/java/com/jozufozu/flywheel/core/CoreShaderInfoMap.java b/src/main/java/com/jozufozu/flywheel/core/CoreShaderInfoMap.java deleted file mode 100644 index 33dfb683f..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/CoreShaderInfoMap.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.jozufozu.flywheel.core; - -import static com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType.COLOR_FOG; -import static com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType.FADE_FOG; -import static com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType.NO_FOG; - -import java.util.HashMap; -import java.util.Map; - -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.backend.ShadersModHandler; -import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType; -import com.mojang.blaze3d.systems.RenderSystem; - -import net.minecraft.client.renderer.ShaderInstance; - -public class CoreShaderInfoMap { - private static final Map MAP = new HashMap<>(); - - static { - registerInfo("block", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("new_entity", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("particle", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - registerInfo("position", new CoreShaderInfo(-1, false, COLOR_FOG)); - registerInfo("position_color", new CoreShaderInfo(0, false, NO_FOG)); - registerInfo("position_color_lightmap", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("position_color_tex", new CoreShaderInfo(0.1f, false, NO_FOG)); - registerInfo("position_color_tex_lightmap", new CoreShaderInfo(0.1f, false, NO_FOG)); - registerInfo("position_tex", new CoreShaderInfo(0, false, NO_FOG)); - registerInfo("position_tex_color", new CoreShaderInfo(0.1f, false, NO_FOG)); - registerInfo("position_tex_color_normal", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - registerInfo("position_tex_lightmap_color", new CoreShaderInfo(0.1f, false, NO_FOG)); - registerInfo("rendertype_solid", new CoreShaderInfo(-1, false, COLOR_FOG)); - registerInfo("rendertype_cutout_mipped", new CoreShaderInfo(ShadersModHandler.isShaderPackInUse() ? 0.1f : 0.5f, false, COLOR_FOG)); - registerInfo("rendertype_cutout", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - registerInfo("rendertype_translucent", new CoreShaderInfo(-1, false, COLOR_FOG)); - registerInfo("rendertype_translucent_moving_block", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("rendertype_translucent_no_crumbling", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("rendertype_armor_cutout_no_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_solid", new CoreShaderInfo(-1, true, COLOR_FOG)); - registerInfo("rendertype_entity_cutout", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_cutout_no_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_cutout_no_cull_z_offset", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_item_entity_translucent_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_translucent_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_translucent", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_smooth_cutout", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_beacon_beam", new CoreShaderInfo(-1, false, COLOR_FOG)); - registerInfo("rendertype_entity_decal", new CoreShaderInfo(0.1f, true, COLOR_FOG)); - registerInfo("rendertype_entity_no_outline", new CoreShaderInfo(-1, true, COLOR_FOG)); - registerInfo("rendertype_entity_shadow", new CoreShaderInfo(-1, false, COLOR_FOG)); - // Special alpha discard - registerInfo("rendertype_entity_alpha", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("rendertype_eyes", new CoreShaderInfo(-1, false, FADE_FOG)); - registerInfo("rendertype_energy_swirl", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_leash", new CoreShaderInfo(-1, false, COLOR_FOG)); - registerInfo("rendertype_water_mask", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("rendertype_outline", new CoreShaderInfo(0, false, NO_FOG)); - registerInfo("rendertype_armor_glint", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_armor_entity_glint", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_glint_translucent", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_glint", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_glint_direct", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_entity_glint", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_entity_glint_direct", new CoreShaderInfo(0.1f, false, FADE_FOG)); - registerInfo("rendertype_text", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - registerInfo("rendertype_text_intensity", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - registerInfo("rendertype_text_see_through", new CoreShaderInfo(0.1f, false, NO_FOG)); - registerInfo("rendertype_text_intensity_see_through", new CoreShaderInfo(0.1f, false, NO_FOG)); - registerInfo("rendertype_lightning", new CoreShaderInfo(-1, false, FADE_FOG)); - registerInfo("rendertype_tripwire", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - registerInfo("rendertype_end_portal", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("rendertype_end_gateway", new CoreShaderInfo(-1, false, NO_FOG)); - registerInfo("rendertype_lines", new CoreShaderInfo(-1, false, COLOR_FOG)); - registerInfo("rendertype_crumbling", new CoreShaderInfo(0.1f, false, NO_FOG)); - - registerInfo("forge:rendertype_entity_unlit_translucent", new CoreShaderInfo(0.1f, false, COLOR_FOG)); - } - - public static void registerInfo(String name, CoreShaderInfo info) { - MAP.put(name, info); - } - - @Nullable - public static CoreShaderInfo getInfo(String name) { - return MAP.get(name); - } - - public record CoreShaderInfo(float alphaDiscard, boolean appliesDiffuse, FogType fogType) { - public static final CoreShaderInfo DEFAULT = new CoreShaderInfo(-1, false, NO_FOG); - - public static CoreShaderInfo get() { - CoreShaderInfo out = null; - ShaderInstance coreShader = RenderSystem.getShader(); - if (coreShader != null) { - String coreShaderName = coreShader.getName(); - out = getInfo(coreShaderName); - } - if (out == null) { - out = DEFAULT; - } - return out; - } - - public float getAdjustedAlphaDiscard() { - float alphaDiscard = alphaDiscard(); - if (alphaDiscard == 0) { - alphaDiscard = 0.0001f; - } else if (alphaDiscard < 0) { - alphaDiscard = 0; - } - return alphaDiscard; - } - - public enum FogType { - NO_FOG, - COLOR_FOG, - FADE_FOG; - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java b/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java deleted file mode 100644 index 7d797a5bb..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.jozufozu.flywheel.core; - -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; - -import com.jozufozu.flywheel.core.shader.GameStateProvider; -import com.jozufozu.flywheel.core.shader.ShaderConstants; -import com.jozufozu.flywheel.core.shader.StateSnapshot; - -public class GameStateRegistry { - - private static final List PROVIDERS = new ArrayList<>(); - - /** - * Registers a game state provider. - * @param provider The provider to register. - */ - public static void register(GameStateProvider provider) { - PROVIDERS.add(provider); - } - - /** - * Takes a snapshot of the current game state, storing it in a bit set. - * @return An object that represents the current game state. - */ - public static StateSnapshot takeSnapshot() { - BitSet bitSet = new BitSet(PROVIDERS.size()); - - for (int i = 0, listSize = PROVIDERS.size(); i < listSize; i++) { - if (PROVIDERS.get(i).isTrue()) { - bitSet.set(i); - } - } - return new StateSnapshot(bitSet); - } - - /** - * Based on the given snapshot, gathers shader constants to be injected during shader compilation. - * @param snapshot The snapshot to use. - * @return A list of shader constants. - */ - public static ShaderConstants getShaderConstants(StateSnapshot snapshot) { - BitSet ctx = snapshot.ctx(); - ShaderConstants shaderConstants = new ShaderConstants(); - - for (int i = 0, listSize = PROVIDERS.size(); i < listSize; i++) { - if (ctx.get(i)) { - PROVIDERS.get(i).alterConstants(shaderConstants); - } - } - return shaderConstants; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/Materials.java b/src/main/java/com/jozufozu/flywheel/core/Materials.java index 82b1a01b4..d83021605 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Materials.java +++ b/src/main/java/com/jozufozu/flywheel/core/Materials.java @@ -3,6 +3,7 @@ package com.jozufozu.flywheel.core; import com.jozufozu.flywheel.api.RenderStage; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.core.material.SimpleMaterial; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; @@ -10,11 +11,33 @@ import net.minecraft.resources.ResourceLocation; public class Materials { private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); - public static final Material DEFAULT = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_SOLID_TERRAIN, RenderType.cutout(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); - public static final Material CHEST = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, Sheets.chestSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); - public static final Material SHULKER = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); - public static final Material BELL = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, Sheets.solidBlockSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); - public static final Material MINECART = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_ENTITIES, RenderType.entitySolid(MINECART_LOCATION), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); + public static final Material DEFAULT = SimpleMaterial.builder() + .stage(RenderStage.AFTER_SOLID_TERRAIN) + .renderType(RenderType.cutout()) + .fragmentShader(Components.Files.CUTOUT_FRAGMENT) + .register(); + public static final Material CHEST = SimpleMaterial.builder() + .stage(RenderStage.AFTER_BLOCK_ENTITIES) + .renderType(Sheets.chestSheet()) + .diffuseTex(Sheets.CHEST_SHEET) + .register(); + public static final Material SHULKER = SimpleMaterial.builder() + .stage(RenderStage.AFTER_BLOCK_ENTITIES) + .renderType(Sheets.shulkerBoxSheet()) + .diffuseTex(Sheets.SHULKER_SHEET) + .fragmentShader(Components.Files.CUTOUT_FRAGMENT) + .alsoSetup(RenderSystem::disableCull) + .alsoClear(RenderSystem::enableCull) + .register(); + public static final Material BELL = SimpleMaterial.builder() + .stage(RenderStage.AFTER_BLOCK_ENTITIES) + .renderType(Sheets.solidBlockSheet()) + .register(); + public static final Material MINECART = SimpleMaterial.builder() + .stage(RenderStage.AFTER_ENTITIES) + .renderType(RenderType.entitySolid(MINECART_LOCATION)) + .diffuseTex(MINECART_LOCATION) + .register(); public static void init() { // noop diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java b/src/main/java/com/jozufozu/flywheel/core/WorldProgram.java similarity index 93% rename from src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java rename to src/main/java/com/jozufozu/flywheel/core/WorldProgram.java index 0ed6f9620..0be9030ce 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java +++ b/src/main/java/com/jozufozu/flywheel/core/WorldProgram.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.core.shader; +package com.jozufozu.flywheel.core; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java index 13bab6021..2923de834 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java @@ -4,9 +4,6 @@ import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.backend.gl.GLSLVersion; import com.jozufozu.flywheel.backend.gl.shader.GlShader; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; -import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType; -import com.jozufozu.flywheel.core.shader.ShaderConstants; -import com.jozufozu.flywheel.core.shader.StateSnapshot; import com.jozufozu.flywheel.core.source.CompilationContext; import com.jozufozu.flywheel.core.source.SourceFile; @@ -24,10 +21,6 @@ public class FragmentCompiler extends Memoizer 0) { - shaderConstants.define("ALPHA_DISCARD", alphaDiscard); - } - shaderConstants.define(fogType.name()); - - return shaderConstants; - } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java index 89d3aae4b..4b54c2218 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java @@ -3,8 +3,6 @@ package com.jozufozu.flywheel.core.compile; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.jozufozu.flywheel.core.CoreShaderInfoMap; -import com.jozufozu.flywheel.core.shader.StateSnapshot; import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.event.ReloadRenderersEvent; @@ -52,15 +50,13 @@ public class ProgramCompiler extends Memoizer { finalSource.append(CompileUtil.generateHeader(GLSLVersion.V420, ShaderType.VERTEX)); - var shaderConstants = key.ctx.getShaderConstants(); - shaderConstants.writeInto(finalSource); - finalSource.append('\n'); - var index = new CompilationContext(); // LAYOUT @@ -82,7 +77,7 @@ public class VertexCompiler extends Memoizer { """); try { - return new GlShader(finalSource.toString(), ShaderType.VERTEX, ImmutableList.of(layoutShader.name, instanceShader.name, materialShader.name, contextShaderSource.name), shaderConstants); + return new GlShader(finalSource.toString(), ShaderType.VERTEX, ImmutableList.of(layoutShader.name, instanceShader.name, materialShader.name, contextShaderSource.name)); } catch (ShaderCompilationException e) { throw e.withErrorLog(index); } @@ -98,8 +93,7 @@ public class VertexCompiler extends Memoizer { * @param instanceShader The instance shader source. * @param materialShader The vertex material shader source. * @param contextShader The context shader source. - * @param ctx The shader constants to apply. */ - public record Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, SourceFile contextShader, StateSnapshot ctx) { + public record Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, SourceFile contextShader) { } } diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java index 41880da62..777112ee6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.core.crumbling; -import com.jozufozu.flywheel.core.shader.WorldProgram; +import com.jozufozu.flywheel.core.WorldProgram; import net.minecraft.resources.ResourceLocation; diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java index 80f27891a..d4034dd3d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -145,14 +145,5 @@ public class CrumblingRenderer { public CrumblingEngine() { super(Components.CRUMBLING); } - - @Override - protected void render(RenderType type, ListMultimap multimap) { - if (!type.affectsCrumbling()) { - return; - } - - super.render(type, multimap); - } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/material/SimpleMaterial.java b/src/main/java/com/jozufozu/flywheel/core/material/SimpleMaterial.java index c3880e5bd..53ab1d25b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/material/SimpleMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/core/material/SimpleMaterial.java @@ -1,22 +1,43 @@ package com.jozufozu.flywheel.core.material; +import org.jetbrains.annotations.Nullable; + import com.jozufozu.flywheel.api.RenderStage; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.backend.gl.GlTextureUnit; +import com.jozufozu.flywheel.core.ComponentRegistry; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.source.FileResolution; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.InventoryMenu; public class SimpleMaterial implements Material { protected final RenderStage stage; protected final RenderType type; protected final FileResolution vertexShader; protected final FileResolution fragmentShader; + protected final ResourceLocation diffuseTex; + @Nullable + protected final Runnable setup; + @Nullable + protected final Runnable clear; - public SimpleMaterial(RenderStage stage, RenderType type, FileResolution vertexShader, FileResolution fragmentShader) { + public SimpleMaterial(RenderStage stage, RenderType type, FileResolution vertexShader, FileResolution fragmentShader, ResourceLocation diffuseTex, @Nullable Runnable setup, @Nullable Runnable clear) { this.stage = stage; this.type = type; this.vertexShader = vertexShader; this.fragmentShader = fragmentShader; + this.diffuseTex = diffuseTex; + this.setup = setup; + this.clear = clear; + } + + public static Builder builder() { + return new Builder(); } @Override @@ -25,7 +46,7 @@ public class SimpleMaterial implements Material { } @Override - public RenderType getRenderType() { + public RenderType getBatchingRenderType() { return type; } @@ -38,4 +59,88 @@ public class SimpleMaterial implements Material { public FileResolution getFragmentShader() { return fragmentShader; } + + @Override + public void setup() { + + GlTextureUnit.T0.makeActive(); + RenderSystem.setShaderTexture(0, diffuseTex); + Minecraft.getInstance().textureManager.bindForSetup(diffuseTex); + + if (setup != null) { + setup.run(); + } + } + + @Override + public void clear() { + GlTextureUnit.T0.makeActive(); + RenderSystem.setShaderTexture(0, 0); + + if (clear != null) { + clear.run(); + } + } + + public static class Builder { + protected RenderStage stage = RenderStage.AFTER_SOLID_TERRAIN; + protected RenderType type = RenderType.solid(); + protected FileResolution vertexShader = Components.Files.SHADED_VERTEX; + protected FileResolution fragmentShader = Components.Files.DEFAULT_FRAGMENT; + protected ResourceLocation diffuseTex = InventoryMenu.BLOCK_ATLAS; + protected Runnable setup = null; + protected Runnable clear = null; + + public Builder() { + } + + public Builder stage(RenderStage stage) { + this.stage = stage; + return this; + } + + public Builder renderType(RenderType type) { + this.type = type; + return this; + } + + public Builder vertexShader(FileResolution vertexShader) { + this.vertexShader = vertexShader; + return this; + } + + public Builder fragmentShader(FileResolution fragmentShader) { + this.fragmentShader = fragmentShader; + return this; + } + + public Builder shaded() { + this.vertexShader = Components.Files.SHADED_VERTEX; + return this; + } + + public Builder unShaded() { + this.vertexShader = Components.Files.DEFAULT_VERTEX; + return this; + } + + public Builder diffuseTex(ResourceLocation diffuseTex) { + this.diffuseTex = diffuseTex; + return this; + } + + public Builder alsoSetup(Runnable runnable) { + this.setup = runnable; + return this; + } + + public Builder alsoClear(Runnable clear) { + this.clear = clear; + return this; + } + + public SimpleMaterial register() { + return ComponentRegistry.register(new SimpleMaterial(stage, type, vertexShader, fragmentShader, diffuseTex, setup, clear)); + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java deleted file mode 100644 index 2ec67744e..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/shader/GameStateProvider.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.jozufozu.flywheel.core.shader; - -/** - * An object that provides a view of the current game state for shader compilation. - */ -public interface GameStateProvider { - - /** - * Get the status of this game state provider. - * @return Returning {@code true} will cause #alterConstants to be called before compiling a shader. - */ - boolean isTrue(); - - /** - * Alter the constants for shader compilation. - * @param constants The shader constants. - */ - void alterConstants(ShaderConstants constants); -} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java deleted file mode 100644 index 50efebd9f..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/shader/NormalDebugStateProvider.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.jozufozu.flywheel.core.shader; - -import com.jozufozu.flywheel.config.FlwConfig; - -public enum NormalDebugStateProvider implements GameStateProvider { - INSTANCE; - - @Override - public boolean isTrue() { - return FlwConfig.get() - .debugNormals(); - } - - @Override - public void alterConstants(ShaderConstants constants) { - constants.define("DEBUG_NORMAL"); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java b/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java deleted file mode 100644 index ece98bd05..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.jozufozu.flywheel.core.shader; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * A class for manipulating a list of {@code #define} directives. - * - *

Based loosely on code by jellysquid3. - */ -public class ShaderConstants { - - private final Map definitions = new HashMap<>(); - - public ShaderConstants define(String def) { - definitions.put(def, ""); - return this; - } - - public ShaderConstants define(String def, String value) { - definitions.put(def, value); - return this; - } - - public ShaderConstants define(String def, float value) { - definitions.put(def, Float.toString(value)); - return this; - } - - public ShaderConstants defineAll(List defines) { - for (String def : defines) { - definitions.put(def, ""); - } - return this; - } - - public String build() { - final StringBuilder acc = new StringBuilder(); - writeInto(acc); - return acc.toString(); - } - - public void writeInto(final StringBuilder acc) { - for (Map.Entry e : definitions.entrySet()) { - acc.append("#define ") - .append(e.getKey()); - if (e.getValue().length() > 0) { - acc.append(' ') - .append(e.getValue()); - } - acc.append('\n'); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ShaderConstants that = (ShaderConstants) o; - return Objects.equals(definitions, that.definitions); - } - - @Override - public int hashCode() { - return Objects.hash(definitions); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java b/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java deleted file mode 100644 index 6a01a90f1..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/shader/StateSnapshot.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.jozufozu.flywheel.core.shader; - -import java.util.BitSet; - -import com.jozufozu.flywheel.core.GameStateRegistry; - -public record StateSnapshot(BitSet ctx) { - // TODO: is this needed? - - public ShaderConstants getShaderConstants() { - return GameStateRegistry.getShaderConstants(this); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/package-info.java b/src/main/java/com/jozufozu/flywheel/core/shader/package-info.java deleted file mode 100644 index d25693290..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/shader/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -package com.jozufozu.flywheel.core.shader; - -import javax.annotation.ParametersAreNonnullByDefault; - -import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java index 3b156b34f..4d8a2284b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java @@ -29,7 +29,12 @@ public class ShaderSources implements SourceFinder { public final Index index; + public final long loadTimeNs; + public final long indexTimeNs; + public final long totalTimeNs; + public ShaderSources(ErrorReporter errorReporter, ResourceManager manager) { + long loadStart = System.nanoTime(); for (ResourceLocation location : getValidShaderFiles(manager)) { try (Resource resource = manager.getResource(location)) { @@ -42,8 +47,15 @@ public class ShaderSources implements SourceFinder { // } } + long loadEnd = System.nanoTime(); + long indexStart = System.nanoTime(); index = new Index(shaderSources); + long indexEnd = System.nanoTime(); + + loadTimeNs = loadEnd - loadStart; + indexTimeNs = indexEnd - indexStart; + totalTimeNs = indexEnd - loadStart; } public void postResolve() { @@ -67,4 +79,8 @@ public class ShaderSources implements SourceFinder { return false; }); } + + public String getLoadTime() { + return StringUtil.formatTime(totalTimeNs); + } } diff --git a/src/main/java/com/jozufozu/flywheel/util/StringUtil.java b/src/main/java/com/jozufozu/flywheel/util/StringUtil.java index 9a1d5d2e9..054bf0f43 100644 --- a/src/main/java/com/jozufozu/flywheel/util/StringUtil.java +++ b/src/main/java/com/jozufozu/flywheel/util/StringUtil.java @@ -8,6 +8,8 @@ import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; +import java.text.DecimalFormat; +import java.text.NumberFormat; import java.util.Arrays; import java.util.stream.Collectors; @@ -15,6 +17,20 @@ import org.lwjgl.system.MemoryUtil; public class StringUtil { + private static final NumberFormat timeFormat = new DecimalFormat("#0.000"); + + public static String formatTime(long ns) { + if (ns < 1000) { + return ns + " ns"; + } else if (ns < 1000000) { + return timeFormat.format(ns / 1000.) + " μs"; + } else if (ns < 1000000000) { + return timeFormat.format(ns / 1000000.) + " ms"; + } else { + return timeFormat.format(ns / 1000000000.) + " s"; + } + } + public static String args(String functionName, Object... args) { return functionName + '(' + Arrays.stream(args) diff --git a/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl b/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl index 4b652fa18..735f7a84e 100644 --- a/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl +++ b/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl @@ -19,3 +19,16 @@ in vec4 flw_var3; vec4 flw_fragColor; ivec2 flw_fragOverlay; vec2 flw_fragLight; + +/* + * Must be implemented by materials. + */ +vec4 flw_fogFilter(vec4 color); + +/* + * May be implemented by materials. + * If implemented, a material must define FLW_DISCARD + * + * Guard calls with FLW_DISCARD + */ +bool flw_discardPredicate(vec4 finalColor); diff --git a/src/main/resources/assets/flywheel/flywheel/context/common.vert b/src/main/resources/assets/flywheel/flywheel/context/common.vert index 6ea08bf2f..46730bb38 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/common.vert +++ b/src/main/resources/assets/flywheel/flywheel/context/common.vert @@ -4,11 +4,6 @@ #use "flywheel:uniform/view.glsl" void flw_contextVertex() { - // TODO: remove this - #ifdef DEBUG_NORMAL - flw_vertexColor = vec4(flw_vertexNormal, 1.0); - #endif - flw_distance = fog_distance(flw_vertexPos.xyz, flw_cameraPos.xyz, flw_fogShape); gl_Position = flw_viewProjection * flw_vertexPos; flw_vertexNormal = normalize(flw_vertexNormal); diff --git a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag index a6dbf8caa..c2c32b9c1 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag @@ -1,6 +1,4 @@ #use "flywheel:api/fragment.glsl" -#use "flywheel:util/fog.glsl" -#use "flywheel:uniform/fog.glsl" uniform sampler2D flw_diffuseTex; @@ -36,17 +34,11 @@ void flw_initFragment() { void flw_contextFragment() { vec4 color = flw_fragColor; - #ifdef ALPHA_DISCARD - if (color.a < ALPHA_DISCARD) { + #ifdef FLW_DISCARD + if (flw_discardPredicate(color)) { discard; } #endif - #ifdef COLOR_FOG - color = linear_fog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor); - #elif defined(FADE_FOG) - color = linear_fog_fade(color, flw_distance, flw_fogRange.x, flw_fogRange.y); - #endif - - fragColor = color; + fragColor = flw_fogFilter(color); } diff --git a/src/main/resources/assets/flywheel/flywheel/context/world.frag b/src/main/resources/assets/flywheel/flywheel/context/world.frag index 7de6a2698..8b5ffdc24 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/world.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/world.frag @@ -1,6 +1,4 @@ #use "flywheel:api/fragment.glsl" -#use "flywheel:util/fog.glsl" -#use "flywheel:uniform/fog.glsl" // optimize discard usage #ifdef ALPHA_DISCARD @@ -30,17 +28,11 @@ void flw_contextFragment() { color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); color *= lightColor; - #ifdef ALPHA_DISCARD - if (color.a < ALPHA_DISCARD) { + #ifdef FLW_DISCARD + if (flw_discardPredicate(color)) { discard; } #endif - #ifdef COLOR_FOG - color = linear_fog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor); - #elif defined(FADE_FOG) - color = linear_fog_fade(color, flw_distance, flw_fogRange.x, flw_fogRange.y); - #endif - - fragColor = color; + fragColor = flw_fogFilter(color); } diff --git a/src/main/resources/assets/flywheel/flywheel/material/cutout.frag b/src/main/resources/assets/flywheel/flywheel/material/cutout.frag new file mode 100644 index 000000000..59342decf --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/material/cutout.frag @@ -0,0 +1,15 @@ +#use "flywheel:api/fragment.glsl" +#use "flywheel:util/fog.glsl" +#use "flywheel:uniform/fog.glsl" + +void flw_materialFragment() { +} + +#define FLW_DISCARD +bool flw_discardPredicate(vec4 finalColor) { + return finalColor.a < 0.1; +} + +vec4 flw_fogFilter(vec4 color) { + return linear_fog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor); +} diff --git a/src/main/resources/assets/flywheel/flywheel/material/default.frag b/src/main/resources/assets/flywheel/flywheel/material/default.frag index 283efd8ca..808233fb4 100644 --- a/src/main/resources/assets/flywheel/flywheel/material/default.frag +++ b/src/main/resources/assets/flywheel/flywheel/material/default.frag @@ -1,4 +1,10 @@ #use "flywheel:api/fragment.glsl" +#use "flywheel:util/fog.glsl" +#use "flywheel:uniform/fog.glsl" void flw_materialFragment() { } + +vec4 flw_fogFilter(vec4 color) { + return linear_fog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor); +}