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",