From 3a581bac7959358801cfc82ef872321ac0f0574a Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:38:14 -0800 Subject: [PATCH] Materials and You: Volume 1 - Add MaterialShaders - MaterialShaders must be registered - Materials are no longer registered - Material now returns a MaterialShaders instead of the locations of each shader - Rename MaterialIndices to MaterialShaderIndicies - Improve MaterialShaderIndicies and move it to the backend package - Use RegisterClientReloadListenersEvent instead of adding listeners manually --- .../java/com/jozufozu/flywheel/Flywheel.java | 23 +++-- .../flywheel/api/material/Material.java | 12 +-- .../api/material/MaterialShaders.java | 14 +++ .../MaterialShaderIndices.java} | 83 ++++++------------ .../flywheel/backend/compile/FlwPrograms.java | 20 +---- .../engine/batching/BatchedCrumbling.java | 7 +- .../engine/batching/BatchedDrawManager.java | 5 +- .../engine/batching/BatchingEngine.java | 2 +- .../engine/batching/TransformCall.java | 1 - .../backend/engine/indirect/IndirectDraw.java | 6 +- .../engine/indirect/IndirectDrawSet.java | 3 +- .../engine/instancing/InstancedCrumbling.java | 72 ++++++++-------- .../engine/instancing/InstancingEngine.java | 6 +- .../flywheel/lib/material/Materials.java | 85 ++++++------------- .../flywheel/lib/material/SimpleMaterial.java | 47 ++++------ .../lib/material/SimpleMaterialShaders.java | 8 ++ .../lib/material/StandardMaterialShaders.java | 35 ++++++++ 17 files changed, 195 insertions(+), 234 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/material/MaterialShaders.java rename src/main/java/com/jozufozu/flywheel/{lib/material/MaterialIndices.java => backend/MaterialShaderIndices.java} (51%) create mode 100644 src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterialShaders.java create mode 100644 src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index 6d3d55d13..36d954cc3 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -8,6 +8,7 @@ import org.slf4j.Logger; import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent; import com.jozufozu.flywheel.api.visualization.VisualizationManager; import com.jozufozu.flywheel.backend.Backends; +import com.jozufozu.flywheel.backend.MaterialShaderIndices; import com.jozufozu.flywheel.backend.compile.FlwPrograms; import com.jozufozu.flywheel.backend.compile.Pipelines; import com.jozufozu.flywheel.backend.engine.UniformBuffer; @@ -22,8 +23,7 @@ import com.jozufozu.flywheel.impl.visualization.VisualizationEventHandler; import com.jozufozu.flywheel.lib.context.Contexts; import com.jozufozu.flywheel.lib.instance.InstanceTypes; import com.jozufozu.flywheel.lib.light.LightUpdater; -import com.jozufozu.flywheel.lib.material.MaterialIndices; -import com.jozufozu.flywheel.lib.material.Materials; +import com.jozufozu.flywheel.lib.material.StandardMaterialShaders; import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker; import com.jozufozu.flywheel.lib.model.ModelCache; import com.jozufozu.flywheel.lib.model.ModelHolder; @@ -42,6 +42,7 @@ import net.minecraft.core.Vec3i; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; +import net.minecraftforge.client.event.RegisterClientReloadListenersEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.eventbus.api.IEventBus; @@ -101,6 +102,10 @@ public class Flywheel { forgeEventBus.addListener(LightUpdater::onClientTick); forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.onUnloadLevel(e)); +// forgeEventBus.addListener(ExampleEffect::tick); +// forgeEventBus.addListener(ExampleEffect::onReload); + + modEventBus.addListener(Flywheel::registerClientReloadListeners); modEventBus.addListener(Flywheel::onClientSetup); modEventBus.addListener(BackendManagerImpl::onEndClientResourceReload); @@ -111,25 +116,25 @@ public class Flywheel { modEventBus.addListener(PartialModel::onModelRegistry); modEventBus.addListener(PartialModel::onModelBake); -// forgeEventBus.addListener(ExampleEffect::tick); -// forgeEventBus.addListener(ExampleEffect::onReload); - BackendManagerImpl.init(); + ShadersModHandler.init(); + Pipelines.init(); Backends.init(); - FlwPrograms.ResourceReloadListener.register(); + } - ShadersModHandler.init(); + private static void registerClientReloadListeners(RegisterClientReloadListenersEvent event) { + event.registerReloadListener(FlwPrograms.ResourceReloadListener.INSTANCE); } private static void onClientSetup(FMLClientSetupEvent event) { VertexTypes.init(); InstanceTypes.init(); - Materials.init(); + StandardMaterialShaders.init(); Contexts.init(); - MaterialIndices.init(); + MaterialShaderIndices.init(); VanillaVisuals.init(); 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 b58ef0d1d..b4e86639d 100644 --- a/src/main/java/com/jozufozu/flywheel/api/material/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/material/Material.java @@ -1,22 +1,14 @@ package com.jozufozu.flywheel.api.material; -import com.jozufozu.flywheel.api.registry.Registry; -import com.jozufozu.flywheel.impl.RegistryImpl; - import net.minecraft.client.renderer.RenderType; -import net.minecraft.resources.ResourceLocation; public interface Material { - static Registry REGISTRY = RegistryImpl.create(); - - ResourceLocation vertexShader(); - - ResourceLocation fragmentShader(); - void setup(); void clear(); + MaterialShaders shaders(); + RenderType getFallbackRenderType(); MaterialVertexTransformer getVertexTransformer(); diff --git a/src/main/java/com/jozufozu/flywheel/api/material/MaterialShaders.java b/src/main/java/com/jozufozu/flywheel/api/material/MaterialShaders.java new file mode 100644 index 000000000..a158211de --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/material/MaterialShaders.java @@ -0,0 +1,14 @@ +package com.jozufozu.flywheel.api.material; + +import com.jozufozu.flywheel.api.registry.Registry; +import com.jozufozu.flywheel.impl.RegistryImpl; + +import net.minecraft.resources.ResourceLocation; + +public interface MaterialShaders { + static Registry REGISTRY = RegistryImpl.create(); + + ResourceLocation vertexShader(); + + ResourceLocation fragmentShader(); +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java b/src/main/java/com/jozufozu/flywheel/backend/MaterialShaderIndices.java similarity index 51% rename from src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java rename to src/main/java/com/jozufozu/flywheel/backend/MaterialShaderIndices.java index 61baac3a7..b50447e90 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java +++ b/src/main/java/com/jozufozu/flywheel/backend/MaterialShaderIndices.java @@ -1,11 +1,10 @@ -package com.jozufozu.flywheel.lib.material; +package com.jozufozu.flywheel.backend; import java.util.List; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Unmodifiable; -import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.material.MaterialShaders; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; @@ -15,83 +14,58 @@ import it.unimi.dsi.fastutil.objects.ObjectList; import it.unimi.dsi.fastutil.objects.ObjectLists; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectSet; -import it.unimi.dsi.fastutil.objects.Reference2IntMap; -import it.unimi.dsi.fastutil.objects.Reference2IntMaps; -import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; import net.minecraft.resources.ResourceLocation; -// TODO: add messages to exceptions -public final class MaterialIndices { - private static Reference2IntMap materialIndices; +public final class MaterialShaderIndices { private static Object2IntMap vertexShaderIndices; private static Object2IntMap fragmentShaderIndices; - private static ObjectList materialsByIndex; private static ObjectList vertexShadersByIndex; private static ObjectList fragmentShadersByIndex; private static boolean initialized; - public static int getMaterialIndex(Material material) { - if (!initialized) { - throw new IllegalStateException(); - } - return materialIndices.getInt(material); + private MaterialShaderIndices() { } public static int getVertexShaderIndex(ResourceLocation vertexShader) { if (!initialized) { - throw new IllegalStateException(); + throw new IllegalStateException("Not initialized!"); } return vertexShaderIndices.getInt(vertexShader); } public static int getFragmentShaderIndex(ResourceLocation fragmentShader) { if (!initialized) { - throw new IllegalStateException(); + throw new IllegalStateException("Not initialized!"); } return fragmentShaderIndices.getInt(fragmentShader); } - public static int getVertexShaderIndex(Material material) { - return getVertexShaderIndex(material.vertexShader()); + public static int getVertexShaderIndex(MaterialShaders shaders) { + return getVertexShaderIndex(shaders.vertexShader()); } - public static int getFragmentShaderIndex(Material material) { - return getFragmentShaderIndex(material.fragmentShader()); - } - - public static Material getMaterial(int index) { - if (!initialized) { - throw new IllegalStateException(); - } - return materialsByIndex.get(index); + public static int getFragmentShaderIndex(MaterialShaders shaders) { + return getFragmentShaderIndex(shaders.fragmentShader()); } public static ResourceLocation getVertexShader(int index) { if (!initialized) { - throw new IllegalStateException(); + throw new IllegalStateException("Not initialized!"); } return vertexShadersByIndex.get(index); } public static ResourceLocation getFragmentShader(int index) { if (!initialized) { - throw new IllegalStateException(); + throw new IllegalStateException("Not initialized!"); } return fragmentShadersByIndex.get(index); } - @Unmodifiable - public static List getAllMaterials() { - if (!initialized) { - throw new IllegalStateException(); - } - return materialsByIndex; - } - @Unmodifiable public static List getAllVertexShaders() { if (!initialized) { - throw new IllegalStateException(); + throw new IllegalStateException("Not initialized!"); } return vertexShadersByIndex; } @@ -99,38 +73,34 @@ public final class MaterialIndices { @Unmodifiable public static List getAllFragmentShaders() { if (!initialized) { - throw new IllegalStateException(); + throw new IllegalStateException("Not initialized!"); } return fragmentShadersByIndex; } private static void initInner() { - int amount = Material.REGISTRY.getAll().size(); + int amount = MaterialShaders.REGISTRY.getAll().size(); - Reference2IntMap materialIndices = new Reference2IntOpenHashMap<>(); Object2IntMap vertexShaderIndices = new Object2IntOpenHashMap<>(); + vertexShaderIndices.defaultReturnValue(-1); Object2IntMap fragmentShaderIndices = new Object2IntOpenHashMap<>(); - ObjectList materialsByIndex = new ObjectArrayList<>(amount); + fragmentShaderIndices.defaultReturnValue(-1); ObjectList vertexShadersByIndex = new ObjectArrayList<>(amount); ObjectList fragmentShadersByIndex = new ObjectArrayList<>(amount); ObjectSet allVertexShaders = new ObjectOpenHashSet<>(); ObjectSet allFragmentShaders = new ObjectOpenHashSet<>(); - int materialIndex = 0; int vertexShaderIndex = 0; int fragmentShaderIndex = 0; - for (Material material : Material.REGISTRY) { - materialIndices.put(material, materialIndex); - materialsByIndex.add(material); - materialIndex++; - ResourceLocation vertexShader = material.vertexShader(); + for (MaterialShaders shaders : MaterialShaders.REGISTRY) { + ResourceLocation vertexShader = shaders.vertexShader(); if (allVertexShaders.add(vertexShader)) { vertexShaderIndices.put(vertexShader, vertexShaderIndex); vertexShadersByIndex.add(vertexShader); vertexShaderIndex++; } - ResourceLocation fragmentShader = material.fragmentShader(); + ResourceLocation fragmentShader = shaders.fragmentShader(); if (allFragmentShaders.add(fragmentShader)) { fragmentShaderIndices.put(fragmentShader, fragmentShaderIndex); fragmentShadersByIndex.add(fragmentShader); @@ -138,18 +108,15 @@ public final class MaterialIndices { } } - MaterialIndices.materialIndices = Reference2IntMaps.unmodifiable(materialIndices); - MaterialIndices.vertexShaderIndices = Object2IntMaps.unmodifiable(vertexShaderIndices); - MaterialIndices.fragmentShaderIndices = Object2IntMaps.unmodifiable(fragmentShaderIndices); - MaterialIndices.materialsByIndex = ObjectLists.unmodifiable(materialsByIndex); - MaterialIndices.vertexShadersByIndex = ObjectLists.unmodifiable(vertexShadersByIndex); - MaterialIndices.fragmentShadersByIndex = ObjectLists.unmodifiable(fragmentShadersByIndex); + MaterialShaderIndices.vertexShaderIndices = Object2IntMaps.unmodifiable(vertexShaderIndices); + MaterialShaderIndices.fragmentShaderIndices = Object2IntMaps.unmodifiable(fragmentShaderIndices); + MaterialShaderIndices.vertexShadersByIndex = ObjectLists.unmodifiable(vertexShadersByIndex); + MaterialShaderIndices.fragmentShadersByIndex = ObjectLists.unmodifiable(fragmentShadersByIndex); initialized = true; } - @ApiStatus.Internal public static void init() { - Material.REGISTRY.addFreezeCallback(MaterialIndices::initInner); + MaterialShaders.REGISTRY.addFreezeCallback(MaterialShaderIndices::initInner); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java index 54f029fa8..7dd533339 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java @@ -6,16 +6,14 @@ import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.uniform.ShaderUniforms; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.MaterialShaderIndices; import com.jozufozu.flywheel.backend.compile.component.MaterialAdapterComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.backend.compile.core.CompilerStats; import com.jozufozu.flywheel.glsl.ShaderSources; import com.jozufozu.flywheel.glsl.generate.FnSignature; import com.jozufozu.flywheel.glsl.generate.GlslExpr; -import com.jozufozu.flywheel.lib.material.MaterialIndices; -import net.minecraft.client.Minecraft; -import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManagerReloadListener; @@ -44,7 +42,7 @@ public class FlwPrograms { private static MaterialAdapterComponent createFragmentMaterialComponent(SourceLoader loadChecker) { return MaterialAdapterComponent.builder(Flywheel.rl("fragment_material_adapter")) - .materialSources(MaterialIndices.getAllFragmentShaders()) + .materialSources(MaterialShaderIndices.getAllFragmentShaders()) .adapt(FnSignature.ofVoid("flw_materialFragment")) .adapt(FnSignature.create() .returnType("bool") @@ -62,7 +60,7 @@ public class FlwPrograms { private static MaterialAdapterComponent createVertexMaterialComponent(SourceLoader loadChecker) { return MaterialAdapterComponent.builder(Flywheel.rl("vertex_material_adapter")) - .materialSources(MaterialIndices.getAllVertexShaders()) + .materialSources(MaterialShaderIndices.getAllVertexShaders()) .adapt(FnSignature.ofVoid("flw_materialVertex")) .switchOn(GlslExpr.variable("_flw_materialVertexID")) .build(loadChecker); @@ -100,17 +98,5 @@ public class FlwPrograms { public void onResourceManagerReload(ResourceManager manager) { FlwPrograms.reload(manager); } - - public static void register() { - // Can be null when running data generators due to the unfortunate time we call this - Minecraft minecraft = Minecraft.getInstance(); - if (minecraft == null) { - return; - } - - if (minecraft.getResourceManager() instanceof ReloadableResourceManager reloadable) { - reloadable.registerReloadListener(INSTANCE); - } - } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedCrumbling.java index 32cf6da25..8729acc46 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedCrumbling.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedCrumbling.java @@ -20,7 +20,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.resources.model.ModelBakery; public class BatchedCrumbling { - static void renderCrumbling(List crumblingBlocks, BatchContext batchContext, BatchedDrawTracker drawTracker) { + public static void render(List crumblingBlocks, BatchContext batchContext, BatchedDrawTracker drawTracker) { var instancesPerType = doCrumblingSort(crumblingBlocks); for (var entry : instancesPerType.entrySet()) { @@ -82,7 +82,7 @@ public class BatchedCrumbling { return out; } - public static int bufferOne(BatchedInstancer batchedInstancer, int baseVertex, ReusableVertexList vertexList, DrawBuffer drawBuffer, Instance instance) { + private static int bufferOne(BatchedInstancer batchedInstancer, int baseVertex, ReusableVertexList vertexList, DrawBuffer drawBuffer, Instance instance) { int totalVertices = 0; for (TransformCall transformCall : batchedInstancer.getTransformCalls()) { @@ -101,9 +101,8 @@ public class BatchedCrumbling { return totalVertices; } - static final class CrumblingBucket { + private static class CrumblingBucket { private int vertexCount; private final List>> instances = new ArrayList<>(); - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedDrawManager.java index 9f494ca9c..9c645e3a2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedDrawManager.java @@ -44,6 +44,7 @@ class BatchedDrawManager extends InstancerStorage> { return new BatchedInstancer<>(type); } + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override protected void add(InstancerKey key, BatchedInstancer instancer, Model model, RenderStage stage) { var stagePlan = stagePlans.computeIfAbsent(stage, renderStage -> new BatchedStagePlan(renderStage, drawTracker)); @@ -51,8 +52,10 @@ class BatchedDrawManager extends InstancerStorage> { for (var entry : meshes.entrySet()) { var material = entry.getKey(); RenderType renderType = material.getFallbackRenderType(); - var transformCall = new TransformCall<>(instancer, material, alloc(entry.getValue(), renderType.format())); + var mesh = alloc(entry.getValue(), renderType.format()); + var transformCall = new TransformCall<>(instancer, material, mesh); stagePlan.put(renderType, transformCall); + instancer.addTransformCall((TransformCall) transformCall); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java index a54808494..64d2bf5b3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java @@ -48,7 +48,7 @@ public class BatchingEngine extends AbstractEngine { executor.syncUntil(flushFlag::isRaised); var batchContext = BatchContext.create(context, this.renderOrigin); - BatchedCrumbling.renderCrumbling(crumblingBlocks, batchContext, this.drawManager.drawTracker); + BatchedCrumbling.render(crumblingBlocks, batchContext, this.drawManager.drawTracker); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java index b7f7511bd..4b2cb434d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java @@ -30,7 +30,6 @@ public class TransformCall { this.instancer = instancer; this.material = material; this.mesh = mesh; - instancer.addTransformCall(this); InstanceVertexTransformer instanceVertexTransformer = instancer.type.getVertexTransformer(); InstanceBoundingSphereTransformer boundingSphereTransformer = instancer.type.getBoundingSphereTransformer(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java index 245fb79a4..760d390c9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java @@ -5,7 +5,7 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.lib.material.MaterialIndices; +import com.jozufozu.flywheel.backend.MaterialShaderIndices; public class IndirectDraw { private final IndirectInstancer instancer; @@ -25,8 +25,8 @@ public class IndirectDraw { this.mesh = mesh; this.stage = stage; - this.vertexMaterialID = MaterialIndices.getVertexShaderIndex(material); - this.fragmentMaterialID = MaterialIndices.getFragmentShaderIndex(material); + this.vertexMaterialID = MaterialShaderIndices.getVertexShaderIndex(material.shaders()); + this.fragmentMaterialID = MaterialShaderIndices.getFragmentShaderIndex(material.shaders()); } public IndirectInstancer instancer() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java index c9b77c7c7..78e9886c2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java @@ -13,7 +13,6 @@ import java.util.Map; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.lib.material.MaterialIndices; public class IndirectDrawSet { @@ -49,7 +48,7 @@ public class IndirectDrawSet { multiDraws.clear(); // sort by stage, then material indirectDraws.sort(Comparator.comparing(IndirectDraw::stage) - .thenComparing(draw -> MaterialIndices.getMaterialIndex(draw.material()))); + .thenComparing(draw -> draw.material().hashCode())); for (int start = 0, i = 0; i < indirectDraws.size(); i++) { var draw = indirectDraws.get(i); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java index 738ef53a9..02d071233 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java @@ -23,42 +23,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.resources.model.ModelBakery; public class InstancedCrumbling { - @NotNull - public static Map>> doCrumblingSort(List instances) { - Map>> out = new HashMap<>(); - - for (Engine.CrumblingBlock triple : instances) { - int progress = triple.progress(); - - if (progress < 0 || progress >= ModelBakery.DESTROY_TYPES.size()) { - continue; - } - - for (Instance instance : triple.instances()) { - // Filter out instances that weren't created by this engine. - // If all is well, we probably shouldn't take the `continue` - // branches but better to do checked casts. - if (!(instance.handle() instanceof InstanceHandleImpl impl)) { - continue; - } - if (!(impl.instancer instanceof InstancedInstancer instancer)) { - continue; - } - - List draws = instancer.drawCalls(); - - draws.removeIf(DrawCall::isInvalid); - - for (DrawCall draw : draws) { - out.computeIfAbsent(draw.shaderState, $ -> new Int2ObjectArrayMap<>()) - .computeIfAbsent(progress, $ -> new ArrayList<>()) - .add(() -> draw.renderOne(impl)); - } - } - } - return out; - } - public static void render(List crumblingBlocks) { // Sort draw calls into buckets, so we don't have to do as many shader binds. var byShaderState = doCrumblingSort(crumblingBlocks); @@ -108,6 +72,42 @@ public class InstancedCrumbling { } } + @NotNull + private static Map>> doCrumblingSort(List instances) { + Map>> out = new HashMap<>(); + + for (Engine.CrumblingBlock triple : instances) { + int progress = triple.progress(); + + if (progress < 0 || progress >= ModelBakery.DESTROY_TYPES.size()) { + continue; + } + + for (Instance instance : triple.instances()) { + // Filter out instances that weren't created by this engine. + // If all is well, we probably shouldn't take the `continue` + // branches but better to do checked casts. + if (!(instance.handle() instanceof InstanceHandleImpl impl)) { + continue; + } + if (!(impl.instancer instanceof InstancedInstancer instancer)) { + continue; + } + + List draws = instancer.drawCalls(); + + draws.removeIf(DrawCall::isInvalid); + + for (DrawCall draw : draws) { + out.computeIfAbsent(draw.shaderState, $ -> new Int2ObjectArrayMap<>()) + .computeIfAbsent(progress, $ -> new ArrayList<>()) + .add(() -> draw.renderOne(impl)); + } + } + } + return out; + } + private static int getDiffuseTexture(Material material) { material.setup(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java index 1cea1109b..61afd655f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java @@ -9,6 +9,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.task.Plan; import com.jozufozu.flywheel.api.task.TaskExecutor; +import com.jozufozu.flywheel.backend.MaterialShaderIndices; import com.jozufozu.flywheel.backend.compile.InstancingPrograms; import com.jozufozu.flywheel.backend.engine.AbstractEngine; import com.jozufozu.flywheel.backend.engine.AbstractInstancer; @@ -18,7 +19,6 @@ import com.jozufozu.flywheel.gl.GlStateTracker; import com.jozufozu.flywheel.gl.GlTextureUnit; import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.lib.context.Contexts; -import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.jozufozu.flywheel.lib.task.Flag; import com.jozufozu.flywheel.lib.task.NamedFlag; import com.jozufozu.flywheel.lib.task.SyncedPlan; @@ -125,8 +125,8 @@ public class InstancingEngine extends AbstractEngine { public static void uploadMaterialIDUniform(GlProgram program, Material material) { int materialIDUniform = program.getUniformLocation("_flw_materialID_instancing"); - int vertexID = MaterialIndices.getVertexShaderIndex(material); - int fragmentID = MaterialIndices.getFragmentShaderIndex(material); + int vertexID = MaterialShaderIndices.getVertexShaderIndex(material.shaders()); + int fragmentID = MaterialShaderIndices.getFragmentShaderIndex(material.shaders()); GL32.glUniform2ui(materialIDUniform, vertexID, fragmentID); } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java index c53363dfb..3de25529c 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java @@ -1,8 +1,5 @@ package com.jozufozu.flywheel.lib.material; -import org.jetbrains.annotations.ApiStatus; - -import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.MaterialVertexTransformer; import com.jozufozu.flywheel.gl.GlTextureUnit; @@ -37,109 +34,92 @@ public final class Materials { private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); public static final Material CHUNK_SOLID_SHADED = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) - .fragmentShader(Files.DEFAULT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(RenderType.solid()) .vertexTransformer(SHADING_TRANSFORMER) - .register(); + .build(); public static final Material CHUNK_SOLID_UNSHADED = SimpleMaterial.builder() - .vertexShader(Files.DEFAULT_VERTEX) - .fragmentShader(Files.DEFAULT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) .fallbackRenderType(RenderType.solid()) - .register(); + .build(); public static final Material CHUNK_CUTOUT_MIPPED_SHADED = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(RenderType.cutoutMipped()) .vertexTransformer(SHADING_TRANSFORMER) - .register(); + .build(); public static final Material CHUNK_CUTOUT_MIPPED_UNSHADED = SimpleMaterial.builder() - .vertexShader(Files.DEFAULT_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .shaders(StandardMaterialShaders.CUTOUT) .fallbackRenderType(RenderType.cutoutMipped()) - .register(); + .build(); public static final Material CHUNK_CUTOUT_SHADED = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false)) + .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(RenderType.cutout()) .vertexTransformer(SHADING_TRANSFORMER) - .register(); + .build(); public static final Material CHUNK_CUTOUT_UNSHADED = SimpleMaterial.builder() - .vertexShader(Files.DEFAULT_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false)) + .shaders(StandardMaterialShaders.CUTOUT) .fallbackRenderType(RenderType.cutout()) - .register(); + .build(); public static final Material CHUNK_TRANSLUCENT_SHADED = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) - .fragmentShader(Files.DEFAULT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(RenderType.translucent()) .vertexTransformer(SHADING_TRANSFORMER) - .register(); + .build(); public static final Material CHUNK_TRANSLUCENT_UNSHADED = SimpleMaterial.builder() - .vertexShader(Files.DEFAULT_VERTEX) - .fragmentShader(Files.DEFAULT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) .addShard(Shards.TRANSLUCENT_TRANSPARENCY) .fallbackRenderType(RenderType.translucent()) - .register(); + .build(); public static final Material CHUNK_TRIPWIRE_SHADED = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(RenderType.tripwire()) .vertexTransformer(SHADING_TRANSFORMER) - .register(); + .build(); public static final Material CHUNK_TRIPWIRE_UNSHADED = SimpleMaterial.builder() - .vertexShader(Files.DEFAULT_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .shaders(StandardMaterialShaders.CUTOUT) .fallbackRenderType(RenderType.tripwire()) - .register(); + .build(); public static final Material CHEST = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) .addShard(Shards.diffuseTex(Sheets.CHEST_SHEET, false, false)) + .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(Sheets.chestSheet()) - .register(); + .build(); public static final Material SHULKER = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) - .fragmentShader(Files.CUTOUT_FRAGMENT) .addShard(Shards.diffuseTex(Sheets.SHULKER_SHEET, false, false)) .addShard(Shards.DISABLE_CULL) + .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(Sheets.shulkerBoxSheet()) - .register(); + .build(); public static final Material BELL = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false)) + .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(Sheets.solidBlockSheet()) - .register(); + .build(); public static final Material MINECART = SimpleMaterial.builder() - .vertexShader(Files.SHADED_VERTEX) .addShard(Shards.diffuseTex(MINECART_LOCATION, false, false)) + .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(RenderType.entitySolid(MINECART_LOCATION)) - .register(); + .build(); private Materials() { } - @ApiStatus.Internal - public static void init() { - } - public static final class Shards { public static final GlStateShard DISABLE_CULL = new GlStateShard( () -> { @@ -176,17 +156,4 @@ public final class Materials { ); } } - - public static final class Files { - public static final ResourceLocation DEFAULT_VERTEX = Names.DEFAULT.withSuffix(".vert"); - public static final ResourceLocation SHADED_VERTEX = Names.SHADED.withSuffix(".vert"); - public static final ResourceLocation DEFAULT_FRAGMENT = Names.DEFAULT.withSuffix(".frag"); - public static final ResourceLocation CUTOUT_FRAGMENT = Names.CUTOUT.withSuffix(".frag"); - } - - public static final class Names { - 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"); - } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java index 219434a11..8be882b3d 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java @@ -1,25 +1,23 @@ package com.jozufozu.flywheel.lib.material; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.material.MaterialShaders; import com.jozufozu.flywheel.api.material.MaterialVertexTransformer; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; -import net.minecraft.resources.ResourceLocation; public class SimpleMaterial implements Material { - protected final ResourceLocation vertexShader; - protected final ResourceLocation fragmentShader; protected final Runnable setup; protected final Runnable clear; + protected final MaterialShaders shaders; protected final RenderType fallbackRenderType; protected final MaterialVertexTransformer vertexTransformer; - public SimpleMaterial(ResourceLocation vertexShader, ResourceLocation fragmentShader, Runnable setup, Runnable clear, RenderType fallbackRenderType, MaterialVertexTransformer vertexTransformer) { - this.vertexShader = vertexShader; - this.fragmentShader = fragmentShader; + public SimpleMaterial(Runnable setup, Runnable clear, MaterialShaders shaders, RenderType fallbackRenderType, MaterialVertexTransformer vertexTransformer) { this.setup = setup; this.clear = clear; + this.shaders = shaders; this.fallbackRenderType = fallbackRenderType; this.vertexTransformer = vertexTransformer; } @@ -28,16 +26,6 @@ public class SimpleMaterial implements Material { return new Builder(); } - @Override - public ResourceLocation vertexShader() { - return vertexShader; - } - - @Override - public ResourceLocation fragmentShader() { - return fragmentShader; - } - @Override public void setup() { setup.run(); @@ -48,6 +36,11 @@ public class SimpleMaterial implements Material { clear.run(); } + @Override + public MaterialShaders shaders() { + return shaders; + } + @Override public RenderType getFallbackRenderType() { return fallbackRenderType; @@ -59,26 +52,15 @@ public class SimpleMaterial implements Material { } public static class Builder { - protected ResourceLocation vertexShader = Materials.Files.DEFAULT_VERTEX; - protected ResourceLocation fragmentShader = Materials.Files.DEFAULT_FRAGMENT; protected Runnable setup = () -> {}; protected Runnable clear = () -> {}; + protected MaterialShaders shaders = StandardMaterialShaders.DEFAULT; protected RenderType fallbackRenderType = RenderType.solid(); protected MaterialVertexTransformer vertexTransformer = (vertexList, level) -> {}; public Builder() { } - public Builder vertexShader(ResourceLocation vertexShader) { - this.vertexShader = vertexShader; - return this; - } - - public Builder fragmentShader(ResourceLocation fragmentShader) { - this.fragmentShader = fragmentShader; - return this; - } - public Builder addSetup(Runnable setup) { this.setup = chain(this.setup, setup); return this; @@ -95,6 +77,11 @@ public class SimpleMaterial implements Material { return this; } + public Builder shaders(MaterialShaders shaders) { + this.shaders = shaders; + return this; + } + public Builder fallbackRenderType(RenderType type) { this.fallbackRenderType = type; return this; @@ -105,8 +92,8 @@ public class SimpleMaterial implements Material { return this; } - public SimpleMaterial register() { - return Material.REGISTRY.registerAndGet(new SimpleMaterial(vertexShader, fragmentShader, setup, clear, fallbackRenderType, vertexTransformer)); + public SimpleMaterial build() { + return new SimpleMaterial(setup, clear, shaders, fallbackRenderType, vertexTransformer); } private static Runnable chain(Runnable runnable1, Runnable runnable2) { diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterialShaders.java b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterialShaders.java new file mode 100644 index 000000000..2ac0c6d6c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterialShaders.java @@ -0,0 +1,8 @@ +package com.jozufozu.flywheel.lib.material; + +import com.jozufozu.flywheel.api.material.MaterialShaders; + +import net.minecraft.resources.ResourceLocation; + +public record SimpleMaterialShaders(ResourceLocation vertexShader, ResourceLocation fragmentShader) implements MaterialShaders { +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java b/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java new file mode 100644 index 000000000..a642ff4b8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/material/StandardMaterialShaders.java @@ -0,0 +1,35 @@ +package com.jozufozu.flywheel.lib.material; + +import org.jetbrains.annotations.ApiStatus; + +import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.material.MaterialShaders; + +import net.minecraft.resources.ResourceLocation; + +public final class StandardMaterialShaders { + public static final MaterialShaders DEFAULT = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Files.DEFAULT_VERTEX, Files.DEFAULT_FRAGMENT)); + public static final MaterialShaders SHADED = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Files.SHADED_VERTEX, Files.DEFAULT_FRAGMENT)); + public static final MaterialShaders CUTOUT = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Files.DEFAULT_VERTEX, Files.CUTOUT_FRAGMENT)); + public static final MaterialShaders SHADED_CUTOUT = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Files.SHADED_VERTEX, Files.CUTOUT_FRAGMENT)); + + private StandardMaterialShaders() { + } + + @ApiStatus.Internal + public static void init() { + } + + public static final class Files { + public static final ResourceLocation DEFAULT_VERTEX = Names.DEFAULT.withSuffix(".vert"); + public static final ResourceLocation SHADED_VERTEX = Names.SHADED.withSuffix(".vert"); + public static final ResourceLocation DEFAULT_FRAGMENT = Names.DEFAULT.withSuffix(".frag"); + public static final ResourceLocation CUTOUT_FRAGMENT = Names.CUTOUT.withSuffix(".frag"); + } + + public static final class Names { + public static final ResourceLocation DEFAULT = Flywheel.rl("material/default"); + public static final ResourceLocation SHADED = Flywheel.rl("material/shaded"); + public static final ResourceLocation CUTOUT = Flywheel.rl("material/cutout"); + } +}