diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index 7d7465897..c541fbbeb 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -11,24 +11,15 @@ import com.jozufozu.flywheel.backend.model.MeshPool; import com.jozufozu.flywheel.config.BackendTypeArgument; import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; -import com.jozufozu.flywheel.core.Contexts; -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.*; import com.jozufozu.flywheel.core.compile.ProgramCompiler; import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; -import com.jozufozu.flywheel.core.material.MaterialShaders; import com.jozufozu.flywheel.core.shader.NormalDebugStateProvider; -import com.jozufozu.flywheel.core.structs.InstanceShaders; -import com.jozufozu.flywheel.core.vertex.LayoutShaders; import com.jozufozu.flywheel.event.EntityWorldHandler; import com.jozufozu.flywheel.event.ForgeEvents; import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor; import com.jozufozu.flywheel.vanilla.VanillaInstances; -import com.jozufozu.flywheel.vanilla.effect.ExampleEffect; import com.mojang.logging.LogUtils; import net.minecraft.commands.synchronization.ArgumentTypes; @@ -112,10 +103,7 @@ public class Flywheel { // forgeEventBus.addListener(ExampleEffect::tick); // forgeEventBus.addListener(ExampleEffect::onReload); - LayoutShaders.init(); - InstanceShaders.init(); - Contexts.init(); - MaterialShaders.init(); + Components.init(); GameStateRegistry.register(NormalDebugStateProvider.INSTANCE); 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 c9b80ef43..1525f48b7 100644 --- a/src/main/java/com/jozufozu/flywheel/api/material/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/material/Material.java @@ -1,9 +1,17 @@ package com.jozufozu.flywheel.api.material; import com.jozufozu.flywheel.core.source.FileResolution; +import com.jozufozu.flywheel.core.source.SourceFile; import net.minecraft.client.renderer.RenderType; public record Material(RenderType renderType, FileResolution vertexShader, FileResolution fragmentShader) { + public SourceFile getVertexShader() { + return vertexShader.getFile(); + } + + public SourceFile getFragmentShader() { + return fragmentShader.getFile(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java b/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java new file mode 100644 index 000000000..2e189f452 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/uniform/UniformProvider.java @@ -0,0 +1,24 @@ +package com.jozufozu.flywheel.api.uniform; + +import java.nio.ByteBuffer; + +import com.jozufozu.flywheel.core.source.FileResolution; + +public abstract class UniformProvider { + + protected ByteBuffer buffer; + protected Notifier notifier; + + public abstract int getSize(); + + public void updatePtr(ByteBuffer backing, Notifier notifier) { + this.buffer = backing; + this.notifier = notifier; + } + + public abstract FileResolution getUniformShader(); + + public interface Notifier { + void signalChanged(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/Loader.java b/src/main/java/com/jozufozu/flywheel/backend/Loader.java index dfcdf4caa..fa5864d6f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Loader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Loader.java @@ -47,6 +47,10 @@ public class Loader implements ResourceManagerReloadListener { throw new ShaderLoadingException("Failed to resolve all source files, see log for details"); } + sources.postResolve(); + + FileResolution.checkAll(errorReporter); + Backend.LOGGER.info("Loaded all shader sources."); ClientLevel world = Minecraft.getInstance().level; diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java index c02a418c6..84650d9b2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java @@ -88,9 +88,9 @@ public abstract class GlProgram extends GlObject { /** * A factory interface to create a {@link GlProgram}. */ - public interface Factory

{ + public interface Factory { @NotNull - P create(ResourceLocation name, int handle); + GlProgram create(ResourceLocation name, int handle); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index 78ba4c6c3..cc0405fec 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -9,11 +9,10 @@ import com.jozufozu.flywheel.backend.instancing.effect.Effect; import com.jozufozu.flywheel.backend.instancing.effect.EffectInstanceManager; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager; import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine; -import com.jozufozu.flywheel.core.Contexts; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.util.ClientLevelExtension; -import com.jozufozu.flywheel.vanilla.effect.ExampleEffect; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; @@ -39,7 +38,7 @@ public class InstanceWorld { public static InstanceWorld create(LevelAccessor level) { var engine = switch (Backend.getBackendType()) { - case INSTANCING -> new InstancingEngine<>(Contexts.WORLD); + case INSTANCING -> new InstancingEngine(Components.WORLD); case BATCHING -> new BatchingEngine(); case OFF -> throw new IllegalStateException("Cannot create instance world when backend is off."); }; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index ab05356a4..604e62014 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -16,6 +16,7 @@ import com.jozufozu.flywheel.vanilla.effect.ExampleEffect; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.RenderType; +import net.minecraft.core.Vec3i; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.entity.BlockEntity; @@ -131,4 +132,8 @@ public class InstancedRenderDispatcher { debug.add("Disabled"); } } + + public static Vec3i getOriginCoordinate(ClientLevel level) { + return instanceWorlds.get(level).engine.getOriginCoordinate(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/SadCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/SadCrumbling.java new file mode 100644 index 000000000..fc29d871d --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/SadCrumbling.java @@ -0,0 +1,154 @@ +package com.jozufozu.flywheel.backend.instancing; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; + +import javax.annotation.Nonnull; + +import org.jetbrains.annotations.NotNull; + +import com.jozufozu.flywheel.api.InstancedPart; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; +import com.jozufozu.flywheel.backend.instancing.instancing.GPUInstancer; +import com.jozufozu.flywheel.core.model.ModelSupplier; +import com.jozufozu.flywheel.mixin.LevelRendererAccessor; + +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.server.level.BlockDestructionProgress; + +public class SadCrumbling { +// public void renderCrumbling(LevelRenderer levelRenderer, ClientLevel level, PoseStack stack, Camera camera, Matrix4f projectionMatrix) { +// var dataByStage = getDataByStage(levelRenderer, level); +// if (dataByStage.isEmpty()) { +// return; +// } +// +// var map = modelsToParts(dataByStage); +// var stateSnapshot = GameStateRegistry.takeSnapshot(); +// +//// Vec3 cameraPosition = camera.getPosition(); +//// var camX = cameraPosition.x - originCoordinate.getX(); +//// var camY = cameraPosition.y - originCoordinate.getY(); +//// var camZ = cameraPosition.z - originCoordinate.getZ(); +//// +//// // don't want to mutate viewProjection +//// var vp = projectionMatrix.copy(); +//// vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ); +// +// GlBuffer instanceBuffer = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER); +// +// GlVertexArray crumblingVAO = new GlVertexArray(); +// +// crumblingVAO.bind(); +// +// // crumblingVAO.bindAttributes(); +// +// for (var entry : map.entrySet()) { +// var model = entry.getKey(); +// var parts = entry.getValue(); +// +// if (parts.isEmpty()) { +// continue; +// } +// +// StructType structType = parts.get(0).type; +// +// for (var meshEntry : model.get() +// .entrySet()) { +// Material material = meshEntry.getKey(); +// Mesh mesh = meshEntry.getValue(); +// +// MeshPool.BufferedMesh bufferedMesh = MeshPool.getInstance() +// .get(mesh); +// +// if (bufferedMesh == null || !bufferedMesh.isGpuResident()) { +// continue; +// } +// +// material.renderType().setupRenderState(); +// +// CoreShaderInfoMap.CoreShaderInfo coreShaderInfo = CoreShaderInfoMap.CoreShaderInfo.get(); +// +// +// var program = Compile.PROGRAM.getProgram(new ProgramCompiler.Context(Formats.POS_TEX_NORMAL, +// material, structType.getInstanceShader(), Components.CRUMBLING, +// coreShaderInfo.getAdjustedAlphaDiscard(), coreShaderInfo.fogType(), +// GameStateRegistry.takeSnapshot())); +// +// program.bind(); +// +// // bufferedMesh.drawInstances(); +// } +// } +// } + + @NotNull + private Map> modelsToParts(Int2ObjectMap>> dataByStage) { + var map = new HashMap>(); + + for (var entry : dataByStage.int2ObjectEntrySet()) { + RenderType currentLayer = ModelBakery.DESTROY_TYPES.get(entry.getIntKey()); + + // something about when we call this means that the textures are not ready for use on the first frame they should appear + if (currentLayer == null) { + continue; + } + + for (var blockEntityInstance : entry.getValue()) { + + for (var part : blockEntityInstance.getCrumblingParts()) { + if (part.getOwner() instanceof GPUInstancer instancer) { + + // queue the instances for copying to the crumbling instance buffer + map.computeIfAbsent(instancer.parent.getModel(), k -> new ArrayList<>()).add(part); + } + } + } + } + return map; + } + + @Nonnull + private Int2ObjectMap>> getDataByStage(LevelRenderer levelRenderer, ClientLevel level) { + var destructionProgress = ((LevelRendererAccessor) levelRenderer).flywheel$getDestructionProgress(); + if (destructionProgress.isEmpty()) { + return Int2ObjectMaps.emptyMap(); + } + + if (!(InstancedRenderDispatcher.getInstanceWorld(level) + .getBlockEntities() instanceof BlockEntityInstanceManager beim)) { + return Int2ObjectMaps.emptyMap(); + } + + var dataByStage = new Int2ObjectArrayMap>>(); + + for (var entry : destructionProgress.long2ObjectEntrySet()) { + SortedSet progresses = entry.getValue(); + + if (progresses == null || progresses.isEmpty()) { + continue; + } + + int progress = progresses.last() + .getProgress(); + + var data = dataByStage.computeIfAbsent(progress, $ -> new ArrayList<>()); + + long pos = entry.getLongKey(); + + beim.getCrumblingInstances(pos, data); + } + + return dataByStage; + } +} 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 9e1043636..b8b375dd3 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 @@ -4,67 +4,43 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.SortedSet; - -import javax.annotation.Nonnull; import org.jetbrains.annotations.NotNull; import com.google.common.collect.ListMultimap; -import com.google.common.collect.Multimaps; import com.jozufozu.flywheel.api.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.GlVertexArray; -import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; -import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.Engine; -import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.backend.instancing.TaskEngine; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; -import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.backend.model.MeshPool; -import com.jozufozu.flywheel.core.Contexts; 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.crumbling.CrumblingProgram; -import com.jozufozu.flywheel.core.model.Mesh; -import com.jozufozu.flywheel.core.model.ModelSupplier; import com.jozufozu.flywheel.core.shader.StateSnapshot; -import com.jozufozu.flywheel.core.shader.WorldProgram; import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.vertex.Formats; -import com.jozufozu.flywheel.mixin.LevelRendererAccessor; +import com.jozufozu.flywheel.core.uniform.UniformBuffer; import com.jozufozu.flywheel.util.Textures; import com.jozufozu.flywheel.util.WeakHashSet; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Matrix4f; -import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import net.minecraft.client.Camera; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; -import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; -public class InstancingEngine

implements Engine { +public class InstancingEngine implements Engine { public static int MAX_ORIGIN_DISTANCE = 100; protected BlockPos originCoordinate = BlockPos.ZERO; - protected final ProgramCompiler

context; + protected final ContextShader context; protected final Map, GPUInstancerFactory> factories = new HashMap<>(); @@ -78,7 +54,7 @@ public class InstancingEngine

implements Engine { private int vertexCount; private int instanceCount; - public InstancingEngine(ProgramCompiler

context) { + public InstancingEngine(ContextShader context) { this.context = context; this.instanceManagers = new WeakHashSet<>(); @@ -98,16 +74,8 @@ public class InstancingEngine

implements Engine { @Override public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) { - var camX = context.camX() - originCoordinate.getX(); - var camY = context.camY() - originCoordinate.getY(); - var camZ = context.camZ() - originCoordinate.getZ(); - - // don't want to mutate viewProjection - var vp = context.viewProjection().copy(); - vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ); - for (RenderType renderType : renderLists.drainLayers()) { - render(renderType, camX, camY, camZ, vp, context.level()); + render(renderType); } } @@ -117,18 +85,10 @@ public class InstancingEngine

implements Engine { return; } - var camX = context.camX() - originCoordinate.getX(); - var camY = context.camY() - originCoordinate.getY(); - var camZ = context.camZ() - originCoordinate.getZ(); - - // don't want to mutate viewProjection - var vp = context.viewProjection().copy(); - vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ); - - render(type, camX, camY, camZ, vp, context.level()); + render(type); } - protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { + protected void render(RenderType type) { vertexCount = 0; instanceCount = 0; @@ -138,16 +98,16 @@ public class InstancingEngine

implements Engine { return; } - render(type, multimap, camX, camY, camZ, viewProjection, level); + render(type, multimap); } - protected void render(RenderType type, ListMultimap multimap, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { + protected void render(RenderType type, ListMultimap multimap) { type.setupRenderState(); Textures.bindActiveTextures(); CoreShaderInfo coreShaderInfo = CoreShaderInfo.get(); StateSnapshot state = GameStateRegistry.takeSnapshot(); - for (var entry : Multimaps.asMap(multimap).entrySet()) { + for (var entry : multimap.asMap().entrySet()) { var shader = entry.getKey(); var drawCalls = entry.getValue(); @@ -157,7 +117,7 @@ public class InstancingEngine

implements Engine { continue; } - setup(shader, coreShaderInfo, camX, camY, camZ, viewProjection, level, state); + setup(shader, coreShaderInfo, state); for (var drawCall : drawCalls) { drawCall.render(); @@ -168,21 +128,18 @@ public class InstancingEngine

implements Engine { type.clearRenderState(); } - protected P setup(ShaderState desc, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level, StateSnapshot ctx) { + protected void setup(ShaderState desc, CoreShaderInfo coreShaderInfo, StateSnapshot ctx) { VertexType vertexType = desc.vertex(); FileResolution instanceShader = desc.instance() .getInstanceShader(); Material material = desc.material(); - P program = context.getProgram(new ProgramCompiler.Context(vertexType, instanceShader, - material.vertexShader(), material.fragmentShader(), coreShaderInfo.getAdjustedAlphaDiscard(), - coreShaderInfo.fogType(), ctx)); + var program = ProgramCompiler.INSTANCE.getProgram(new ProgramCompiler.Context(vertexType, material, + instanceShader, context, coreShaderInfo.getAdjustedAlphaDiscard(), coreShaderInfo.fogType(), ctx)); program.bind(); - program.uploadUniforms(camX, camY, camZ, viewProjection, level); - - return program; + UniformBuffer.getInstance().sync(); } public void clearAll() { @@ -250,131 +207,4 @@ public class InstancingEngine

implements Engine { info.add("Vertices: " + vertexCount); info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ()); } - - public void renderCrumbling(LevelRenderer levelRenderer, ClientLevel level, PoseStack stack, Camera camera, Matrix4f projectionMatrix) { - var dataByStage = getDataByStage(levelRenderer, level); - if (dataByStage.isEmpty()) { - return; - } - - var map = modelsToParts(dataByStage); - var stateSnapshot = GameStateRegistry.takeSnapshot(); - - Vec3 cameraPosition = camera.getPosition(); - var camX = cameraPosition.x - originCoordinate.getX(); - var camY = cameraPosition.y - originCoordinate.getY(); - var camZ = cameraPosition.z - originCoordinate.getZ(); - - // don't want to mutate viewProjection - var vp = projectionMatrix.copy(); - vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ); - - GlBuffer instanceBuffer = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER); - - GlVertexArray crumblingVAO = new GlVertexArray(); - - crumblingVAO.bind(); - - // crumblingVAO.bindAttributes(); - - for (var entry : map.entrySet()) { - var model = entry.getKey(); - var parts = entry.getValue(); - - if (parts.isEmpty()) { - continue; - } - - StructType structType = parts.get(0).type; - - for (var meshEntry : model.get() - .entrySet()) { - Material material = meshEntry.getKey(); - Mesh mesh = meshEntry.getValue(); - - MeshPool.BufferedMesh bufferedMesh = MeshPool.getInstance() - .get(mesh); - - if (bufferedMesh == null || !bufferedMesh.isGpuResident()) { - continue; - } - - material.renderType().setupRenderState(); - - CoreShaderInfo coreShaderInfo = CoreShaderInfo.get(); - - - CrumblingProgram program = Contexts.CRUMBLING.getProgram(new ProgramCompiler.Context(Formats.POS_TEX_NORMAL, - structType.getInstanceShader(), material.vertexShader(), material.fragmentShader(), - coreShaderInfo.getAdjustedAlphaDiscard(), coreShaderInfo.fogType(), - GameStateRegistry.takeSnapshot())); - - program.bind(); - program.uploadUniforms(camX, camY, camZ, vp, level); - - // bufferedMesh.drawInstances(); - } - } - } - - @NotNull - private Map> modelsToParts(Int2ObjectMap>> dataByStage) { - var map = new HashMap>(); - - for (var entry : dataByStage.int2ObjectEntrySet()) { - RenderType currentLayer = ModelBakery.DESTROY_TYPES.get(entry.getIntKey()); - - // something about when we call this means that the textures are not ready for use on the first frame they should appear - if (currentLayer == null) { - continue; - } - - for (var blockEntityInstance : entry.getValue()) { - - for (var part : blockEntityInstance.getCrumblingParts()) { - if (part.getOwner() instanceof GPUInstancer instancer) { - - // queue the instances for copying to the crumbling instance buffer - map.computeIfAbsent(instancer.parent.getModel(), k -> new ArrayList<>()).add(part); - } - } - } - } - return map; - } - - @Nonnull - private Int2ObjectMap>> getDataByStage(LevelRenderer levelRenderer, ClientLevel level) { - var destructionProgress = ((LevelRendererAccessor) levelRenderer).flywheel$getDestructionProgress(); - if (destructionProgress.isEmpty()) { - return Int2ObjectMaps.emptyMap(); - } - - if (!(InstancedRenderDispatcher.getInstanceWorld(level) - .getBlockEntities() instanceof BlockEntityInstanceManager beim)) { - return Int2ObjectMaps.emptyMap(); - } - - var dataByStage = new Int2ObjectArrayMap>>(); - - for (var entry : destructionProgress.long2ObjectEntrySet()) { - SortedSet progresses = entry.getValue(); - - if (progresses == null || progresses.isEmpty()) { - continue; - } - - int progress = progresses.last() - .getProgress(); - - var data = dataByStage.computeIfAbsent(progress, $ -> new ArrayList<>()); - - long pos = entry.getLongKey(); - - beim.getCrumblingInstances(pos, data); - } - - return dataByStage; - } - } diff --git a/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java b/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java index e64837738..29a9399ad 100644 --- a/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java +++ b/src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java @@ -6,22 +6,18 @@ import org.jetbrains.annotations.NotNull; import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.core.material.MaterialShaders; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.model.ModelSupplier; import com.jozufozu.flywheel.util.Lazy; import com.jozufozu.flywheel.util.NonNullSupplier; -import net.minecraft.client.renderer.RenderType; - public class BasicModelSupplier implements ModelSupplier { - private static final Material DEFAULT_MATERIAL = new Material(RenderType.solid(), MaterialShaders.DEFAULT_VERTEX, MaterialShaders.DEFAULT_FRAGMENT); private Material material; private final Lazy supplier; public BasicModelSupplier(NonNullSupplier supplier) { - this(supplier, DEFAULT_MATERIAL); + this(supplier, Materials.DEFAULT); } public BasicModelSupplier(NonNullSupplier supplier, Material material) { diff --git a/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java b/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java new file mode 100644 index 000000000..e227f4eae --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/ComponentRegistry.java @@ -0,0 +1,60 @@ +package com.jozufozu.flywheel.core; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.uniform.UniformProvider; +import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.compile.ContextShader; +import com.jozufozu.flywheel.core.vertex.BlockVertex; + +import net.minecraft.resources.ResourceLocation; + +public class ComponentRegistry { + + private static final Set uniformProviderFiles = new HashSet<>(); + private static final List uniformProviders = new ArrayList<>(); + + // TODO: fill out the rest of the registry + + public static Material register(Material material) { + return material; + } + + public static > T register(T type) { + + return type; + } + + public static T register(T vertexType) { + return vertexType; + } + + public static ContextShader register(ContextShader 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; + } + + public static Collection getAllUniformProviders() { + return Collections.unmodifiableCollection(uniformProviders); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/ComponentType.java b/src/main/java/com/jozufozu/flywheel/core/ComponentType.java new file mode 100644 index 000000000..0b9f922df --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/ComponentType.java @@ -0,0 +1,9 @@ +package com.jozufozu.flywheel.core; + +public enum ComponentType { + MATERIAL, + INSTANCE, + LAYOUT, + CONTEXT, + UNIFORM_PROVIDER +} diff --git a/src/main/java/com/jozufozu/flywheel/core/Components.java b/src/main/java/com/jozufozu/flywheel/core/Components.java new file mode 100644 index 000000000..2f536ccf0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/Components.java @@ -0,0 +1,113 @@ +package com.jozufozu.flywheel.core; + +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; +import com.jozufozu.flywheel.core.source.error.ErrorReporter; +import com.jozufozu.flywheel.core.structs.StructTypes; +import com.jozufozu.flywheel.core.uniform.FogProvider; +import com.jozufozu.flywheel.core.uniform.ViewProvider; +import com.jozufozu.flywheel.core.vertex.Formats; +import com.jozufozu.flywheel.util.ResourceUtil; + +import net.minecraft.resources.ResourceLocation; + +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 void init() { + Files.init(); + Formats.init(); + StructTypes.init(); + Materials.init(); + } + + public static class Files { + + public static final FileResolution VIEW_UNIFORMS = uniform(Flywheel.rl("uniform/view.glsl")); + public static final FileResolution FOG_UNIFORMS = uniform(Flywheel.rl("uniform/fog.glsl")); + public static final FileResolution BLOCK_LAYOUT = layoutVertex(ResourceUtil.subPath(Names.BLOCK, ".vert")); + public static final FileResolution POS_TEX_NORMAL_LAYOUT = layoutVertex(ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert")); + 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 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) { + return FileResolution.get(location); + } + + public static FileResolution layoutVertex(ResourceLocation location) { + return FileResolution.get(location) + .validateWith(Checks.LAYOUT_VERTEX); + } + + public static FileResolution instanceVertex(ResourceLocation location) { + return FileResolution.get(location) + .validateWith(Checks.INSTANCE_VERTEX); + } + + public static FileResolution materialVertex(ResourceLocation location) { + return FileResolution.get(location) + .validateWith(Checks.MATERIAL_VERTEX); + } + + public static FileResolution materialFragment(ResourceLocation location) { + return FileResolution.get(location) + .validateWith(Checks.MATERIAL_FRAGMENT); + } + + public static FileResolution contextVertex(ResourceLocation location) { + return FileResolution.get(location) + .validateWith(Checks.CONTEXT_VERTEX); + } + + public static FileResolution contextFragment(ResourceLocation location) { + return FileResolution.get(location) + .validateWith(Checks.CONTEXT_FRAGMENT); + } + + public static void init() { + // noop, just in case + } + } + + public static class Checks { + + public static final BiConsumer LAYOUT_VERTEX = SourceChecks.checkFunctionArity("flw_layoutVertex", 0); + public static final BiConsumer INSTANCE_VERTEX = SourceChecks.checkFunctionArity("flw_instanceVertex", 0); + public static final BiConsumer MATERIAL_VERTEX = SourceChecks.checkFunctionArity("flw_materialVertex", 0); + public static final BiConsumer MATERIAL_FRAGMENT = SourceChecks.checkFunctionArity("flw_materialFragment", 0); + public static final BiConsumer CONTEXT_VERTEX = SourceChecks.checkFunctionArity("flw_contextVertex", 0); + public static final BiConsumer CONTEXT_FRAGMENT = SourceChecks.checkFunctionArity("flw_contextFragment", 0); + } + + public static class Names { + public static final ResourceLocation BLOCK = Flywheel.rl("layout/block"); + public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal"); + + public static final ResourceLocation TRANSFORMED = Flywheel.rl("instance/transformed"); + public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented"); + + public static final ResourceLocation DEFAULT = Flywheel.rl("material/default"); + 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/Contexts.java b/src/main/java/com/jozufozu/flywheel/core/Contexts.java deleted file mode 100644 index c87d58e9a..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/Contexts.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.jozufozu.flywheel.core; - -import java.util.function.BiConsumer; - -import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.backend.gl.GLSLVersion; -import com.jozufozu.flywheel.core.compile.ProgramCompiler; -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; -import com.jozufozu.flywheel.core.source.error.ErrorReporter; -import com.jozufozu.flywheel.util.ResourceUtil; - -import net.minecraft.resources.ResourceLocation; - -public class Contexts { - public static final BiConsumer VERTEX_CHECK = SourceChecks.checkFunctionArity("flw_contextVertex", 0); - public static final BiConsumer FRAGMENT_CHECK = SourceChecks.checkFunctionArity("flw_contextFragment", 0); - - public static final ProgramCompiler WORLD; - public static final ProgramCompiler CRUMBLING; - - static { - var worldVertex = createVertex(ResourceUtil.subPath(Names.WORLD, ".vert")); - var worldFragment = createFragment(ResourceUtil.subPath(Names.WORLD, ".frag")); - var crumblingVertex = createVertex(ResourceUtil.subPath(Names.CRUMBLING, ".vert")); - var crumblingFragment = createFragment(ResourceUtil.subPath(Names.CRUMBLING, ".frag")); - - WORLD = ProgramCompiler.create(WorldProgram::new, worldVertex, worldFragment, GLSLVersion.V330); - CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, crumblingVertex, crumblingFragment, GLSLVersion.V330); - } - - public static FileResolution createVertex(ResourceLocation location) { - return FileResolution.get(location).validateWith(VERTEX_CHECK); - } - - public static FileResolution createFragment(ResourceLocation location) { - return FileResolution.get(location).validateWith(FRAGMENT_CHECK); - } - - public static void init() { - } - - public static class Names { - 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/Materials.java b/src/main/java/com/jozufozu/flywheel/core/Materials.java new file mode 100644 index 000000000..da53ea2e7 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/Materials.java @@ -0,0 +1,19 @@ +package com.jozufozu.flywheel.core; + +import com.jozufozu.flywheel.api.material.Material; + +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Sheets; +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 Material(RenderType.solid(), Components.Files.DEFAULT_VERTEX, Components.Files.DEFAULT_FRAGMENT)); + public static final Material CHEST = ComponentRegistry.register(new Material(Sheets.chestSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); + public static final Material SHULKER = ComponentRegistry.register(new Material(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); + public static final Material MINECART = ComponentRegistry.register(new Material(RenderType.entitySolid(MINECART_LOCATION), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); + + public static void init() { + // noop + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/ContextShader.java b/src/main/java/com/jozufozu/flywheel/core/compile/ContextShader.java new file mode 100644 index 000000000..66d8c850f --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/compile/ContextShader.java @@ -0,0 +1,16 @@ +package com.jozufozu.flywheel.core.compile; + +import com.jozufozu.flywheel.backend.gl.shader.GlProgram; +import com.jozufozu.flywheel.core.source.FileResolution; +import com.jozufozu.flywheel.core.source.SourceFile; + +public record ContextShader(GlProgram.Factory factory, FileResolution vertexShader, FileResolution fragmentShader) { + + public SourceFile getVertexShader() { + return vertexShader.getFile(); + } + + public SourceFile getFragmentShader() { + return fragmentShader.getFile(); + } +} 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 8fd766456..ec7d3470c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java @@ -7,43 +7,38 @@ 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.FileIndex; -import com.jozufozu.flywheel.core.source.FileResolution; +import com.jozufozu.flywheel.core.source.CompilationContext; import com.jozufozu.flywheel.core.source.SourceFile; /** * Handles compilation and deletion of fragment shaders. */ public class FragmentCompiler extends Memoizer { - private final FileResolution contextShader; - private final GLSLVersion glslVersion; - public FragmentCompiler(FileResolution contextShader, GLSLVersion glslVersion) { - this.contextShader = contextShader; - this.glslVersion = glslVersion; + public FragmentCompiler() { } @Override protected GlShader _create(Context key) { StringBuilder finalSource = new StringBuilder(); - finalSource.append(CompileUtil.generateHeader(glslVersion, ShaderType.FRAGMENT)); + finalSource.append(CompileUtil.generateHeader(GLSLVersion.V420, ShaderType.FRAGMENT)); - ShaderConstants shaderConstants = key.getShaderConstants(); + var shaderConstants = key.getShaderConstants(); shaderConstants.writeInto(finalSource); finalSource.append('\n'); - FileIndex index = new FileIndex(); + var ctx = new CompilationContext(); // MATERIAL SourceFile materialShader = key.materialShader; - materialShader.generateFinalSource(index, finalSource); + finalSource.append(materialShader.generateFinalSource(ctx)); // CONTEXT - SourceFile contextShaderSource = contextShader.getFile(); - contextShaderSource.generateFinalSource(index, finalSource); + SourceFile contextShaderSource = key.contextShader; + finalSource.append(contextShaderSource.generateFinalSource(ctx)); // MAIN @@ -52,7 +47,7 @@ public class FragmentCompiler extends Memoizer P build(GlProgram.Factory

factory) { + public GlProgram build(GlProgram.Factory factory) { return factory.create(name, program); } } 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 60d53a657..b00b2b3a7 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,8 @@ package com.jozufozu.flywheel.core.compile; import java.util.ArrayList; import java.util.List; +import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.backend.gl.GLSLVersion; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.core.CoreShaderInfoMap; import com.jozufozu.flywheel.core.shader.StateSnapshot; @@ -22,41 +22,28 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent; * A ProgramCompiler is also responsible for deleting programs and shaders on renderer reload. *

*/ -public class ProgramCompiler

extends Memoizer { +public class ProgramCompiler extends Memoizer { - private static final List> ALL_COMPILERS = new ArrayList<>(); + public static final ProgramCompiler INSTANCE = new ProgramCompiler(); + private static final List ALL_COMPILERS = new ArrayList<>(); - private final GlProgram.Factory

factory; private final VertexCompiler vertexCompiler; private final FragmentCompiler fragmentCompiler; - public ProgramCompiler(GlProgram.Factory

factory, VertexCompiler vertexCompiler, FragmentCompiler fragmentCompiler) { - this.factory = factory; - this.vertexCompiler = vertexCompiler; - this.fragmentCompiler = fragmentCompiler; + public ProgramCompiler() { + this.vertexCompiler = new VertexCompiler(); + this.fragmentCompiler = new FragmentCompiler(); ALL_COMPILERS.add(this); } - /** - * Creates a program compiler using provided templates and headers. - * @param factory A factory to add meaning to compiled programs. - * @param vertexContextShader The context shader to use when compiling vertex shaders. - * @param fragmentContextShader The context shader to use when compiling fragment shaders. - * @param

The type of program to compile. - * @return A program compiler. - */ - public static

ProgramCompiler

create(GlProgram.Factory

factory, FileResolution vertexContextShader, FileResolution fragmentContextShader, GLSLVersion glslVersion) { - return new ProgramCompiler<>(factory, new VertexCompiler(vertexContextShader, glslVersion), new FragmentCompiler(fragmentContextShader, glslVersion)); - } - /** * Get or compile a spec to the given vertex type, accounting for all game state conditions specified by the spec. * * @param ctx The context of compilation. * @return A compiled GlProgram. */ - public P getProgram(Context ctx) { + public GlProgram getProgram(ProgramCompiler.Context ctx) { return super.get(ctx); } @@ -68,17 +55,28 @@ public class ProgramCompiler

extends Memoizer extends Memoizer { - private final FileResolution contextShader; - private final GLSLVersion glslVersion; - public VertexCompiler(FileResolution contextShader, GLSLVersion glslVersion) { - this.contextShader = contextShader; - this.glslVersion = glslVersion; + public VertexCompiler() { } @Override protected GlShader _create(Context key) { StringBuilder finalSource = new StringBuilder(); - finalSource.append(CompileUtil.generateHeader(glslVersion, ShaderType.VERTEX)); + finalSource.append(CompileUtil.generateHeader(GLSLVersion.V420, ShaderType.VERTEX)); var shaderConstants = key.ctx.getShaderConstants(); shaderConstants.writeInto(finalSource); finalSource.append('\n'); - var index = new FileIndex(); + var index = new CompilationContext(); // LAYOUT var layoutShader = key.vertexType.getLayoutShader().getFile(); - layoutShader.generateFinalSource(index, finalSource); + finalSource.append(layoutShader.generateFinalSource(index)); // INSTANCE @@ -62,17 +55,17 @@ public class VertexCompiler extends Memoizer { int newLocation = location + attributeBaseIndex; replacements.add(Pair.of(field.location, Integer.toString(newLocation))); } - instanceShader.generateFinalSource(index, finalSource, replacements); + finalSource.append(instanceShader.generateFinalSource(index, replacements)); // MATERIAL var materialShader = key.materialShader; - materialShader.generateFinalSource(index, finalSource); + finalSource.append(materialShader.generateFinalSource(index)); // CONTEXT - var contextShaderSource = contextShader.getFile(); - contextShaderSource.generateFinalSource(index, finalSource); + var contextShaderSource = key.contextShader; + finalSource.append(contextShaderSource.generateFinalSource(index)); // MAIN @@ -104,8 +97,9 @@ public class VertexCompiler extends Memoizer { * @param vertexType The vertex type to use. * @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, StateSnapshot ctx) { + public record Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, SourceFile contextShader, StateSnapshot ctx) { } } 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 2624cf2f1..835e7ce7d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -9,7 +9,7 @@ import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine; import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine; -import com.jozufozu.flywheel.core.Contexts; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.mixin.LevelRendererAccessor; @@ -153,15 +153,15 @@ public class CrumblingRenderer { } } - private static class CrumblingEngine extends InstancingEngine { + private static class CrumblingEngine extends InstancingEngine { private RenderType currentLayer; public CrumblingEngine() { - super(Contexts.CRUMBLING); + super(Components.CRUMBLING); } @Override - protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { + protected void render(RenderType type) { if (!type.affectsCrumbling()) { return; } @@ -172,7 +172,7 @@ public class CrumblingRenderer { return; } - render(currentLayer, multimap, camX, camY, camZ, viewProjection, level); + render(currentLayer, multimap); } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java b/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java deleted file mode 100644 index 78ca6a488..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.jozufozu.flywheel.core.material; - -import java.util.function.BiConsumer; - -import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.source.SourceChecks; -import com.jozufozu.flywheel.core.source.SourceFile; -import com.jozufozu.flywheel.core.source.error.ErrorReporter; -import com.jozufozu.flywheel.util.ResourceUtil; - -import net.minecraft.resources.ResourceLocation; - -public class MaterialShaders { - public static final BiConsumer VERTEX_CHECK = SourceChecks.checkFunctionArity("flw_materialVertex", 0); - public static final BiConsumer FRAGMENT_CHECK = SourceChecks.checkFunctionArity("flw_materialFragment", 0); - - public static final FileResolution DEFAULT_VERTEX = createVertex(ResourceUtil.subPath(Names.DEFAULT, ".vert")); - public static final FileResolution DEFAULT_FRAGMENT = createFragment(ResourceUtil.subPath(Names.DEFAULT, ".frag")); - public static final FileResolution SHADED_VERTEX = createVertex(ResourceUtil.subPath(Names.SHADED, ".vert")); - - public static FileResolution createVertex(ResourceLocation location) { - return FileResolution.get(location).validateWith(VERTEX_CHECK); - } - - public static FileResolution createFragment(ResourceLocation location) { - return FileResolution.get(location).validateWith(FRAGMENT_CHECK); - } - - public static void init() { - } - - public static class Names { - public static final ResourceLocation DEFAULT = Flywheel.rl("material/default"); - public static final ResourceLocation SHADED = Flywheel.rl("material/shaded"); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/WorldFog.java b/src/main/java/com/jozufozu/flywheel/core/shader/WorldFog.java deleted file mode 100644 index e466a7603..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/shader/WorldFog.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.jozufozu.flywheel.core.shader; - -import org.lwjgl.opengl.GL20; - -import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.mojang.blaze3d.systems.RenderSystem; - -public class WorldFog { - - private final int uFogRange; - private final int uFogColor; - private final int uFogShape; - - public WorldFog(GlProgram program) { - this.uFogRange = program.getUniformLocation("uFogRange"); - this.uFogColor = program.getUniformLocation("uFogColor"); - this.uFogShape = program.getUniformLocation("uFogShape"); - } - - public void uploadUniforms() { - GL20.glUniform2f(uFogRange, RenderSystem.getShaderFogStart(), RenderSystem.getShaderFogEnd()); - GL20.glUniform4fv(uFogColor, RenderSystem.getShaderFogColor()); - GL20.glUniform1i(uFogShape, RenderSystem.getShaderFogShape().getIndex()); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java b/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java index 0fe6eb734..0800d204f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java @@ -1,35 +1,18 @@ package com.jozufozu.flywheel.core.shader; -import static org.lwjgl.opengl.GL20.glUniform1f; -import static org.lwjgl.opengl.GL20.glUniform1i; -import static org.lwjgl.opengl.GL20.glUniform2f; -import static org.lwjgl.opengl.GL20.glUniform3f; - import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.jozufozu.flywheel.util.AnimationTickHolder; -import com.mojang.blaze3d.platform.Window; -import com.mojang.math.Matrix4f; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.resources.ResourceLocation; public class WorldProgram extends GlProgram { - protected final int uTime = getUniformLocation("uTime"); - protected final int uViewProjection = getUniformLocation("uViewProjection"); - protected final int uCameraPos = getUniformLocation("uCameraPos"); - protected final int uWindowSize = getUniformLocation("uWindowSize"); - protected final int uConstantAmbientLight = getUniformLocation("uConstantAmbientLight"); - private final WorldFog fog; + // TODO: sampler registry? protected int uBlockAtlas; protected int uLightMap; public WorldProgram(ResourceLocation name, int handle) { super(name, handle); - fog = new WorldFog(this); - bind(); registerSamplers(); unbind(); @@ -39,48 +22,4 @@ public class WorldProgram extends GlProgram { uBlockAtlas = setSamplerBinding("uBlockAtlas", 0); uLightMap = setSamplerBinding("uLightMap", 2); } - - // TODO: create uniform registry - public void uploadUniforms(double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { - fog.uploadUniforms(); - uploadTime(AnimationTickHolder.getRenderTime()); - uploadViewProjection(viewProjection); - uploadCameraPos(camX, camY, camZ); - uploadWindowSize(); - uploadConstantAmbientLight(level); - } - - protected void uploadTime(float renderTime) { - if (uTime < 0) return; - - glUniform1f(uTime, renderTime); - } - - protected void uploadViewProjection(Matrix4f viewProjection) { - if (uViewProjection < 0) return; - - uploadMatrixUniform(uViewProjection, viewProjection); - } - - protected void uploadCameraPos(double camX, double camY, double camZ) { - if (uCameraPos < 0) return; - - glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ); - } - - protected void uploadWindowSize() { - if (uWindowSize < 0) return; - - Window window = Minecraft.getInstance().getWindow(); - - int height = window.getScreenHeight(); - int width = window.getScreenWidth(); - glUniform2f(uWindowSize, width, height); - } - - protected void uploadConstantAmbientLight(ClientLevel level) { - if (uConstantAmbientLight < 0) return; - - glUniform1i(uConstantAmbientLight, level.effects().constantAmbientLight() ? 1 : 0); - } } diff --git a/src/main/java/com/jozufozu/flywheel/core/source/FileIndex.java b/src/main/java/com/jozufozu/flywheel/core/source/CompilationContext.java similarity index 94% rename from src/main/java/com/jozufozu/flywheel/core/source/FileIndex.java rename to src/main/java/com/jozufozu/flywheel/core/source/CompilationContext.java index b2c5a9b6e..2217b5708 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/FileIndex.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/CompilationContext.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable; import com.jozufozu.flywheel.core.source.error.ErrorBuilder; import com.jozufozu.flywheel.core.source.span.Span; -public class FileIndex { +public class CompilationContext { public final List files = new ArrayList<>(); /** @@ -27,7 +27,7 @@ public class FileIndex { return size; } - public boolean exists(SourceFile sourceFile) { + public boolean contains(SourceFile sourceFile) { return files.contains(sourceFile); } diff --git a/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java b/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java index 8b4503391..5533a6b01 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java @@ -24,6 +24,7 @@ import net.minecraft.resources.ResourceLocation; public class FileResolution { private static final Map ALL = new HashMap<>(); + private static final Map WEAK = new HashMap<>(); private static boolean tooLate = false; /** @@ -56,34 +57,65 @@ public class FileResolution { } } + /** + * Weak resolutions don't persist through resource reloads.

+ * This should be used inside parsing code. + * + * @param file The location of the file to resolve. + * @return A weak resolution for the given file. + */ + public static FileResolution weak(ResourceLocation file) { + FileResolution fileResolution = ALL.get(file); + + if (fileResolution != null) { + return fileResolution; + } + // never too late for weak resolutions. + return WEAK.computeIfAbsent(file, FileResolution::new); + } + /** * Try and resolve all referenced source files, printing errors if any aren't found. */ public static void run(ErrorReporter errorReporter, SourceFinder sources) { for (FileResolution resolution : ALL.values()) { - resolution.resolveAndCheck(errorReporter, sources); + resolution.resolve(errorReporter, sources); } + for (FileResolution resolution : WEAK.values()) { + resolution.resolve(errorReporter, sources); + } + + WEAK.clear(); + tooLate = true; } - private void resolveAndCheck(ErrorReporter errorReporter, SourceFinder sources) { + public static void checkAll(ErrorReporter errorReporter) { + for (FileResolution resolution : ALL.values()) { + resolution.runChecks(errorReporter); + } + } + + private void resolve(ErrorReporter errorReporter, SourceFinder sources) { file = sources.findSource(fileLoc); if (file == null) { - ErrorBuilder builder = errorReporter.error(String.format("could not find source for file %s", fileLoc)); - for (Span location : neededAt) { - builder.pointAtFile(location.getSourceFile()) - .pointAt(location, 1); - } - } else { - runChecks(errorReporter); + reportMissing(errorReporter); } // Let the GC do its thing neededAt.clear(); } + private void reportMissing(ErrorReporter errorReporter) { + ErrorBuilder builder = errorReporter.error(String.format("could not find source for file %s", fileLoc)); + for (Span location : neededAt) { + builder.pointAtFile(location.getSourceFile()) + .pointAt(location, 1); + } + } + private void runChecks(ErrorReporter errorReporter) { for (var check : checks) { check.accept(errorReporter, file); 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 502d19bb2..3b156b34f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java @@ -6,6 +6,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.google.common.collect.Lists; @@ -29,14 +30,8 @@ public class ShaderSources implements SourceFinder { public final Index index; public ShaderSources(ErrorReporter errorReporter, ResourceManager manager) { - Collection allShaders = manager.listResources(SHADER_DIR, s -> { - for (String ext : EXTENSIONS) { - if (s.endsWith(ext)) return true; - } - return false; - }); - for (ResourceLocation location : allShaders) { + for (ResourceLocation location : getValidShaderFiles(manager)) { try (Resource resource = manager.getResource(location)) { String source = StringUtil.readToString(resource.getInputStream()); @@ -51,9 +46,25 @@ public class ShaderSources implements SourceFinder { index = new Index(shaderSources); } + public void postResolve() { + for (SourceFile file : shaderSources.values()) { + file.postResolve(); + } + } + @Override @Nullable public SourceFile findSource(ResourceLocation name) { return shaderSources.get(name); } + + @NotNull + private static Collection getValidShaderFiles(ResourceManager manager) { + return manager.listResources(SHADER_DIR, s -> { + for (String ext : EXTENSIONS) { + if (s.endsWith(ext)) return true; + } + return false; + }); + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java index 72b05f946..43f95c6a3 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java @@ -57,6 +57,9 @@ public class SourceFile { public final ImmutableMap fields; private final List elisions; + // POST-RESOLUTION + private List flattenedImports; + public SourceFile(ErrorReporter errorReporter, ShaderSources parent, ResourceLocation name, String source) { this.parent = parent; this.name = name; @@ -72,6 +75,37 @@ public class SourceFile { this.fields = parseFields(); } + public void postResolve() { + this.flattenImports(); + } + + private void flattenImports() { + // somebody #used us and got resolved before we did + if (this.flattenedImports != null) { + return; + } + + if (this.imports.isEmpty()) { + this.flattenedImports = Collections.emptyList(); + return; + } + + List flat = new ArrayList<>(this.imports.size()); + + for (Import include : this.imports) { + SourceFile file = include.resolution.getFile(); + + file.flattenImports(); + + flat.addAll(file.flattenedImports); + flat.add(include); + } + + this.flattenedImports = flat.stream() + .distinct() + .toList(); + } + public Span getLineSpan(int line) { int begin = lines.getLineStart(line); int end = begin + lines.getLine(line).length(); @@ -95,16 +129,23 @@ public class SourceFile { * @param name The name of the struct to find. * @return null if no definition matches the name. */ - public Optional findStruct(CharSequence name) { - ShaderStruct struct = structs.get(name.toString()); + public Optional findStruct(String name) { + ShaderStruct struct = structs.get(name); if (struct != null) return Optional.of(struct); - for (Import include : imports) { - Optional externalStruct = include.getOptional() - .flatMap(file -> file.findStruct(name)); + for (Import include : flattenedImports) { + var file = include.getFile(); - if (externalStruct.isPresent()) return externalStruct; + if (file == null) { + continue; + } + + var external = file.structs.get(name); + + if (external != null) { + return Optional.of(external); + } } return Optional.empty(); @@ -116,16 +157,23 @@ public class SourceFile { * @param name The name of the function to find. * @return Optional#empty() if no definition matches the name. */ - public Optional findFunction(CharSequence name) { - ShaderFunction local = functions.get(name.toString()); + public Optional findFunction(String name) { + ShaderFunction local = functions.get(name); if (local != null) return Optional.of(local); for (Import include : imports) { - Optional external = include.getOptional() - .flatMap(file -> file.findFunction(name)); + var file = include.getFile(); - if (external.isPresent()) return external; + if (file == null) { + continue; + } + + var external = file.functions.get(name); + + if (external != null) { + return Optional.of(external); + } } return Optional.empty(); @@ -135,40 +183,46 @@ public class SourceFile { return "#use " + '"' + name + '"'; } - public void generateFinalSource(FileIndex env, StringBuilder source) { - generateFinalSource(env, source, Collections.emptyList()); + public String generateFinalSource(CompilationContext env) { + return generateFinalSource(env, Collections.emptyList()); } - public void generateFinalSource(FileIndex env, StringBuilder source, List> replacements) { - for (Import include : imports) { + public String generateFinalSource(CompilationContext env, List> replacements) { + var out = new StringBuilder(); + for (Import include : flattenedImports) { SourceFile file = include.getFile(); - if (file != null && !env.exists(file)) { - file.generateFinalSource(env, source, replacements); + if (file == null || env.contains(file)) { + continue; } + + out.append(file.generateLineHeader(env)) + .append(file.replaceAndElide(replacements)); } - source.append("#line ") - .append(0) - .append(' ') - .append(env.getFileID(this)) - .append(" // ") - .append(name) - .append('\n'); + out.append(this.generateLineHeader(env)) + .append(this.replaceAndElide(replacements)); - var replacementsAndElisions = new ArrayList<>(replacements); - for (Span elision : elisions) { - replacementsAndElisions.add(Pair.of(elision, "")); - } + return out.toString(); + } - source.append(this.replace(replacementsAndElisions)); - source.append('\n'); + private String generateLineHeader(CompilationContext env) { + return "#line " + 0 + ' ' + env.getFileID(this) + " // " + name + '\n'; } public String printSource() { return "Source for shader '" + name + "':\n" + lines.printLinesWithNumbers(); } + private CharSequence replaceAndElide(List> replacements) { + var replacementsAndElisions = new ArrayList<>(replacements); + for (var include : imports) { + replacementsAndElisions.add(Pair.of(include.self, "")); + } + + return this.replace(replacementsAndElisions); + } + private CharSequence replace(List> replacements) { StringBuilder out = new StringBuilder(); @@ -276,7 +330,7 @@ public class SourceFile { Matcher uses = Import.PATTERN.matcher(source); Set importedFiles = new HashSet<>(); - List imports = new ArrayList<>(); + var imports = ImmutableList.builder(); while (uses.find()) { Span use = Span.fromMatcher(this, uses); @@ -284,17 +338,14 @@ public class SourceFile { String fileName = file.get(); if (importedFiles.add(fileName)) { - // FIXME: creating imports after the first resource reload crashes the game var checked = Import.create(errorReporter, use, file); if (checked != null) { imports.add(checked); } } - - this.elisions.add(use); // we have to trim that later } - return ImmutableList.copyOf(imports); + return imports.build(); } /** diff --git a/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorBuilder.java b/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorBuilder.java index ebd2d22bd..93ab86e84 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorBuilder.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorBuilder.java @@ -7,7 +7,7 @@ import java.util.regex.Pattern; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.core.source.FileIndex; +import com.jozufozu.flywheel.core.source.CompilationContext; import com.jozufozu.flywheel.core.source.SourceFile; import com.jozufozu.flywheel.core.source.SourceLines; import com.jozufozu.flywheel.core.source.error.lines.ErrorLine; @@ -45,7 +45,7 @@ public class ErrorBuilder { } @Nullable - public static ErrorBuilder fromLogLine(FileIndex env, String s) { + public static ErrorBuilder fromLogLine(CompilationContext env, String s) { Matcher matcher = ERROR_LINE.matcher(s); if (matcher.find()) { diff --git a/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java b/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java index 860617dac..764bcc4ef 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java @@ -17,7 +17,7 @@ public class Import extends AbstractShaderElement { public static final Pattern PATTERN = Pattern.compile("^\\s*#\\s*use\\s+\"(.*)\"", Pattern.MULTILINE); - private final FileResolution resolution; + public final FileResolution resolution; protected Import(Span self, FileResolution resolution, Span file) { super(self); @@ -34,11 +34,7 @@ public class Import extends AbstractShaderElement { return null; } - return new Import(self, FileResolution.get(fileLocation), file); - } - - public FileResolution getResolution() { - return resolution; + return new Import(self, FileResolution.weak(fileLocation), file); } public Optional getOptional() { diff --git a/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java b/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java index 7491f0cf4..e295702b3 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java @@ -131,14 +131,14 @@ public abstract class Span implements CharSequence, Comparable { if (isErr()) { return Optional.empty(); } - return in.findStruct(this); + return in.findStruct(this.toString()); } public Optional findFunction() { if (isErr()) { return Optional.empty(); } - return in.findFunction(this); + return in.findFunction(this.toString()); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java b/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java deleted file mode 100644 index f86faaee2..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.jozufozu.flywheel.core.structs; - -import java.util.function.BiConsumer; - -import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.source.SourceChecks; -import com.jozufozu.flywheel.core.source.SourceFile; -import com.jozufozu.flywheel.core.source.error.ErrorReporter; -import com.jozufozu.flywheel.util.ResourceUtil; - -import net.minecraft.resources.ResourceLocation; - -public class InstanceShaders { - public static final BiConsumer CHECK = SourceChecks.checkFunctionArity("flw_instanceVertex", 0); - - public static final FileResolution TRANSFORMED = create(ResourceUtil.subPath(Names.TRANSFORMED, ".vert")); - public static final FileResolution ORIENTED = create(ResourceUtil.subPath(Names.ORIENTED, ".vert")); - - public static FileResolution create(ResourceLocation location) { - return FileResolution.get(location).validateWith(CHECK); - } - - public static void init() { - } - - public static class Names { - public static final ResourceLocation TRANSFORMED = Flywheel.rl("instance/transformed"); - public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented"); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java b/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java index a11cec5c9..96015bf27 100644 --- a/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java +++ b/src/main/java/com/jozufozu/flywheel/core/structs/StructTypes.java @@ -1,12 +1,17 @@ package com.jozufozu.flywheel.core.structs; import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.core.ComponentRegistry; import com.jozufozu.flywheel.core.structs.model.TransformedPart; import com.jozufozu.flywheel.core.structs.model.TransformedType; import com.jozufozu.flywheel.core.structs.oriented.OrientedPart; import com.jozufozu.flywheel.core.structs.oriented.OrientedType; public class StructTypes { - public static final StructType TRANSFORMED = new TransformedType(); - public static final StructType ORIENTED = new OrientedType(); + public static final StructType TRANSFORMED = ComponentRegistry.register(new TransformedType()); + public static final StructType ORIENTED = ComponentRegistry.register(new OrientedType()); + + public static void init() { + // noop + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java b/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java index bf1c3809a..10b5e3e07 100644 --- a/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java +++ b/src/main/java/com/jozufozu/flywheel/core/structs/model/TransformedType.java @@ -4,11 +4,11 @@ import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.struct.StructWriter; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.model.ModelTransformer; import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.structs.InstanceShaders; public class TransformedType implements StructType { @@ -34,7 +34,7 @@ public class TransformedType implements StructType { @Override public FileResolution getInstanceShader() { - return InstanceShaders.TRANSFORMED; + return Components.Files.TRANSFORMED; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java index 97b1a33fb..d709a0607 100644 --- a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java +++ b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java @@ -4,11 +4,11 @@ import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.struct.StructWriter; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.model.ModelTransformer; import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.structs.InstanceShaders; import com.mojang.math.Quaternion; public class OrientedType implements StructType { @@ -35,7 +35,7 @@ public class OrientedType implements StructType { @Override public FileResolution getInstanceShader() { - return InstanceShaders.ORIENTED; + return Components.Files.ORIENTED; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java b/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java new file mode 100644 index 000000000..80c875a2f --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/uniform/FogProvider.java @@ -0,0 +1,45 @@ +package com.jozufozu.flywheel.core.uniform; + +import java.nio.ByteBuffer; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.uniform.UniformProvider; +import com.jozufozu.flywheel.core.Components; +import com.jozufozu.flywheel.core.source.FileResolution; +import com.mojang.blaze3d.systems.RenderSystem; + +public class FogProvider extends UniformProvider { + + + + @Override + public int getSize() { + return 16 + 8 + 4; + } + + public void update() { + if (buffer == null) { + return; + } + + var color = RenderSystem.getShaderFogColor(); + + long ptr = MemoryUtil.memAddress(buffer); + + MemoryUtil.memPutFloat(ptr, color[0]); + MemoryUtil.memPutFloat(ptr + 4, color[1]); + MemoryUtil.memPutFloat(ptr + 8, color[2]); + MemoryUtil.memPutFloat(ptr + 12, color[3]); + MemoryUtil.memPutFloat(ptr + 16, RenderSystem.getShaderFogStart()); + MemoryUtil.memPutFloat(ptr + 20, RenderSystem.getShaderFogEnd()); + MemoryUtil.memPutInt(ptr + 24, RenderSystem.getShaderFogShape().getIndex()); + + notifier.signalChanged(); + } + + @Override + public FileResolution getUniformShader() { + return Components.Files.FOG_UNIFORMS; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java b/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java new file mode 100644 index 000000000..2d8f04c34 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/uniform/UniformBuffer.java @@ -0,0 +1,131 @@ +package com.jozufozu.flywheel.core.uniform; + +import java.nio.ByteBuffer; +import java.util.BitSet; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.atomic.AtomicLongArray; + +import org.lwjgl.opengl.GL32; +import org.lwjgl.system.MemoryUtil; + +import com.google.common.collect.ImmutableList; +import com.jozufozu.flywheel.api.uniform.UniformProvider; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; +import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; +import com.jozufozu.flywheel.core.ComponentRegistry; +import com.jozufozu.flywheel.util.RenderMath; +import com.mojang.blaze3d.platform.MemoryTracker; + +public class UniformBuffer { + + private static final int OFFSET_ALIGNMENT = GL32.glGetInteger(GL32.GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + private static final int MAX_SIZE = GL32.glGetInteger(GL32.GL_MAX_UNIFORM_BLOCK_SIZE); + private static final int MAX_BINDINGS = GL32.glGetInteger(GL32.GL_MAX_UNIFORM_BUFFER_BINDINGS); + private static final boolean PO2_ALIGNMENT = RenderMath.isPowerOf2(OFFSET_ALIGNMENT); + + private static UniformBuffer instance; + private final List allocatedProviders; + + public static UniformBuffer getInstance() { + if (instance == null) { + instance = new UniformBuffer(); + } + return instance; + } + + private final MappedGlBuffer buffer; + private final ByteBuffer data; + + private final BitSet changedBytes; + + private UniformBuffer() { + buffer = new MappedGlBuffer(GlBufferType.UNIFORM_BUFFER); + + Collection providers = ComponentRegistry.getAllUniformProviders(); + + var builder = ImmutableList.builder(); + int totalBytes = 0; + int index = 0; + for (UniformProvider provider : providers) { + int size = provider.getSize(); + + builder.add(new Allocated(provider, totalBytes, size, index)); + + totalBytes = align(totalBytes + size); + index++; + } + + allocatedProviders = builder.build(); + + data = MemoryTracker.create(totalBytes); + changedBytes = new BitSet(totalBytes); + + for (Allocated p : allocatedProviders) { + p.updatePtr(data); + } + } + + public void sync() { + if (changedBytes.isEmpty()) { + return; + } + + changedBytes.clear(); + + buffer.upload(data); + + int handle = buffer.handle(); + for (Allocated p : allocatedProviders) { + GL32.glBindBufferRange(GL32.GL_UNIFORM_BUFFER, p.index, handle, p.offset, p.size); + } + } + + // https://stackoverflow.com/questions/3407012/rounding-up-to-the-nearest-multiple-of-a-number + private static int align(int numToRound) { + if (PO2_ALIGNMENT) { + return (numToRound + OFFSET_ALIGNMENT - 1) & -OFFSET_ALIGNMENT; + } else { + return ((numToRound + OFFSET_ALIGNMENT - 1) / OFFSET_ALIGNMENT) * OFFSET_ALIGNMENT; + } + } + + private class Allocated implements UniformProvider.Notifier { + private final UniformProvider provider; + private final int offset; + private final int size; + private final int index; + + private Allocated(UniformProvider provider, int offset, int size, int index) { + this.provider = provider; + this.offset = offset; + this.size = size; + this.index = index; + } + + @Override + public void signalChanged() { + changedBytes.set(offset, offset + size); + } + + private void updatePtr(ByteBuffer bufferBase) { + provider.updatePtr(MemoryUtil.memSlice(bufferBase, offset, size), this); + } + + public UniformProvider provider() { + return provider; + } + + public int offset() { + return offset; + } + + public int size() { + return size; + } + + public int index() { + return index; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java new file mode 100644 index 000000000..ab50b5112 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java @@ -0,0 +1,69 @@ +package com.jozufozu.flywheel.core.uniform; + +import java.nio.ByteBuffer; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.uniform.UniformProvider; +import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.core.Components; +import com.jozufozu.flywheel.core.RenderContext; +import com.jozufozu.flywheel.core.source.FileResolution; +import com.jozufozu.flywheel.event.BeginFrameEvent; +import com.jozufozu.flywheel.util.MatrixWrite; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.Vec3i; +import net.minecraftforge.common.MinecraftForge; + +public class ViewProvider extends UniformProvider { + + public ViewProvider() { + MinecraftForge.EVENT_BUS.addListener(this::beginFrame); + } + + public void beginFrame(BeginFrameEvent event) { + update(RenderContext.CURRENT); + } + + @Override + public int getSize() { + return 4 * 16 + 16 + 4; + } + + public void update(RenderContext context) { + if (buffer == null) { + return; + } + + ClientLevel level = context.level(); + + int constantAmbientLight = level.effects() + .constantAmbientLight() ? 1 : 0; + + Vec3i originCoordinate = InstancedRenderDispatcher.getOriginCoordinate(level); + + var camX = (float) (context.camX() - originCoordinate.getX()); + var camY = (float) (context.camY() - originCoordinate.getY()); + var camZ = (float) (context.camZ() - originCoordinate.getZ()); + + // don't want to mutate viewProjection + var vp = context.viewProjection().copy(); + vp.multiplyWithTranslation(-camX, -camY, -camZ); + + long ptr = MemoryUtil.memAddress(buffer); + + MatrixWrite.writeUnsafe(vp, ptr); + MemoryUtil.memPutFloat(ptr + 64, camX); + MemoryUtil.memPutFloat(ptr + 68, camY); + MemoryUtil.memPutFloat(ptr + 72, camZ); + MemoryUtil.memPutInt(ptr + 76, constantAmbientLight); + + notifier.signalChanged(); + } + + @Override + public FileResolution getUniformShader() { + return Components.Files.VIEW_UNIFORMS; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java index 080f2a26a..d41672f8c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java @@ -4,6 +4,7 @@ import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder; @@ -40,7 +41,7 @@ public class BlockVertex implements VertexType { @Override public FileResolution getLayoutShader() { - return LayoutShaders.BLOCK; + return Components.Files.BLOCK_LAYOUT; } public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) { diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/Formats.java b/src/main/java/com/jozufozu/flywheel/core/vertex/Formats.java index 901ff449d..8c2c31e03 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/Formats.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/Formats.java @@ -1,6 +1,12 @@ package com.jozufozu.flywheel.core.vertex; +import com.jozufozu.flywheel.core.ComponentRegistry; + public class Formats { - public static final BlockVertex BLOCK = new BlockVertex(); - public static final PosTexNormalVertex POS_TEX_NORMAL = new PosTexNormalVertex(); + public static final BlockVertex BLOCK = ComponentRegistry.register(new BlockVertex()); + public static final PosTexNormalVertex POS_TEX_NORMAL = ComponentRegistry.register(new PosTexNormalVertex()); + + public static void init() { + // noop + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java b/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java deleted file mode 100644 index 95843694c..000000000 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.jozufozu.flywheel.core.vertex; - -import java.util.function.BiConsumer; - -import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.core.source.FileResolution; -import com.jozufozu.flywheel.core.source.SourceChecks; -import com.jozufozu.flywheel.core.source.SourceFile; -import com.jozufozu.flywheel.core.source.error.ErrorReporter; -import com.jozufozu.flywheel.util.ResourceUtil; - -import net.minecraft.resources.ResourceLocation; - -public class LayoutShaders { - public static final BiConsumer CHECK = SourceChecks.checkFunctionArity("flw_layoutVertex", 0); - - public static final FileResolution BLOCK = create(ResourceUtil.subPath(Names.BLOCK, ".vert")); - public static final FileResolution POS_TEX_NORMAL = create(ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert")); - - public static FileResolution create(ResourceLocation location) { - return FileResolution.get(location).validateWith(CHECK); - } - - public static void init() { - } - - public static class Names { - public static final ResourceLocation BLOCK = Flywheel.rl("layout/block"); - public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal"); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java index e55540dbf..2c115041c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertex.java @@ -3,6 +3,7 @@ package com.jozufozu.flywheel.core.vertex; import java.nio.ByteBuffer; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.source.FileResolution; @@ -30,6 +31,6 @@ public class PosTexNormalVertex implements VertexType { @Override public FileResolution getLayoutShader() { - return LayoutShaders.POS_TEX_NORMAL; + return Components.Files.POS_TEX_NORMAL_LAYOUT; } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/FogUpdateMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/FogUpdateMixin.java new file mode 100644 index 000000000..6312ce9e3 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/FogUpdateMixin.java @@ -0,0 +1,33 @@ +package com.jozufozu.flywheel.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.jozufozu.flywheel.core.Components; + +import net.minecraft.client.renderer.FogRenderer; + +@Mixin(FogRenderer.class) +public class FogUpdateMixin { + + @Inject(method = "setupNoFog", at = @At("TAIL")) + private static void onNoFog(CallbackInfo ci) { + flywheel$updateFog(); + } + + @Inject(method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", remap = false, at = @At("TAIL")) + private static void onFog(CallbackInfo ci) { + flywheel$updateFog(); + } + + @Inject(method = "levelFogColor", at = @At("TAIL")) + private static void onFogColor(CallbackInfo ci) { + flywheel$updateFog(); + } + + private static void flywheel$updateFog() { + Components.FOG_PROVIDER.update(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/util/MatrixWrite.java b/src/main/java/com/jozufozu/flywheel/util/MatrixWrite.java index 9af8c92bc..5b29338a7 100644 --- a/src/main/java/com/jozufozu/flywheel/util/MatrixWrite.java +++ b/src/main/java/com/jozufozu/flywheel/util/MatrixWrite.java @@ -2,6 +2,9 @@ package com.jozufozu.flywheel.util; import java.nio.ByteBuffer; +import com.mojang.math.Matrix3f; +import com.mojang.math.Matrix4f; + /** * @see com.jozufozu.flywheel.mixin.matrix.Matrix3fMixin * @see com.jozufozu.flywheel.mixin.matrix.Matrix4fMixin @@ -14,4 +17,12 @@ public interface MatrixWrite { void flywheel$writeUnsafe(long ptr); void flywheel$write(ByteBuffer buf); + + static void write(Matrix4f matrix, ByteBuffer buf) { + ((MatrixWrite) (Object) matrix).flywheel$write(buf); + } + + static void writeUnsafe(Matrix4f matrix, long ptr) { + ((MatrixWrite) (Object) matrix).flywheel$writeUnsafe(ptr); + } } diff --git a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java b/src/main/java/com/jozufozu/flywheel/util/RenderMath.java index 9ee9ecddc..861262f71 100644 --- a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java +++ b/src/main/java/com/jozufozu/flywheel/util/RenderMath.java @@ -50,26 +50,6 @@ public class RenderMath { return Math.sqrt(lengthSqr(x, y, z)); } - public static float rad(double angle) { - if (angle == 0) return 0; - return (float) (angle / 180 * Math.PI); - } - - public static float deg(double angle) { - if (angle == 0) return 0; - return (float) (angle * 180 / Math.PI); - } - - public static float angleLerp(double pct, double current, double target) { - return (float) (current + getShortestAngleDiff(current, target) * pct); - } - - public static float getShortestAngleDiff(double current, double target) { - current = current % 360; - target = target % 360; - return (float) (((((target - current) % 360) + 540) % 360) - 180); - } - public static float diffuseLight(float x, float y, float z, boolean shaded) { if (!shaded) { return 1f; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index e1746a006..834d92097 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -11,8 +11,8 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.BasicModelSupplier; +import com.jozufozu.flywheel.core.Components; import com.jozufozu.flywheel.core.hardcoded.ModelPart; -import com.jozufozu.flywheel.core.material.MaterialShaders; import com.jozufozu.flywheel.core.structs.StructTypes; import com.jozufozu.flywheel.core.structs.oriented.OrientedPart; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -26,7 +26,7 @@ import net.minecraft.world.level.block.entity.BellBlockEntity; public class BellInstance extends BlockEntityInstance implements DynamicInstance { - private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, new Material(Sheets.solidBlockSheet(), MaterialShaders.SHADED_VERTEX, MaterialShaders.DEFAULT_FRAGMENT)); + private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, new Material(Sheets.solidBlockSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT)); private final OrientedPart bell; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index d444378ea..f50b6314f 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -12,8 +12,8 @@ import com.jozufozu.flywheel.api.InstancerManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.BasicModelSupplier; +import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.hardcoded.ModelPart; -import com.jozufozu.flywheel.core.material.MaterialShaders; import com.jozufozu.flywheel.core.structs.StructTypes; import com.jozufozu.flywheel.core.structs.model.TransformedPart; import com.jozufozu.flywheel.core.structs.oriented.OrientedPart; @@ -25,7 +25,6 @@ import it.unimi.dsi.fastutil.floats.Float2FloatFunction; import net.minecraft.Util; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.Material; import net.minecraft.world.level.block.AbstractChestBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.ChestBlock; @@ -37,15 +36,14 @@ import net.minecraft.world.level.block.state.properties.ChestType; public class ChestInstance extends BlockEntityInstance implements DynamicInstance { - private static final com.jozufozu.flywheel.api.material.Material CHEST_MATERIAL = new com.jozufozu.flywheel.api.material.Material(Sheets.chestSheet(), MaterialShaders.SHADED_VERTEX, MaterialShaders.DEFAULT_FRAGMENT); - private static final BiFunction LID = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createLidModel(type, mat.sprite()), CHEST_MATERIAL)); - private static final BiFunction BASE = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createBaseModel(type, mat.sprite()), CHEST_MATERIAL)); + private static final BiFunction LID = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createLidModel(type, mat), Materials.CHEST)); + private static final BiFunction BASE = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createBaseModel(type, mat), Materials.CHEST)); private final OrientedPart body; private final TransformedPart lid; private final Float2FloatFunction lidProgress; - private final Material renderMaterial; + private final TextureAtlasSprite sprite; @NotNull private final ChestType chestType; private final Quaternion baseRotation; @@ -58,7 +56,7 @@ public class ChestInstance extends Block Block block = blockState.getBlock(); chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE; - renderMaterial = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()); + sprite = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()).sprite(); body = baseInstance() .setPosition(getInstancePosition()); @@ -126,14 +124,14 @@ public class ChestInstance extends Block private OrientedPart baseInstance() { return instancerManager.factory(StructTypes.ORIENTED) - .model(BASE.apply(chestType, renderMaterial)) + .model(BASE.apply(chestType, sprite)) .createInstance(); } private TransformedPart lidInstance() { return instancerManager.factory(StructTypes.TRANSFORMED) - .model(LID.apply(chestType, renderMaterial)) + .model(LID.apply(chestType, sprite)) .createInstance(); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index 7adb8713f..3d5b2d395 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -5,12 +5,11 @@ import org.jetbrains.annotations.NotNull; import com.jozufozu.flywheel.api.InstancerManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import com.jozufozu.flywheel.core.BasicModelSupplier; +import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.Models; import com.jozufozu.flywheel.core.hardcoded.ModelPart; -import com.jozufozu.flywheel.core.material.MaterialShaders; import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.structs.StructTypes; import com.jozufozu.flywheel.core.structs.model.TransformedPart; @@ -19,9 +18,7 @@ import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; -import net.minecraft.client.renderer.RenderType; import net.minecraft.core.Vec3i; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.entity.vehicle.AbstractMinecart; import net.minecraft.world.level.block.RenderShape; @@ -30,8 +27,7 @@ import net.minecraft.world.phys.Vec3; public class MinecartInstance extends EntityInstance implements DynamicInstance, TickableInstance { - private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); - private static final BasicModelSupplier MODEL = new BasicModelSupplier(MinecartInstance::getBodyModel, new Material(RenderType.entitySolid(MINECART_LOCATION), MaterialShaders.SHADED_VERTEX, MaterialShaders.DEFAULT_FRAGMENT)); + private static final BasicModelSupplier MODEL = new BasicModelSupplier(MinecartInstance::getBodyModel, Materials.MINECART); private final PoseStack stack = new PoseStack(); diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index e02349d79..819774c60 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -7,11 +7,10 @@ import java.util.function.Function; import com.jozufozu.flywheel.api.InstancedPart; import com.jozufozu.flywheel.api.InstancerManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.BasicModelSupplier; +import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.hardcoded.ModelPart; -import com.jozufozu.flywheel.core.material.MaterialShaders; import com.jozufozu.flywheel.core.structs.StructTypes; import com.jozufozu.flywheel.core.structs.model.TransformedPart; import com.jozufozu.flywheel.util.AnimationTickHolder; @@ -21,7 +20,6 @@ import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; import net.minecraft.Util; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.Direction; @@ -31,9 +29,8 @@ import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; public class ShulkerBoxInstance extends BlockEntityInstance implements DynamicInstance { - private static final Material SHULKER_BOX_MATERIAL = new Material(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), MaterialShaders.SHADED_VERTEX, MaterialShaders.DEFAULT_FRAGMENT); - private static final Function BASE = Util.memoize(it -> new BasicModelSupplier(() -> makeBaseModel(it), SHULKER_BOX_MATERIAL)); - private static final Function LID = Util.memoize(it -> new BasicModelSupplier(() -> makeLidModel(it), SHULKER_BOX_MATERIAL)); + private static final Function BASE = Util.memoize(it -> new BasicModelSupplier(() -> makeBaseModel(it), Materials.SHULKER)); + private static final Function LID = Util.memoize(it -> new BasicModelSupplier(() -> makeLidModel(it), Materials.SHULKER)); private final TextureAtlasSprite texture; diff --git a/src/main/resources/assets/flywheel/flywheel/context/common.vert b/src/main/resources/assets/flywheel/flywheel/context/common.vert index d9e0807ea..6ea08bf2f 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/common.vert +++ b/src/main/resources/assets/flywheel/flywheel/context/common.vert @@ -1,9 +1,7 @@ #use "flywheel:api/vertex.glsl" #use "flywheel:util/fog.glsl" - -uniform mat4 uViewProjection; -uniform vec3 uCameraPos; -uniform int uFogShape; +#use "flywheel:uniform/fog.glsl" +#use "flywheel:uniform/view.glsl" void flw_contextVertex() { // TODO: remove this @@ -11,7 +9,7 @@ void flw_contextVertex() { flw_vertexColor = vec4(flw_vertexNormal, 1.0); #endif - flw_distance = fog_distance(flw_vertexPos.xyz, uCameraPos, uFogShape); - gl_Position = uViewProjection * flw_vertexPos; + 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 46cb1ad37..942cb70d8 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag @@ -1,8 +1,6 @@ #use "flywheel:api/fragment.glsl" #use "flywheel:util/fog.glsl" - -uniform vec2 uFogRange; -uniform vec4 uFogColor; +#use "flywheel:uniform/fog.glsl" uniform sampler2D uCrumblingTex; @@ -37,9 +35,9 @@ void flw_contextFragment() { #endif #ifdef COLOR_FOG - color = linear_fog(color, flw_distance, uFogRange.x, uFogRange.y, uFogColor); + 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, uFogRange.x, uFogRange.y); + color = linear_fog_fade(color, flw_distance, flw_fogRange.x, flw_fogRange.y); #endif fragColor = color; diff --git a/src/main/resources/assets/flywheel/flywheel/context/world.frag b/src/main/resources/assets/flywheel/flywheel/context/world.frag index 872b8db6d..8f53b158b 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/world.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/world.frag @@ -1,5 +1,6 @@ #use "flywheel:api/fragment.glsl" #use "flywheel:util/fog.glsl" +#use "flywheel:uniform/fog.glsl" // optimize discard usage #ifdef ALPHA_DISCARD @@ -8,9 +9,6 @@ layout (depth_greater) out float gl_FragDepth; #endif #endif -uniform vec2 uFogRange; -uniform vec4 uFogColor; - uniform sampler2D uBlockAtlas; uniform sampler2D uLightMap; @@ -28,9 +26,9 @@ void flw_contextFragment() { #endif #ifdef COLOR_FOG - color = linear_fog(color, flw_distance, uFogRange.x, uFogRange.y, uFogColor); + 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, uFogRange.x, uFogRange.y); + color = linear_fog_fade(color, flw_distance, flw_fogRange.x, flw_fogRange.y); #endif fragColor = color; diff --git a/src/main/resources/assets/flywheel/flywheel/material/shaded.vert b/src/main/resources/assets/flywheel/flywheel/material/shaded.vert index cc274aaa2..f7ac29954 100644 --- a/src/main/resources/assets/flywheel/flywheel/material/shaded.vert +++ b/src/main/resources/assets/flywheel/flywheel/material/shaded.vert @@ -1,13 +1,12 @@ #use "flywheel:api/vertex.glsl" #use "flywheel:util/diffuse.glsl" - -uniform int uConstantAmbientLight; +#use "flywheel:uniform/view.glsl" void flw_materialVertex() { flw_vertexNormal = normalize(flw_vertexNormal); float diffuseFactor; - if (uConstantAmbientLight == 1) { + if (flw_constantAmbientLight == 1) { diffuseFactor = diffuseNether(flw_vertexNormal); } else { diffuseFactor = diffuse(flw_vertexNormal); diff --git a/src/main/resources/assets/flywheel/flywheel/uniform/fog.glsl b/src/main/resources/assets/flywheel/flywheel/uniform/fog.glsl new file mode 100644 index 000000000..2acbef9e1 --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/uniform/fog.glsl @@ -0,0 +1,5 @@ +layout(std140, binding = 1) uniform flw_fog { + vec4 flw_fogColor; + vec2 flw_fogRange; + int flw_fogShape; +}; diff --git a/src/main/resources/assets/flywheel/flywheel/uniform/view.glsl b/src/main/resources/assets/flywheel/flywheel/uniform/view.glsl new file mode 100644 index 000000000..4def2de12 --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/uniform/view.glsl @@ -0,0 +1,6 @@ + +layout(std140, binding = 0) uniform flw_view { + mat4 flw_viewProjection; + vec4 flw_cameraPos; + int flw_constantAmbientLight; +}; diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index 71f847654..28306e886 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -14,6 +14,7 @@ "ClientLevelMixin", "EntityTypeMixin", "FixFabulousDepthMixin", + "FogUpdateMixin", "FrustumMixin", "GlStateManagerMixin", "InstanceAddMixin",