From fe0eacad8e8df7f52c2b67927632746706eadc13 Mon Sep 17 00:00:00 2001
From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com>
Date: Mon, 15 Jul 2024 15:36:52 -0600
Subject: [PATCH] Light clean up
- Ensure section set returned by SectionTracker is Unmodifiable to avoid copy in LightUpdatedVisualStorage
- Do not recompute section set in ShaderLightVisualStorage if not dirty
- Fix BlockEntityStorage not clearing posLookup on recreation or invalidation
- Fix Storage.invalidate not clearing everything
- Inline TopLevelEmbeddedEnvironment and NestedEmbeddedEnvironment into AbstractEmbeddedEnvironment and rename to EmbeddedEnvironment
- Move some classes between packages
- Remove unused fields in EmbeddingUniforms
- Remove suffix on field names in BufferBindings
- Rename enqueueLightUpdateSection methods to onLightUpdate
- Rename SectionCollectorImpl to SectionTracker
- Rename classes, methods, fields, and parameters and edit javadoc and comments to match previously done renames, new renames, and other existing classes
---
.../flywheel/api/backend/Engine.java | 14 +-
.../api/visual/LightUpdatedVisual.java | 5 +-
.../api/visual/SectionTrackedVisual.java | 8 +-
.../flywheel/api/visual/Visual.java | 1 +
.../{engine/embed => }/LightUpdateHolder.java | 13 +-
.../component/SsboInstanceComponent.java | 2 +-
.../backend/engine/{embed => }/Arena.java | 2 +-
.../flywheel/backend/engine/DrawManager.java | 1 -
.../flywheel/backend/engine/EngineImpl.java | 30 ++--
.../backend/engine/EnvironmentStorage.java | 19 ---
.../backend/engine/{embed => }/LightLut.java | 8 +-
.../engine/{embed => }/LightStorage.java | 3 +-
...ironment.java => EmbeddedEnvironment.java} | 89 +++++++-----
.../engine/embed/EmbeddingUniforms.java | 14 +-
.../backend/engine/embed/Environment.java | 4 +-
.../engine/embed/EnvironmentStorage.java | 18 +++
.../engine/embed/GlobalEnvironment.java | 9 +-
.../embed/NestedEmbeddedEnvironment.java | 23 ---
.../embed/TopLevelEmbeddedEnvironment.java | 19 ---
.../engine/indirect/BufferBindings.java | 16 +--
.../engine/indirect/IndirectBuffers.java | 4 +-
.../engine/indirect/IndirectDrawManager.java | 9 +-
.../backend/engine/indirect/LightBuffers.java | 11 +-
.../instancing/InstancedDrawManager.java | 2 +-
.../engine/instancing/InstancedLight.java | 6 +-
.../backend/mixin/ClientChunkCacheMixin.java | 2 +-
.../internal/indirect/buffer_bindings.glsl | 4 +-
.../flywheel/internal/indirect/light.glsl | 4 +-
.../impl/mixin/ClientChunkCacheMixin.java | 2 +-
.../VisualizationManagerImpl.java | 23 ++-
.../manager/BlockEntityStorage.java | 14 +-
.../manager/VisualManagerImpl.java | 23 +--
...ge.java => LightUpdatedVisualStorage.java} | 77 +++++-----
...CollectorImpl.java => SectionTracker.java} | 19 ++-
.../storage/ShaderLightStorage.java | 52 -------
.../storage/ShaderLightVisualStorage.java | 53 +++++++
.../impl/visualization/storage/Storage.java | 131 +++++++++---------
.../flywheel/vanilla/MinecartVisual.java | 2 +-
38 files changed, 364 insertions(+), 372 deletions(-)
rename common/src/backend/java/dev/engine_room/flywheel/backend/{engine/embed => }/LightUpdateHolder.java (84%)
rename common/src/backend/java/dev/engine_room/flywheel/backend/engine/{embed => }/Arena.java (95%)
delete mode 100644 common/src/backend/java/dev/engine_room/flywheel/backend/engine/EnvironmentStorage.java
rename common/src/backend/java/dev/engine_room/flywheel/backend/engine/{embed => }/LightLut.java (96%)
rename common/src/backend/java/dev/engine_room/flywheel/backend/engine/{embed => }/LightStorage.java (99%)
rename common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/{AbstractEmbeddedEnvironment.java => EmbeddedEnvironment.java} (70%)
create mode 100644 common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EnvironmentStorage.java
delete mode 100644 common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/NestedEmbeddedEnvironment.java
delete mode 100644 common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/TopLevelEmbeddedEnvironment.java
rename common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/{LightUpdatedStorage.java => LightUpdatedVisualStorage.java} (74%)
rename common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/{SectionCollectorImpl.java => SectionTracker.java} (58%)
delete mode 100644 common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightStorage.java
create mode 100644 common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightVisualStorage.java
diff --git a/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java b/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java
index 86865e33b..b6b7baa25 100644
--- a/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java
+++ b/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java
@@ -62,13 +62,6 @@ public interface Engine {
*/
Vec3i renderOrigin();
- /**
- * Free all resources associated with this engine.
- *
- * This engine will not be used again after this method is called.
- */
- void delete();
-
/**
* Assign the set of sections that visuals have requested GPU light for.
*
@@ -78,6 +71,13 @@ public interface Engine {
*/
void lightSections(LongSet sections);
+ /**
+ * Free all resources associated with this engine.
+ *
+ * This engine will not be used again after this method is called.
+ */
+ void delete();
+
/**
* A block to be rendered as a crumbling overlay.
* @param progress The progress of the crumbling animation in the range [0, 10).
diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/LightUpdatedVisual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/LightUpdatedVisual.java
index 3ac56d93d..52015c436 100644
--- a/common/src/api/java/dev/engine_room/flywheel/api/visual/LightUpdatedVisual.java
+++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/LightUpdatedVisual.java
@@ -9,7 +9,8 @@ package dev.engine_room.flywheel.api.visual;
*/
public non-sealed interface LightUpdatedVisual extends SectionTrackedVisual {
/**
- * Called when a section this visual is contained in receives a light update.
+ * Called when a section this visual is contained in receives a light update. It is not called
+ * unconditionally after visual creation or {@link SectionCollector#sections}.
*
*
Even if multiple sections are updated at the same time, this method will only be called once.
*
@@ -17,8 +18,6 @@ public non-sealed interface LightUpdatedVisual extends SectionTrackedVisual {
* returned by {@link DynamicVisual#planFrame} simultaneously. It is safe to query/update light here,
* but you must ensure proper synchronization if you want to mutate anything outside this visual or
* anything that is also mutated within {@link DynamicVisual#planFrame}.
- *
- * This method not is invoked automatically after visual creation.
*/
void updateLight(float partialTick);
}
diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/SectionTrackedVisual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/SectionTrackedVisual.java
index 725d4a4ed..a2189357a 100644
--- a/common/src/api/java/dev/engine_room/flywheel/api/visual/SectionTrackedVisual.java
+++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/SectionTrackedVisual.java
@@ -6,15 +6,15 @@ import it.unimi.dsi.fastutil.longs.LongSet;
public sealed interface SectionTrackedVisual extends Visual permits ShaderLightVisual, LightUpdatedVisual {
/**
- * Set the section property object.
+ * Set the section collector object.
*
* This method is only called once, upon visual creation.
- *
If the property is assigned to in this method, the
+ *
If the collector is invoked in this method, the
* visual will immediately be tracked in the given sections.
*
- * @param property The property.
+ * @param collector The collector.
*/
- void setSectionCollector(SectionCollector property);
+ void setSectionCollector(SectionCollector collector);
@ApiStatus.NonExtendable
interface SectionCollector {
diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java
index 60b42fd15..f6d44d1de 100644
--- a/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java
+++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java
@@ -6,6 +6,7 @@ package dev.engine_room.flywheel.api.visual;
* @see DynamicVisual
* @see TickableVisual
* @see LightUpdatedVisual
+ * @see ShaderLightVisual
*/
public interface Visual {
/**
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightUpdateHolder.java b/common/src/backend/java/dev/engine_room/flywheel/backend/LightUpdateHolder.java
similarity index 84%
rename from common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightUpdateHolder.java
rename to common/src/backend/java/dev/engine_room/flywheel/backend/LightUpdateHolder.java
index 52c5c09f7..e6f9e856d 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightUpdateHolder.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/LightUpdateHolder.java
@@ -1,7 +1,8 @@
-package dev.engine_room.flywheel.backend.engine.embed;
+package dev.engine_room.flywheel.backend;
import dev.engine_room.flywheel.lib.util.LevelAttached;
import it.unimi.dsi.fastutil.longs.LongArraySet;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.world.level.LevelAccessor;
@@ -11,12 +12,15 @@ import net.minecraft.world.level.LevelAccessor;
public class LightUpdateHolder {
private static final LevelAttached HOLDERS = new LevelAttached<>(level -> new LightUpdateHolder());
+ private final LongSet updatedSections = new LongOpenHashSet();
+
+ private LightUpdateHolder() {
+ }
+
public static LightUpdateHolder get(LevelAccessor level) {
return HOLDERS.get(level);
}
- private final LongSet updatedSections = new LongArraySet();
-
public LongSet getAndClearUpdatedSections() {
if (updatedSections.isEmpty()) {
return LongSet.of();
@@ -30,7 +34,4 @@ public class LightUpdateHolder {
public void add(long section) {
updatedSections.add(section);
}
-
- private LightUpdateHolder() {
- }
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java
index 92fb61099..c8902b2d4 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java
@@ -43,7 +43,7 @@ public class SsboInstanceComponent extends InstanceAssemblerComponent {
fnBody.ret(GlslExpr.call(STRUCT_NAME, unpackArgs));
- builder._addRaw("layout(std430, binding = " + BufferBindings.INSTANCE_BUFFER_BINDING + ") restrict readonly buffer InstanceBuffer {\n"
+ builder._addRaw("layout(std430, binding = " + BufferBindings.INSTANCE + ") restrict readonly buffer InstanceBuffer {\n"
+ " uint _flw_instances[];\n"
+ "};");
builder.blankLine();
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Arena.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/Arena.java
similarity index 95%
rename from common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Arena.java
rename to common/src/backend/java/dev/engine_room/flywheel/backend/engine/Arena.java
index a43d6cbe5..101cc0013 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Arena.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/Arena.java
@@ -1,4 +1,4 @@
-package dev.engine_room.flywheel.backend.engine.embed;
+package dev.engine_room.flywheel.backend.engine;
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
import it.unimi.dsi.fastutil.ints.IntArrayList;
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java
index 8f8def6e0..8b78be928 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java
@@ -16,7 +16,6 @@ import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.backend.FlwBackend;
import dev.engine_room.flywheel.backend.engine.embed.Environment;
-import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
import dev.engine_room.flywheel.lib.util.Pair;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java
index fa36cd21f..46e66c007 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java
@@ -14,9 +14,9 @@ import dev.engine_room.flywheel.api.task.Plan;
import dev.engine_room.flywheel.api.task.TaskExecutor;
import dev.engine_room.flywheel.api.visualization.VisualEmbedding;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
+import dev.engine_room.flywheel.backend.engine.embed.EmbeddedEnvironment;
import dev.engine_room.flywheel.backend.engine.embed.Environment;
-import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
-import dev.engine_room.flywheel.backend.engine.embed.TopLevelEmbeddedEnvironment;
+import dev.engine_room.flywheel.backend.engine.embed.EnvironmentStorage;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
import dev.engine_room.flywheel.lib.task.Flag;
@@ -30,11 +30,11 @@ import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.Vec3;
public class EngineImpl implements Engine {
- private final int sqrMaxOriginDistance;
private final DrawManager extends AbstractInstancer>> drawManager;
+ private final int sqrMaxOriginDistance;
+ private final Flag flushFlag = new NamedFlag("flushed");
private final EnvironmentStorage environmentStorage;
private final LightStorage lightStorage;
- private final Flag flushFlag = new NamedFlag("flushed");
private BlockPos renderOrigin = BlockPos.ZERO;
@@ -45,6 +45,11 @@ public class EngineImpl implements Engine {
lightStorage = new LightStorage(level);
}
+ @Override
+ public VisualizationContext createVisualizationContext(RenderStage stage) {
+ return new VisualizationContextImpl(stage);
+ }
+
@Override
public Plan createFramePlan() {
return lightStorage.createFramePlan()
@@ -69,11 +74,6 @@ public class EngineImpl implements Engine {
drawManager.renderCrumbling(crumblingBlocks);
}
- @Override
- public VisualizationContext createVisualizationContext(RenderStage stage) {
- return new VisualizationContextImpl(stage);
- }
-
@Override
public boolean updateRenderOrigin(Camera camera) {
Vec3 cameraPos = camera.getPosition();
@@ -97,14 +97,14 @@ public class EngineImpl implements Engine {
}
@Override
- public void delete() {
- drawManager.delete();
- lightStorage.delete();
+ public void lightSections(LongSet sections) {
+ lightStorage.sections(sections);
}
@Override
- public void lightSections(LongSet sections) {
- lightStorage.sections(sections);
+ public void delete() {
+ drawManager.delete();
+ lightStorage.delete();
}
public Instancer instancer(Environment environment, InstanceType type, Model model, RenderStage stage) {
@@ -150,7 +150,7 @@ public class EngineImpl implements Engine {
@Override
public VisualEmbedding createEmbedding() {
- var out = new TopLevelEmbeddedEnvironment(EngineImpl.this, stage);
+ var out = new EmbeddedEnvironment(EngineImpl.this, stage);
environmentStorage.track(out);
return out;
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EnvironmentStorage.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EnvironmentStorage.java
deleted file mode 100644
index e68ea5250..000000000
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EnvironmentStorage.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package dev.engine_room.flywheel.backend.engine;
-
-import dev.engine_room.flywheel.backend.engine.embed.AbstractEmbeddedEnvironment;
-import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
-import it.unimi.dsi.fastutil.objects.ReferenceSet;
-import it.unimi.dsi.fastutil.objects.ReferenceSets;
-
-public class EnvironmentStorage {
- protected final ReferenceSet environments = ReferenceSets.synchronize(new ReferenceLinkedOpenHashSet<>());
-
- public void track(AbstractEmbeddedEnvironment environment) {
- environments.add(environment);
- }
-
- public void flush() {
- environments.removeIf(AbstractEmbeddedEnvironment::isDeleted);
- environments.forEach(AbstractEmbeddedEnvironment::flush);
- }
-}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightLut.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java
similarity index 96%
rename from common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightLut.java
rename to common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java
index 736811c5a..bb04c7760 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightLut.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java
@@ -1,4 +1,4 @@
-package dev.engine_room.flywheel.backend.engine.embed;
+package dev.engine_room.flywheel.backend.engine;
import org.jetbrains.annotations.NotNull;
@@ -11,8 +11,8 @@ import it.unimi.dsi.fastutil.longs.LongComparator;
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
import net.minecraft.core.SectionPos;
-public class LightLut {
- public static final LongComparator SECTION_X_THEN_Y_THEN_Z = (long a, long b) -> {
+public final class LightLut {
+ private static final LongComparator SECTION_X_THEN_Y_THEN_Z = (long a, long b) -> {
final var xComp = Integer.compare(SectionPos.x(a), SectionPos.x(b));
if (xComp != 0) {
return xComp;
@@ -24,6 +24,8 @@ public class LightLut {
return Integer.compare(SectionPos.z(a), SectionPos.z(b));
};
+ private LightLut() {
+ }
// Massive kudos to RogueLogix for figuring out this LUT scheme.
// TODO: switch to y x z or x z y ordering
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightStorage.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java
similarity index 99%
rename from common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightStorage.java
rename to common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java
index 90f551e9a..909dbdb95 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/LightStorage.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java
@@ -1,4 +1,4 @@
-package dev.engine_room.flywheel.backend.engine.embed;
+package dev.engine_room.flywheel.backend.engine;
import java.util.BitSet;
@@ -7,6 +7,7 @@ import org.lwjgl.system.MemoryUtil;
import dev.engine_room.flywheel.api.event.RenderContext;
import dev.engine_room.flywheel.api.task.Plan;
+import dev.engine_room.flywheel.backend.LightUpdateHolder;
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
import dev.engine_room.flywheel.lib.task.SimplePlan;
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/AbstractEmbeddedEnvironment.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java
similarity index 70%
rename from common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/AbstractEmbeddedEnvironment.java
rename to common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java
index 6bf89450c..fef623172 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/AbstractEmbeddedEnvironment.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java
@@ -1,5 +1,6 @@
package dev.engine_room.flywheel.backend.engine.embed;
+import org.jetbrains.annotations.Nullable;
import org.joml.Matrix3f;
import org.joml.Matrix3fc;
import org.joml.Matrix4f;
@@ -17,61 +18,44 @@ import dev.engine_room.flywheel.backend.engine.EngineImpl;
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
import net.minecraft.core.Vec3i;
-public abstract class AbstractEmbeddedEnvironment implements Environment, VisualEmbedding {
- protected final Matrix4f pose = new Matrix4f();
- protected final Matrix3f normal = new Matrix3f();
+public class EmbeddedEnvironment implements VisualEmbedding, Environment {
+ private final EngineImpl engine;
+ private final RenderStage renderStage;
+ @Nullable
+ private final EmbeddedEnvironment parent;
+ private final InstancerProvider instancerProvider;
+
+ private final Matrix4f pose = new Matrix4f();
+ private final Matrix3f normal = new Matrix3f();
private final Matrix4f poseComposed = new Matrix4f();
private final Matrix3f normalComposed = new Matrix3f();
- private final InstancerProvider instancerProvider;
- protected final EngineImpl engine;
- private final RenderStage renderStage;
private boolean deleted = false;
- public AbstractEmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
+ public EmbeddedEnvironment(EngineImpl engine, RenderStage renderStage, @Nullable EmbeddedEnvironment parent) {
this.engine = engine;
this.renderStage = renderStage;
+ this.parent = parent;
instancerProvider = new InstancerProvider() {
@Override
public Instancer instancer(InstanceType type, Model model) {
// Kinda cursed usage of anonymous classes here, but it does the job.
- return engine.instancer(AbstractEmbeddedEnvironment.this, type, model, renderStage);
+ return engine.instancer(EmbeddedEnvironment.this, type, model, renderStage);
}
};
}
+ public EmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
+ this(engine, renderStage, null);
+ }
+
@Override
public void transforms(Matrix4fc pose, Matrix3fc normal) {
this.pose.set(pose);
this.normal.set(normal);
}
- public void flush() {
- poseComposed.identity();
- normalComposed.identity();
-
- composeMatrices(poseComposed, normalComposed);
- }
-
- @Override
- public void setupDraw(GlProgram program) {
- program.setMat4(EmbeddingUniforms.MODEL_MATRIX, poseComposed);
- program.setMat3(EmbeddingUniforms.NORMAL_MATRIX, normalComposed);
- }
-
- @Override
- public void setupCull(GlProgram program) {
- program.setBool(EmbeddingUniforms.USE_MODEL_MATRIX, true);
-
- program.setMat4(EmbeddingUniforms.MODEL_MATRIX1, poseComposed);
- }
-
- @Override
- public ContextShader contextShader() {
- return ContextShader.EMBEDDED;
- }
-
@Override
public InstancerProvider instancerProvider() {
return instancerProvider;
@@ -84,12 +68,47 @@ public abstract class AbstractEmbeddedEnvironment implements Environment, Visual
@Override
public VisualEmbedding createEmbedding() {
- var out = new NestedEmbeddedEnvironment(this, engine, renderStage);
+ var out = new EmbeddedEnvironment(engine, renderStage, this);
engine.environmentStorage()
.track(out);
return out;
}
+ @Override
+ public ContextShader contextShader() {
+ return ContextShader.EMBEDDED;
+ }
+
+ @Override
+ public void setupCull(GlProgram program) {
+ program.setBool(EmbeddingUniforms.USE_MODEL_MATRIX, true);
+ program.setMat4(EmbeddingUniforms.MODEL_MATRIX, poseComposed);
+ }
+
+ @Override
+ public void setupDraw(GlProgram program) {
+ program.setMat4(EmbeddingUniforms.MODEL_MATRIX, poseComposed);
+ program.setMat3(EmbeddingUniforms.NORMAL_MATRIX, normalComposed);
+ }
+
+ public void flush() {
+ poseComposed.identity();
+ normalComposed.identity();
+
+ composeMatrices(poseComposed, normalComposed);
+ }
+
+ private void composeMatrices(Matrix4f pose, Matrix3f normal) {
+ if (parent != null) {
+ parent.composeMatrices(pose, normal);
+ pose.mul(this.pose);
+ normal.mul(this.normal);
+ } else {
+ pose.set(this.pose);
+ normal.set(this.normal);
+ }
+ }
+
public boolean isDeleted() {
return deleted;
}
@@ -101,6 +120,4 @@ public abstract class AbstractEmbeddedEnvironment implements Environment, Visual
public void delete() {
deleted = true;
}
-
- public abstract void composeMatrices(Matrix4f pose, Matrix3f normal);
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddingUniforms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddingUniforms.java
index eb0c58bef..e62f0b018 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddingUniforms.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddingUniforms.java
@@ -1,11 +1,13 @@
package dev.engine_room.flywheel.backend.engine.embed;
-public class EmbeddingUniforms {
+public final class EmbeddingUniforms {
+ /**
+ * Only used by cull shaders.
+ */
+ public static final String USE_MODEL_MATRIX = "_flw_useModelMatrix";
public static final String MODEL_MATRIX = "_flw_modelMatrix";
public static final String NORMAL_MATRIX = "_flw_normalMatrix";
- public static final String USE_MODEL_MATRIX = "_flw_useModelMatrix";
- public static final String MODEL_MATRIX1 = "_flw_modelMatrix";
- public static final String ONE_OVER_LIGHT_BOX_SIZE = "_flw_oneOverLightBoxSize";
- public static final String LIGHT_VOLUME_MIN = "_flw_lightVolumeMin";
- public static final String USE_LIGHT_VOLUME = "_flw_useLightVolume";
+
+ private EmbeddingUniforms() {
+ }
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Environment.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Environment.java
index 626f103e5..83fa60d62 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Environment.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/Environment.java
@@ -6,7 +6,7 @@ import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
public interface Environment {
ContextShader contextShader();
- void setupDraw(GlProgram drawProgram);
-
void setupCull(GlProgram cullProgram);
+
+ void setupDraw(GlProgram drawProgram);
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EnvironmentStorage.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EnvironmentStorage.java
new file mode 100644
index 000000000..9206b9cf3
--- /dev/null
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EnvironmentStorage.java
@@ -0,0 +1,18 @@
+package dev.engine_room.flywheel.backend.engine.embed;
+
+import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
+import it.unimi.dsi.fastutil.objects.ReferenceSet;
+import it.unimi.dsi.fastutil.objects.ReferenceSets;
+
+public class EnvironmentStorage {
+ protected final ReferenceSet environments = ReferenceSets.synchronize(new ReferenceLinkedOpenHashSet<>());
+
+ public void track(EmbeddedEnvironment environment) {
+ environments.add(environment);
+ }
+
+ public void flush() {
+ environments.removeIf(EmbeddedEnvironment::isDeleted);
+ environments.forEach(EmbeddedEnvironment::flush);
+ }
+}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/GlobalEnvironment.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/GlobalEnvironment.java
index c6e50acbd..aaac1ca35 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/GlobalEnvironment.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/GlobalEnvironment.java
@@ -14,13 +14,12 @@ public class GlobalEnvironment implements Environment {
return ContextShader.DEFAULT;
}
- @Override
- public void setupDraw(GlProgram drawProgram) {
-
- }
-
@Override
public void setupCull(GlProgram cullProgram) {
cullProgram.setBool(EmbeddingUniforms.USE_MODEL_MATRIX, false);
}
+
+ @Override
+ public void setupDraw(GlProgram drawProgram) {
+ }
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/NestedEmbeddedEnvironment.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/NestedEmbeddedEnvironment.java
deleted file mode 100644
index fb4bfbb49..000000000
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/NestedEmbeddedEnvironment.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package dev.engine_room.flywheel.backend.engine.embed;
-
-import org.joml.Matrix3f;
-import org.joml.Matrix4f;
-
-import dev.engine_room.flywheel.api.event.RenderStage;
-import dev.engine_room.flywheel.backend.engine.EngineImpl;
-
-public class NestedEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
- private final AbstractEmbeddedEnvironment parent;
-
- public NestedEmbeddedEnvironment(AbstractEmbeddedEnvironment parent, EngineImpl engine, RenderStage renderStage) {
- super(engine, renderStage);
- this.parent = parent;
- }
-
- @Override
- public void composeMatrices(Matrix4f pose, Matrix3f normal) {
- parent.composeMatrices(pose, normal);
- pose.mul(this.pose);
- normal.mul(this.normal);
- }
-}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/TopLevelEmbeddedEnvironment.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/TopLevelEmbeddedEnvironment.java
deleted file mode 100644
index 297c3dd6b..000000000
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/TopLevelEmbeddedEnvironment.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package dev.engine_room.flywheel.backend.engine.embed;
-
-import org.joml.Matrix3f;
-import org.joml.Matrix4f;
-
-import dev.engine_room.flywheel.api.event.RenderStage;
-import dev.engine_room.flywheel.backend.engine.EngineImpl;
-
-public class TopLevelEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
- public TopLevelEmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
- super(engine, renderStage);
- }
-
- @Override
- public void composeMatrices(Matrix4f pose, Matrix3f normal) {
- pose.set(this.pose);
- normal.set(this.normal);
- }
-}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/BufferBindings.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/BufferBindings.java
index 97970f3b5..a0ae93a28 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/BufferBindings.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/BufferBindings.java
@@ -1,13 +1,13 @@
package dev.engine_room.flywheel.backend.engine.indirect;
-public class BufferBindings {
- public static final int INSTANCE_BUFFER_BINDING = 0;
- public static final int TARGET_BUFFER_BINDING = 1;
- public static final int MODEL_INDEX_BUFFER_BINDING = 2;
- public static final int MODEL_BUFFER_BINDING = 3;
- public static final int DRAW_BUFFER_BINDING = 4;
- public static final int LIGHT_LUT_BINDING = 5;
- public static final int LIGHT_SECTION_BINDING = 6;
+public final class BufferBindings {
+ public static final int INSTANCE = 0;
+ public static final int TARGET = 1;
+ public static final int MODEL_INDEX = 2;
+ public static final int MODEL = 3;
+ public static final int DRAW = 4;
+ public static final int LIGHT_LUT = 5;
+ public static final int LIGHT_SECTION = 6;
private BufferBindings() {
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java
index 68034d16a..90ecd4149 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java
@@ -110,7 +110,7 @@ public class IndirectBuffers {
private void multiBind() {
final long ptr = multiBindBlock.ptr();
- nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.INSTANCE_BUFFER_BINDING, IndirectBuffers.BUFFER_COUNT, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
+ nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.INSTANCE, IndirectBuffers.BUFFER_COUNT, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
}
/**
@@ -118,7 +118,7 @@ public class IndirectBuffers {
*/
public void bindForCrumbling() {
final long ptr = multiBindBlock.ptr();
- nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.INSTANCE_BUFFER_BINDING, 4, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
+ nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.INSTANCE, 4, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
}
public void delete() {
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java
index 1aadae5a3..d9ef2254a 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java
@@ -20,10 +20,10 @@ import dev.engine_room.flywheel.backend.engine.CommonCrumbling;
import dev.engine_room.flywheel.backend.engine.DrawManager;
import dev.engine_room.flywheel.backend.engine.GroupKey;
import dev.engine_room.flywheel.backend.engine.InstancerKey;
+import dev.engine_room.flywheel.backend.engine.LightStorage;
import dev.engine_room.flywheel.backend.engine.MaterialRenderState;
import dev.engine_room.flywheel.backend.engine.MeshPool;
import dev.engine_room.flywheel.backend.engine.TextureBinder;
-import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
import dev.engine_room.flywheel.backend.gl.array.GlVertexArray;
@@ -40,18 +40,15 @@ public class IndirectDrawManager extends DrawManager> {
private final GlVertexArray vertexArray;
private final Map, IndirectCullingGroup>> cullingGroups = new HashMap<>();
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
-
private final LightBuffers lightBuffers;
public IndirectDrawManager(IndirectPrograms programs) {
this.programs = programs;
programs.acquire();
+
stagingBuffer = new StagingBuffer(this.programs);
-
meshPool = new MeshPool();
-
vertexArray = GlVertexArray.create();
-
meshPool.bind(vertexArray);
lightBuffers = new LightBuffers();
}
@@ -170,7 +167,7 @@ public class IndirectDrawManager extends DrawManager> {
var block = MemoryBlock.malloc(IndirectBuffers.DRAW_COMMAND_STRIDE);
GlBufferType.DRAW_INDIRECT_BUFFER.bind(crumblingDrawBuffer.handle());
- glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.DRAW_BUFFER_BINDING, crumblingDrawBuffer.handle(), 0, IndirectBuffers.DRAW_COMMAND_STRIDE);
+ glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.DRAW, crumblingDrawBuffer.handle(), 0, IndirectBuffers.DRAW_COMMAND_STRIDE);
for (var groupEntry : byType.entrySet()) {
var byProgress = groupEntry.getValue();
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/LightBuffers.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/LightBuffers.java
index 2423ae0fb..9db63afb0 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/LightBuffers.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/LightBuffers.java
@@ -3,14 +3,11 @@ package dev.engine_room.flywheel.backend.engine.indirect;
import org.lwjgl.opengl.GL46;
import org.lwjgl.system.MemoryUtil;
-import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
+import dev.engine_room.flywheel.backend.engine.LightStorage;
public class LightBuffers {
- private final ResizableStorageArray sections = new ResizableStorageArray(LightStorage.SECTION_SIZE_BYTES);
private final ResizableStorageArray lut = new ResizableStorageArray(4);
-
- public LightBuffers() {
- }
+ private final ResizableStorageArray sections = new ResizableStorageArray(LightStorage.SECTION_SIZE_BYTES);
public void flush(StagingBuffer staging, LightStorage light) {
var capacity = light.capacity();
@@ -40,7 +37,7 @@ public class LightBuffers {
return;
}
- GL46.glBindBufferRange(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.LIGHT_LUT_BINDING, lut.handle(), 0, lut.byteCapacity());
- GL46.glBindBufferRange(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.LIGHT_SECTION_BINDING, sections.handle(), 0, sections.byteCapacity());
+ GL46.glBindBufferRange(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.LIGHT_LUT, lut.handle(), 0, lut.byteCapacity());
+ GL46.glBindBufferRange(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.LIGHT_SECTION, sections.handle(), 0, sections.byteCapacity());
}
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java
index 6ea923cc1..ae231de0b 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java
@@ -18,11 +18,11 @@ import dev.engine_room.flywheel.backend.engine.CommonCrumbling;
import dev.engine_room.flywheel.backend.engine.DrawManager;
import dev.engine_room.flywheel.backend.engine.GroupKey;
import dev.engine_room.flywheel.backend.engine.InstancerKey;
+import dev.engine_room.flywheel.backend.engine.LightStorage;
import dev.engine_room.flywheel.backend.engine.MaterialEncoder;
import dev.engine_room.flywheel.backend.engine.MaterialRenderState;
import dev.engine_room.flywheel.backend.engine.MeshPool;
import dev.engine_room.flywheel.backend.engine.TextureBinder;
-import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
import dev.engine_room.flywheel.backend.gl.TextureBuffer;
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedLight.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedLight.java
index 3d966f0c8..7831019d1 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedLight.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedLight.java
@@ -4,7 +4,7 @@ import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import dev.engine_room.flywheel.backend.Samplers;
-import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
+import dev.engine_room.flywheel.backend.engine.LightStorage;
import dev.engine_room.flywheel.backend.gl.TextureBuffer;
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
@@ -16,8 +16,8 @@ public class InstancedLight {
private final TextureBuffer sectionsTexture;
public InstancedLight() {
- sections = new GlBuffer();
lut = new GlBuffer();
+ sections = new GlBuffer();
lutTexture = new TextureBuffer(GL32.GL_R32UI);
sectionsTexture = new TextureBuffer(GL32.GL_R32UI);
}
@@ -54,8 +54,8 @@ public class InstancedLight {
}
public void delete() {
- sections.delete();
lut.delete();
+ sections.delete();
lutTexture.delete();
sectionsTexture.delete();
}
diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/ClientChunkCacheMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/ClientChunkCacheMixin.java
index 11ea0cea2..eb8c974ec 100644
--- a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/ClientChunkCacheMixin.java
+++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/ClientChunkCacheMixin.java
@@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import dev.engine_room.flywheel.backend.engine.embed.LightUpdateHolder;
+import dev.engine_room.flywheel.backend.LightUpdateHolder;
import net.minecraft.client.multiplayer.ClientChunkCache;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.SectionPos;
diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/buffer_bindings.glsl b/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/buffer_bindings.glsl
index 604da5269..c37db3502 100644
--- a/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/buffer_bindings.glsl
+++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/buffer_bindings.glsl
@@ -3,5 +3,5 @@
#define _FLW_MODEL_INDEX_BUFFER_BINDING 2
#define _FLW_MODEL_BUFFER_BINDING 3
#define _FLW_DRAW_BUFFER_BINDING 4
-#define _FLW_LIGHT_LUT_BINDING 5
-#define _FLW_LIGHT_SECTIONS_BINDING 6
+#define _FLW_LIGHT_LUT_BUFFER_BINDING 5
+#define _FLW_LIGHT_SECTIONS_BUFFER_BINDING 6
diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/light.glsl b/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/light.glsl
index bd688ef28..48975050e 100644
--- a/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/light.glsl
+++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/indirect/light.glsl
@@ -1,10 +1,10 @@
#include "flywheel:internal/light_lut.glsl"
-layout(std430, binding = _FLW_LIGHT_LUT_BINDING) restrict readonly buffer LightLut {
+layout(std430, binding = _FLW_LIGHT_LUT_BUFFER_BINDING) restrict readonly buffer LightLut {
uint _flw_lightLut[];
};
-layout(std430, binding = _FLW_LIGHT_SECTIONS_BINDING) restrict readonly buffer LightSections {
+layout(std430, binding = _FLW_LIGHT_SECTIONS_BUFFER_BINDING) restrict readonly buffer LightSections {
uint _flw_lightSections[];
};
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/ClientChunkCacheMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/ClientChunkCacheMixin.java
index d12415179..f55d6d2e9 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/ClientChunkCacheMixin.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/ClientChunkCacheMixin.java
@@ -24,7 +24,7 @@ abstract class ClientChunkCacheMixin {
var manager = VisualizationManagerImpl.get(level);
if (manager != null) {
- manager.enqueueLightUpdateSection(pos.asLong());
+ manager.onLightUpdate(pos.asLong());
}
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java
index efd5c6820..ccf69cc0e 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java
@@ -106,11 +106,11 @@ public class VisualizationManagerImpl implements VisualizationManager {
.ifFalse(update)
.plan()
.then(SimplePlan.of(() -> {
- if (blockEntities.lightSectionsDirty() || entities.lightSectionsDirty() || effects.lightSectionsDirty()) {
+ if (blockEntities.areGpuLightSectionsDirty() || entities.areGpuLightSectionsDirty() || effects.areGpuLightSectionsDirty()) {
var out = new LongOpenHashSet();
- out.addAll(blockEntities.lightSections());
- out.addAll(entities.lightSections());
- out.addAll(effects.lightSections());
+ out.addAll(blockEntities.gpuLightSections());
+ out.addAll(entities.gpuLightSections());
+ out.addAll(effects.gpuLightSections());
engine.lightSections(out);
}
}))
@@ -302,6 +302,12 @@ public class VisualizationManagerImpl implements VisualizationManager {
}
}
+ public void onLightUpdate(long section) {
+ blockEntities.onLightUpdate(section);
+ entities.onLightUpdate(section);
+ effects.onLightUpdate(section);
+ }
+
/**
* Free all acquired resources and delete this manager.
*/
@@ -315,13 +321,4 @@ public class VisualizationManagerImpl implements VisualizationManager {
effects.invalidate();
engine.delete();
}
-
- public void enqueueLightUpdateSection(long section) {
- blockEntities.getStorage()
- .enqueueLightUpdateSection(section);
- entities.getStorage()
- .enqueueLightUpdateSection(section);
- effects.getStorage()
- .enqueueLightUpdateSection(section);
- }
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java
index db465f461..d3d065c5c 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java
@@ -69,8 +69,20 @@ public class BlockEntityStorage extends Storage {
@Override
public void remove(BlockEntity obj) {
- super.remove(obj);
posLookup.remove(obj.getBlockPos()
.asLong());
+ super.remove(obj);
+ }
+
+ @Override
+ public void recreateAll(float partialTick) {
+ posLookup.clear();
+ super.recreateAll(partialTick);
+ }
+
+ @Override
+ public void invalidate() {
+ posLookup.clear();
+ super.invalidate();
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java
index e8c0b88c9..f0d3420bb 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java
@@ -54,10 +54,6 @@ public class VisualManagerImpl> implements VisualManager
queue.add(Transaction.update(obj));
}
- public void invalidate() {
- getStorage().invalidate();
- }
-
public void processQueue(float partialTick) {
var storage = getStorage();
Transaction transaction;
@@ -76,13 +72,22 @@ public class VisualManagerImpl> implements VisualManager
.then(storage.tickPlan());
}
- public boolean lightSectionsDirty() {
- return getStorage().smoothLitStorage()
- .sectionsDirty();
+ public void onLightUpdate(long section) {
+ getStorage().lightUpdatedVisuals()
+ .onLightUpdate(section);
}
- public LongSet lightSections() {
- return getStorage().smoothLitStorage()
+ public boolean areGpuLightSectionsDirty() {
+ return getStorage().shaderLightVisuals()
+ .isDirty();
+ }
+
+ public LongSet gpuLightSections() {
+ return getStorage().shaderLightVisuals()
.sections();
}
+
+ public void invalidate() {
+ getStorage().invalidate();
+ }
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LightUpdatedStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LightUpdatedVisualStorage.java
similarity index 74%
rename from common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LightUpdatedStorage.java
rename to common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LightUpdatedVisualStorage.java
index d2df21868..3f730abc0 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LightUpdatedStorage.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LightUpdatedVisualStorage.java
@@ -16,7 +16,6 @@ import dev.engine_room.flywheel.lib.task.SimplyComposedPlan;
import dev.engine_room.flywheel.lib.task.Synchronizer;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
-import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@@ -24,15 +23,15 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
/**
* Keeps track of what chunks/sections each listener is in, so we can update exactly what needs to be updated.
*/
-public class LightUpdatedStorage {
+public class LightUpdatedVisualStorage {
private static final long NEVER_UPDATED = Long.MIN_VALUE;
private static final long INITIAL_UPDATE_ID = NEVER_UPDATED + 1;
- private final Map visuals2Sections = new WeakHashMap<>();
- private final Long2ObjectMap> sections2Visuals = new Long2ObjectOpenHashMap<>();
+ private final Map visual2Sections = new WeakHashMap<>();
+ private final Long2ObjectMap> section2Updaters = new Long2ObjectOpenHashMap<>();
- private final Queue movedVisuals = new ConcurrentLinkedQueue<>();
private final LongSet sectionsUpdatedThisFrame = new LongOpenHashSet();
+ private final Queue movedVisuals = new ConcurrentLinkedQueue<>();
private long updateId = INITIAL_UPDATE_ID;
@@ -54,9 +53,9 @@ public class LightUpdatedStorage {
Updater.Context updaterContext = new Updater.Context(updateId, context.partialTick());
for (long section : sectionsUpdatedThisFrame) {
- var visuals = sections2Visuals.get(section);
- if (visuals != null && !visuals.isEmpty()) {
- taskExecutor.execute(() -> Distribute.tasks(taskExecutor, updaterContext, sync, visuals, Updater::updateLight));
+ var updaters = section2Updaters.get(section);
+ if (updaters != null && !updaters.isEmpty()) {
+ taskExecutor.execute(() -> Distribute.tasks(taskExecutor, updaterContext, sync, updaters, Updater::updateLight));
} else {
sync.decrementAndEventuallyRun();
}
@@ -69,7 +68,7 @@ public class LightUpdatedStorage {
while ((moved = movedVisuals.poll()) != null) {
// If the visual isn't there when we try to remove it that means it was deleted before we got to it.
if (remove(moved.visual)) {
- updateTracking(moved.tracker, moved.visual);
+ addInner(moved.visual, moved.tracker);
}
}
}
@@ -86,43 +85,32 @@ public class LightUpdatedStorage {
return out;
}
- public boolean isEmpty() {
- return visuals2Sections.isEmpty();
- }
-
- public void add(SectionCollectorImpl tracker, LightUpdatedVisual visual) {
- var moved = new MovedVisual(tracker, visual);
+ public void add(LightUpdatedVisual visual, SectionTracker tracker) {
+ var moved = new MovedVisual(visual, tracker);
tracker.addListener(() -> movedVisuals.add(moved));
- updateTracking(tracker, visual);
+ addInner(visual, tracker);
}
- public void updateTracking(SectionCollectorImpl tracker, LightUpdatedVisual visual) {
- if (tracker.sections.isEmpty()) {
+ private void addInner(LightUpdatedVisual visual, SectionTracker tracker) {
+ if (tracker.sections().isEmpty()) {
// Add the visual to the map even if sections is empty, this way we can distinguish from deleted visuals
- visuals2Sections.put(visual, LongSet.of());
+ visual2Sections.put(visual, LongSet.of());
// Don't bother creating an updater if the visual isn't in any sections.
return;
}
- // Create a copy of the array, so we know what section to remove the visual from later.
- var sections = new LongArraySet(tracker.sections);
-
- visuals2Sections.put(visual, sections);
-
+ var sections = tracker.sections();
+ visual2Sections.put(visual, sections);
var updater = createUpdater(visual, sections.size());
for (long section : sections) {
- sections2Visuals.computeIfAbsent(section, $ -> new ObjectArrayList<>())
+ section2Updaters.computeIfAbsent(section, $ -> new ObjectArrayList<>())
.add(updater);
}
}
- public void enqueueLightUpdateSection(long section) {
- sectionsUpdatedThisFrame.add(section);
- }
-
/**
* Remove the visual from this storage.
*
@@ -130,31 +118,36 @@ public class LightUpdatedStorage {
* @return {@code true} if the visual was removed, {@code false} otherwise.
*/
public boolean remove(LightUpdatedVisual visual) {
- var sections = visuals2Sections.remove(visual);
+ var sections = visual2Sections.remove(visual);
if (sections == null) {
return false;
}
for (long section : sections) {
- List listeners = sections2Visuals.get(section);
- if (listeners != null) {
- listeners.remove(indexOfUpdater(listeners, visual));
+ List updaters = section2Updaters.get(section);
+ if (updaters != null) {
+ updaters.remove(indexOfUpdater(updaters, visual));
}
}
return true;
}
- public void clear() {
- visuals2Sections.clear();
- sections2Visuals.clear();
- sectionsUpdatedThisFrame.clear();
+ public void onLightUpdate(long section) {
+ sectionsUpdatedThisFrame.add(section);
}
- private static int indexOfUpdater(List listeners, LightUpdatedVisual visual) {
- for (int i = 0; i < listeners.size(); i++) {
- if (listeners.get(i)
+ public void clear() {
+ visual2Sections.clear();
+ section2Updaters.clear();
+ sectionsUpdatedThisFrame.clear();
+ movedVisuals.clear();
+ }
+
+ private static int indexOfUpdater(List updaters, LightUpdatedVisual visual) {
+ for (int i = 0; i < updaters.size(); i++) {
+ if (updaters.get(i)
.visual() == visual) {
return i;
}
@@ -171,7 +164,7 @@ public class LightUpdatedStorage {
}
// Breaking this into 2 separate cases allows us to avoid the overhead of atomics in the common case.
- sealed interface Updater {
+ private sealed interface Updater {
void updateLight(Context ctx);
LightUpdatedVisual visual();
@@ -201,6 +194,6 @@ public class LightUpdatedStorage {
}
}
- private record MovedVisual(SectionCollectorImpl tracker, LightUpdatedVisual visual) {
+ private record MovedVisual(LightUpdatedVisual visual, SectionTracker tracker) {
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/SectionCollectorImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/SectionTracker.java
similarity index 58%
rename from common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/SectionCollectorImpl.java
rename to common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/SectionTracker.java
index faa1d7b45..9cba32f69 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/SectionCollectorImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/SectionTracker.java
@@ -3,20 +3,27 @@ package dev.engine_room.flywheel.impl.visualization.storage;
import java.util.ArrayList;
import java.util.List;
+import org.jetbrains.annotations.Unmodifiable;
+
import dev.engine_room.flywheel.api.visual.SectionTrackedVisual;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.longs.LongSets;
-public class SectionCollectorImpl implements SectionTrackedVisual.SectionCollector {
- public final LongSet sections = new LongArraySet();
-
+public class SectionTracker implements SectionTrackedVisual.SectionCollector {
private final List listeners = new ArrayList<>(2);
+ @Unmodifiable
+ private LongSet sections = LongSet.of();
+
+ @Unmodifiable
+ public LongSet sections() {
+ return sections;
+ }
+
@Override
public void sections(LongSet sections) {
- this.sections.clear();
- this.sections.addAll(sections);
-
+ this.sections = LongSets.unmodifiable(new LongArraySet(sections));
listeners.forEach(Runnable::run);
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightStorage.java
deleted file mode 100644
index c51a55467..000000000
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightStorage.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package dev.engine_room.flywheel.impl.visualization.storage;
-
-import java.util.Map;
-
-import org.jetbrains.annotations.Nullable;
-
-import dev.engine_room.flywheel.api.visual.ShaderLightVisual;
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
-import it.unimi.dsi.fastutil.longs.LongSet;
-import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
-
-public class ShaderLightStorage {
- private final Map visuals = new Reference2ObjectOpenHashMap<>();
-
- @Nullable
- private LongSet cachedSections;
-
- public boolean sectionsDirty() {
- return cachedSections == null;
- }
-
- public void markDirty() {
- cachedSections = null;
- }
-
- public LongSet sections() {
- cachedSections = new LongOpenHashSet();
- for (var value : visuals.values()) {
- cachedSections.addAll(value.sections);
- }
- return cachedSections;
- }
-
- public void remove(ShaderLightVisual visual) {
- visuals.remove(visual);
- }
-
- public void add(SectionCollectorImpl tracker, ShaderLightVisual visual) {
- visuals.put(visual, tracker);
-
- tracker.addListener(this::markDirty);
-
- if (!tracker.sections.isEmpty()) {
- markDirty();
- }
- }
-
- public void clear() {
- visuals.clear();
- }
-
-}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightVisualStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightVisualStorage.java
new file mode 100644
index 000000000..052a9e06c
--- /dev/null
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/ShaderLightVisualStorage.java
@@ -0,0 +1,53 @@
+package dev.engine_room.flywheel.impl.visualization.storage;
+
+import java.util.Map;
+
+import dev.engine_room.flywheel.api.visual.ShaderLightVisual;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
+
+public class ShaderLightVisualStorage {
+ private final Map trackers = new Reference2ReferenceOpenHashMap<>();
+
+ private final LongSet sections = new LongOpenHashSet();
+ private boolean isDirty;
+
+ public LongSet sections() {
+ if (isDirty) {
+ sections.clear();
+ for (var tracker : trackers.values()) {
+ sections.addAll(tracker.sections());
+ }
+ isDirty = false;
+ }
+ return sections;
+ }
+
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ public void markDirty() {
+ isDirty = true;
+ }
+
+ public void add(ShaderLightVisual visual, SectionTracker tracker) {
+ trackers.put(visual, tracker);
+
+ tracker.addListener(this::markDirty);
+
+ if (!tracker.sections().isEmpty()) {
+ markDirty();
+ }
+ }
+
+ public void remove(ShaderLightVisual visual) {
+ trackers.remove(visual);
+ }
+
+ public void clear() {
+ trackers.clear();
+ markDirty();
+ }
+}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java
index f219e9138..4e2d1ebaf 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java
@@ -25,14 +25,14 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
public abstract class Storage {
protected final Supplier visualizationContextSupplier;
+
+ private final Map visuals = new Reference2ObjectOpenHashMap<>();
protected final PlanMap dynamicVisuals = new PlanMap<>();
protected final PlanMap tickableVisuals = new PlanMap<>();
protected final List simpleDynamicVisuals = new ArrayList<>();
protected final List simpleTickableVisuals = new ArrayList<>();
- protected final LightUpdatedStorage litVisuals = new LightUpdatedStorage();
- protected final ShaderLightStorage smoothLitVisuals = new ShaderLightStorage();
-
- private final Map visuals = new Reference2ObjectOpenHashMap<>();
+ protected final LightUpdatedVisualStorage lightUpdatedVisuals = new LightUpdatedVisualStorage();
+ protected final ShaderLightVisualStorage shaderLightVisuals = new ShaderLightVisualStorage();
public Storage(Supplier visualizationContextSupplier) {
this.visualizationContextSupplier = visualizationContextSupplier;
@@ -42,6 +42,29 @@ public abstract class Storage {
return visuals.values();
}
+ public Plan framePlan() {
+ return NestedPlan.of(dynamicVisuals, lightUpdatedVisuals.plan(), ForEachPlan.of(() -> simpleDynamicVisuals, SimpleDynamicVisual::beginFrame));
+ }
+
+ public Plan tickPlan() {
+ return NestedPlan.of(tickableVisuals, ForEachPlan.of(() -> simpleTickableVisuals, SimpleTickableVisual::tick));
+ }
+
+ public LightUpdatedVisualStorage lightUpdatedVisuals() {
+ return lightUpdatedVisuals;
+ }
+
+ public ShaderLightVisualStorage shaderLightVisuals() {
+ return shaderLightVisuals;
+ }
+
+ /**
+ * Is the given object currently capable of being added?
+ *
+ * @return true if the object is currently capable of being visualized.
+ */
+ public abstract boolean willAccept(T obj);
+
public void add(T obj, float partialTick) {
Visual visual = visuals.get(obj);
@@ -57,13 +80,6 @@ public abstract class Storage {
return;
}
- if (visual instanceof TickableVisual tickable) {
- if (visual instanceof SimpleTickableVisual simpleTickable) {
- simpleTickableVisuals.remove(simpleTickable);
- } else {
- tickableVisuals.remove(tickable);
- }
- }
if (visual instanceof DynamicVisual dynamic) {
if (visual instanceof SimpleDynamicVisual simpleDynamic) {
simpleDynamicVisuals.remove(simpleDynamic);
@@ -71,12 +87,20 @@ public abstract class Storage {
dynamicVisuals.remove(dynamic);
}
}
- if (visual instanceof LightUpdatedVisual lit) {
- litVisuals.remove(lit);
+ if (visual instanceof TickableVisual tickable) {
+ if (visual instanceof SimpleTickableVisual simpleTickable) {
+ simpleTickableVisuals.remove(simpleTickable);
+ } else {
+ tickableVisuals.remove(tickable);
+ }
}
- if (visual instanceof ShaderLightVisual smoothLit) {
- smoothLitVisuals.remove(smoothLit);
+ if (visual instanceof LightUpdatedVisual lightUpdated) {
+ lightUpdatedVisuals.remove(lightUpdated);
}
+ if (visual instanceof ShaderLightVisual shaderLight) {
+ shaderLightVisuals.remove(shaderLight);
+ }
+
visual.delete();
}
@@ -91,12 +115,13 @@ public abstract class Storage {
}
public void recreateAll(float partialTick) {
- tickableVisuals.clear();
dynamicVisuals.clear();
- simpleTickableVisuals.clear();
+ tickableVisuals.clear();
simpleDynamicVisuals.clear();
- litVisuals.clear();
- smoothLitVisuals.clear();
+ simpleTickableVisuals.clear();
+ lightUpdatedVisuals.clear();
+ shaderLightVisuals.clear();
+
visuals.replaceAll((obj, visual) -> {
visual.delete();
@@ -110,15 +135,6 @@ public abstract class Storage {
});
}
- public void invalidate() {
- tickableVisuals.clear();
- dynamicVisuals.clear();
- litVisuals.clear();
- visuals.values()
- .forEach(Visual::delete);
- visuals.clear();
- }
-
private void create(T obj, float partialTick) {
var visual = createRaw(obj, partialTick);
@@ -131,27 +147,7 @@ public abstract class Storage {
@Nullable
protected abstract Visual createRaw(T obj, float partialTick);
- public Plan framePlan() {
- return NestedPlan.of(dynamicVisuals, litVisuals.plan(), ForEachPlan.of(() -> simpleDynamicVisuals, SimpleDynamicVisual::beginFrame));
- }
-
- public Plan tickPlan() {
- return NestedPlan.of(tickableVisuals, ForEachPlan.of(() -> simpleTickableVisuals, SimpleTickableVisual::tick));
- }
-
- public void enqueueLightUpdateSection(long section) {
- litVisuals.enqueueLightUpdateSection(section);
- }
-
private void setup(Visual visual) {
- if (visual instanceof TickableVisual tickable) {
- if (visual instanceof SimpleTickableVisual simpleTickable) {
- simpleTickableVisuals.add(simpleTickable);
- } else {
- tickableVisuals.add(tickable, tickable.planTick());
- }
- }
-
if (visual instanceof DynamicVisual dynamic) {
if (visual instanceof SimpleDynamicVisual simpleDynamic) {
simpleDynamicVisuals.add(simpleDynamic);
@@ -160,30 +156,39 @@ public abstract class Storage {
}
}
- if (visual instanceof SectionTrackedVisual tracked) {
- SectionCollectorImpl sectionProperty = new SectionCollectorImpl();
+ if (visual instanceof TickableVisual tickable) {
+ if (visual instanceof SimpleTickableVisual simpleTickable) {
+ simpleTickableVisuals.add(simpleTickable);
+ } else {
+ tickableVisuals.add(tickable, tickable.planTick());
+ }
+ }
- // Give the visual a chance to fill in the property.
- tracked.setSectionCollector(sectionProperty);
+ if (visual instanceof SectionTrackedVisual tracked) {
+ SectionTracker tracker = new SectionTracker();
+
+ // Give the visual a chance to invoke the collector.
+ tracked.setSectionCollector(tracker);
if (visual instanceof LightUpdatedVisual lightUpdated) {
- litVisuals.add(sectionProperty, lightUpdated);
+ lightUpdatedVisuals.add(lightUpdated, tracker);
}
if (visual instanceof ShaderLightVisual shaderLight) {
- smoothLitVisuals.add(sectionProperty, shaderLight);
+ shaderLightVisuals.add(shaderLight, tracker);
}
}
}
- /**
- * Is the given object currently capable of being added?
- *
- * @return true if the object is currently capable of being visualized.
- */
- public abstract boolean willAccept(T obj);
-
- public ShaderLightStorage smoothLitStorage() {
- return smoothLitVisuals;
+ public void invalidate() {
+ dynamicVisuals.clear();
+ tickableVisuals.clear();
+ simpleDynamicVisuals.clear();
+ simpleTickableVisuals.clear();
+ lightUpdatedVisuals.clear();
+ shaderLightVisuals.clear();
+ visuals.values()
+ .forEach(Visual::delete);
+ visuals.clear();
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java
index b0a72f0a7..873ff2bce 100644
--- a/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java
+++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java
@@ -194,7 +194,7 @@ public class MinecartVisual extends SimpleEntityVisu
body.setTransform(stack)
.setChanged();
- // TODO: Use LitVisual if possible.
+ // TODO: Use LightUpdatedVisual/ShaderLightVisual if possible.
updateLight(partialTick);
}