diff --git a/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java b/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java
index a4ddc163c..ed14b4dbb 100644
--- a/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java
+++ b/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java
@@ -6,13 +6,9 @@ import com.jozufozu.flywheel.api.BackendImplemented;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
-import com.jozufozu.flywheel.api.instance.InstanceType;
-import com.jozufozu.flywheel.api.instance.Instancer;
-import com.jozufozu.flywheel.api.instance.InstancerProvider;
-import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.task.Plan;
import com.jozufozu.flywheel.api.task.TaskExecutor;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
+import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
@@ -21,20 +17,12 @@ import net.minecraft.core.Vec3i;
@BackendImplemented
public interface Engine {
/**
- * Get an instancer for the given instance type, model, and render stage.
+ * Create a visualization context that will render to the given stage.
*
- *
Calling this method twice with the same arguments will return the same instancer.
- *
- * If you are writing a visual you should probably be using
- * {@link InstancerProvider#instancer(InstanceType, Model)}, which will decide the {@code RenderStage}
- * based on what type of visual is getting the instancer.
- *
- * @return An instancer for the given instance type, model, and render stage.
- * @see InstancerProvider
+ * @param stage The stage to render to.
+ * @return A new visualization context.
*/
- Instancer instancer(InstanceType type, Model model, RenderStage stage);
-
- Instancer instancer(VisualEmbedding world, InstanceType type, Model model, RenderStage stage);
+ VisualizationContext createVisualizationContext(RenderStage stage);
/**
* Create a plan that will be executed every frame.
diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java
index 4c4ddf92b..07d641c92 100644
--- a/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java
+++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java
@@ -1,10 +1,9 @@
package com.jozufozu.flywheel.api.instance;
-import org.jetbrains.annotations.ApiStatus;
-
+import com.jozufozu.flywheel.api.BackendImplemented;
import com.jozufozu.flywheel.api.model.Model;
-@ApiStatus.NonExtendable
+@BackendImplemented
public interface InstancerProvider {
/**
* Get an instancer for the given instance type rendering the given model.
diff --git a/src/main/java/com/jozufozu/flywheel/api/visualization/VisualEmbedding.java b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualEmbedding.java
index c308a8003..fe75a0d43 100644
--- a/src/main/java/com/jozufozu/flywheel/api/visualization/VisualEmbedding.java
+++ b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualEmbedding.java
@@ -3,12 +3,15 @@ package com.jozufozu.flywheel.api.visualization;
import org.joml.Matrix3fc;
import org.joml.Matrix4fc;
-import net.minecraft.world.phys.AABB;
+import com.jozufozu.flywheel.api.BackendImplemented;
-public interface VisualEmbedding {
- Matrix4fc pose();
-
- Matrix3fc normal();
-
- AABB boundingBox();
+@BackendImplemented
+public interface VisualEmbedding extends VisualizationContext {
+ /**
+ * Set the transformation matrices for the embedding.
+ *
+ * @param pose The model matrix.
+ * @param normal The normal matrix.
+ */
+ void transforms(Matrix4fc pose, Matrix3fc normal);
}
diff --git a/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java
index f8a74775c..88935dd13 100644
--- a/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java
+++ b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java
@@ -2,6 +2,7 @@ package com.jozufozu.flywheel.api.visualization;
import org.jetbrains.annotations.ApiStatus;
+import com.jozufozu.flywheel.api.BackendImplemented;
import com.jozufozu.flywheel.api.instance.InstancerProvider;
import net.minecraft.core.Vec3i;
@@ -9,7 +10,7 @@ import net.minecraft.core.Vec3i;
/**
* A context object passed on visual creation.
*/
-@ApiStatus.NonExtendable
+@BackendImplemented
public interface VisualizationContext {
/**
* @return The {@link InstancerProvider} that the visual can use to get instancers to render models.
@@ -24,5 +25,5 @@ public interface VisualizationContext {
Vec3i renderOrigin();
@ApiStatus.Experimental
- VisualizationContext embed(VisualEmbedding world);
+ VisualEmbedding createEmbedding();
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java
index e8e31a641..219b52f56 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java
@@ -5,8 +5,10 @@ import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
+import com.jozufozu.flywheel.api.instance.InstancerProvider;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
+import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
@@ -21,14 +23,13 @@ public abstract class AbstractEngine implements Engine {
sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance;
}
- @Override
- public Instancer instancer(InstanceType type, Model model, RenderStage stage) {
- return getStorage().getInstancer(null, type, model, stage);
+ public Instancer instancer(Environment environment, InstanceType type, Model model, RenderStage stage) {
+ return getStorage().getInstancer(environment, type, model, stage);
}
@Override
- public Instancer instancer(VisualEmbedding world, InstanceType type, Model model, RenderStage stage) {
- return getStorage().getInstancer(world, type, model, stage);
+ public VisualizationContext createVisualizationContext(RenderStage stage) {
+ return new VisualizationContextImpl(stage);
}
@Override
@@ -54,4 +55,29 @@ public abstract class AbstractEngine implements Engine {
}
protected abstract InstancerStorage extends AbstractInstancer>> getStorage();
+
+ private class VisualizationContextImpl implements VisualizationContext {
+ private final InstancerProviderImpl instancerProvider;
+ private final RenderStage stage;
+
+ public VisualizationContextImpl(RenderStage stage) {
+ instancerProvider = new InstancerProviderImpl(AbstractEngine.this, stage);
+ this.stage = stage;
+ }
+
+ @Override
+ public InstancerProvider instancerProvider() {
+ return instancerProvider;
+ }
+
+ @Override
+ public Vec3i renderOrigin() {
+ return AbstractEngine.this.renderOrigin();
+ }
+
+ @Override
+ public VisualEmbedding createEmbedding() {
+ return new EmbeddedEnvironment(AbstractEngine.this, stage);
+ }
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java
index 6e81b6e26..ad0c6ac1f 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java
@@ -7,13 +7,11 @@ import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
import com.jozufozu.flywheel.lib.util.AtomicBitset;
public abstract class AbstractInstancer implements Instancer {
public final InstanceType type;
- @Nullable
- public final VisualEmbedding embedding;
+ public final Environment environment;
// Lock for all instances, only needs to be used in methods that may run on the TaskExecutor.
protected final Object lock = new Object();
@@ -23,9 +21,9 @@ public abstract class AbstractInstancer implements Instancer
protected final AtomicBitset changed = new AtomicBitset();
protected final AtomicBitset deleted = new AtomicBitset();
- protected AbstractInstancer(InstanceType type, @Nullable VisualEmbedding embedding) {
+ protected AbstractInstancer(InstanceType type, Environment environment) {
this.type = type;
- this.embedding = embedding;
+ this.environment = environment;
}
@Override
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/EmbeddedEnvironment.java b/src/main/java/com/jozufozu/flywheel/backend/engine/EmbeddedEnvironment.java
new file mode 100644
index 000000000..9256dd0ab
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/EmbeddedEnvironment.java
@@ -0,0 +1,81 @@
+package com.jozufozu.flywheel.backend.engine;
+
+import org.joml.Matrix3f;
+import org.joml.Matrix3fc;
+import org.joml.Matrix4f;
+import org.joml.Matrix4fc;
+
+import com.jozufozu.flywheel.api.event.RenderStage;
+import com.jozufozu.flywheel.api.instance.Instance;
+import com.jozufozu.flywheel.api.instance.InstanceType;
+import com.jozufozu.flywheel.api.instance.Instancer;
+import com.jozufozu.flywheel.api.instance.InstancerProvider;
+import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
+import com.jozufozu.flywheel.backend.compile.ContextShader;
+import com.jozufozu.flywheel.backend.compile.ContextShaders;
+import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
+
+import net.minecraft.core.Vec3i;
+
+public class EmbeddedEnvironment implements Environment, VisualEmbedding {
+ private final Matrix4f pose = new Matrix4f();
+ private final Matrix3f normal = new Matrix3f();
+
+ private final InstancerProvider instancerProvider;
+ private final AbstractEngine engine;
+ private final RenderStage renderStage;
+
+ public EmbeddedEnvironment(AbstractEngine engine, RenderStage renderStage) {
+ this.engine = engine;
+ this.renderStage = renderStage;
+
+ 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(EmbeddedEnvironment.this, type, model, renderStage);
+ }
+ };
+ }
+
+ @Override
+ public void transforms(Matrix4fc pose, Matrix3fc normal) {
+ this.pose.set(pose);
+ this.normal.set(normal);
+ }
+
+ @Override
+ public ContextShader contextShader() {
+ return ContextShaders.EMBEDDED;
+ }
+
+ @Override
+ public void setupDraw(GlProgram drawProgram) {
+ drawProgram.setVec3("_flw_oneOverLightBoxSize", 1, 1, 1);
+ drawProgram.setVec3("_flw_lightVolumeMin", 0, 0, 0);
+ drawProgram.setMat4("_flw_model", pose);
+ drawProgram.setMat3("_flw_normal", normal);
+ }
+
+ @Override
+ public void setupCull(GlProgram cullProgram) {
+ cullProgram.setBool("_flw_useEmbeddedModel", true);
+ cullProgram.setMat4("_flw_embeddedModel", pose);
+ }
+
+ @Override
+ public InstancerProvider instancerProvider() {
+ return instancerProvider;
+ }
+
+ @Override
+ public Vec3i renderOrigin() {
+ return Vec3i.ZERO;
+ }
+
+ @Override
+ public VisualEmbedding createEmbedding() {
+ return new EmbeddedEnvironment(engine, renderStage);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/Environment.java b/src/main/java/com/jozufozu/flywheel/backend/engine/Environment.java
new file mode 100644
index 000000000..6b3614e6e
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/Environment.java
@@ -0,0 +1,12 @@
+package com.jozufozu.flywheel.backend.engine;
+
+import com.jozufozu.flywheel.backend.compile.ContextShader;
+import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
+
+public interface Environment {
+ ContextShader contextShader();
+
+ void setupDraw(GlProgram drawProgram);
+
+ void setupCull(GlProgram cullProgram);
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/GlobalEnvironment.java b/src/main/java/com/jozufozu/flywheel/backend/engine/GlobalEnvironment.java
new file mode 100644
index 000000000..f1c909bcd
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/GlobalEnvironment.java
@@ -0,0 +1,27 @@
+package com.jozufozu.flywheel.backend.engine;
+
+import com.jozufozu.flywheel.backend.compile.ContextShader;
+import com.jozufozu.flywheel.backend.compile.ContextShaders;
+import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
+
+public class GlobalEnvironment implements Environment {
+ public static final GlobalEnvironment INSTANCE = new GlobalEnvironment();
+
+ private GlobalEnvironment() {
+ }
+
+ @Override
+ public ContextShader contextShader() {
+ return ContextShaders.DEFAULT;
+ }
+
+ @Override
+ public void setupDraw(GlProgram drawProgram) {
+
+ }
+
+ @Override
+ public void setupCull(GlProgram cullProgram) {
+ cullProgram.setBool("_flw_useEmbeddedModel", false);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java
index 3bb410c63..ecb240dce 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java
@@ -1,13 +1,10 @@
package com.jozufozu.flywheel.backend.engine;
-import org.jetbrains.annotations.Nullable;
-
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.model.Model;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
-public record InstancerKey(@Nullable VisualEmbedding embedding, InstanceType type, Model model,
+public record InstancerKey(Environment environment, InstanceType type, Model model,
RenderStage stage) {
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerProviderImpl.java b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerProviderImpl.java
new file mode 100644
index 000000000..e3894d308
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerProviderImpl.java
@@ -0,0 +1,15 @@
+package com.jozufozu.flywheel.backend.engine;
+
+import com.jozufozu.flywheel.api.event.RenderStage;
+import com.jozufozu.flywheel.api.instance.Instance;
+import com.jozufozu.flywheel.api.instance.InstanceType;
+import com.jozufozu.flywheel.api.instance.Instancer;
+import com.jozufozu.flywheel.api.instance.InstancerProvider;
+import com.jozufozu.flywheel.api.model.Model;
+
+public record InstancerProviderImpl(AbstractEngine engine, RenderStage renderStage) implements InstancerProvider {
+ @Override
+ public Instancer instancer(InstanceType type, Model model) {
+ return engine.instancer(GlobalEnvironment.INSTANCE, type, model, renderStage);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerStorage.java b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerStorage.java
index f969df8e2..939cc42b5 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerStorage.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerStorage.java
@@ -5,15 +5,12 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.jetbrains.annotations.Nullable;
-
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
import com.jozufozu.flywheel.api.model.Model;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
public abstract class InstancerStorage> {
/**
@@ -30,8 +27,8 @@ public abstract class InstancerStorage> {
protected final List> initializationQueue = new ArrayList<>();
@SuppressWarnings("unchecked")
- public Instancer getInstancer(@Nullable VisualEmbedding level, InstanceType type, Model model, RenderStage stage) {
- return (Instancer) instancers.computeIfAbsent(new InstancerKey<>(level, type, model, stage), this::createAndDeferInit);
+ public Instancer getInstancer(Environment environment, InstanceType type, Model model, RenderStage stage) {
+ return (Instancer) instancers.computeIfAbsent(new InstancerKey<>(environment, type, model, stage), this::createAndDeferInit);
}
public void delete() {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java
index 5acefaeac..5d08a189e 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java
@@ -16,17 +16,14 @@ import java.util.EnumMap;
import java.util.List;
import java.util.Map;
-import org.jetbrains.annotations.Nullable;
-
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.model.Model;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
import com.jozufozu.flywheel.backend.compile.ContextShader;
-import com.jozufozu.flywheel.backend.compile.ContextShaders;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
+import com.jozufozu.flywheel.backend.engine.Environment;
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
import com.jozufozu.flywheel.backend.engine.MeshPool;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
@@ -41,8 +38,7 @@ public class IndirectCullingGroup {
private static final int DRAW_BARRIER_BITS = GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT;
private final InstanceType instanceType;
- @Nullable
- private final VisualEmbedding embedding;
+ private final Environment environment;
private final long objectStride;
private final IndirectBuffers buffers;
private final List> instancers = new ArrayList<>();
@@ -58,9 +54,9 @@ public class IndirectCullingGroup {
private boolean needsDrawSort;
private int instanceCountThisFrame;
- IndirectCullingGroup(InstanceType instanceType, @Nullable VisualEmbedding embedding, IndirectPrograms programs) {
+ IndirectCullingGroup(InstanceType instanceType, Environment environment, IndirectPrograms programs) {
this.instanceType = instanceType;
- this.embedding = embedding;
+ this.environment = environment;
objectStride = instanceType.layout()
.byteSize() + IndirectBuffers.INT_SIZE;
buffers = new IndirectBuffers(objectStride);
@@ -68,7 +64,7 @@ public class IndirectCullingGroup {
this.programs = programs;
cullProgram = programs.getCullingProgram(instanceType);
applyProgram = programs.getApplyProgram();
- drawProgram = programs.getIndirectProgram(instanceType, ContextShaders.forEmbedding(embedding));
+ drawProgram = programs.getIndirectProgram(instanceType, environment.contextShader());
}
public void flushInstancers() {
@@ -130,12 +126,7 @@ public class IndirectCullingGroup {
Uniforms.bindFrame();
cullProgram.bind();
- if (embedding != null) {
- cullProgram.setBool("_flw_useEmbeddedModel", true);
- cullProgram.setMat4("_flw_embeddedModel", embedding.pose());
- } else {
- cullProgram.setBool("_flw_useEmbeddedModel", false);
- }
+ environment.setupCull(cullProgram);
buffers.bindForCompute();
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
@@ -208,12 +199,7 @@ public class IndirectCullingGroup {
drawProgram.bind();
buffers.bindForDraw();
- if (embedding != null) {
- drawProgram.setVec3("_flw_oneOverLightBoxSize", 1, 1, 1);
- drawProgram.setVec3("_flw_lightVolumeMin", 0, 0, 0);
- drawProgram.setMat4("_flw_model", embedding.pose());
- drawProgram.setMat3("_flw_normal", embedding.normal());
- }
+ environment.setupDraw(drawProgram);
drawBarrier();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java
index 1866f817b..c507ef39e 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java
@@ -11,16 +11,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.jetbrains.annotations.Nullable;
-
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
import com.jozufozu.flywheel.backend.compile.ContextShaders;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
+import com.jozufozu.flywheel.backend.engine.Environment;
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
@@ -62,14 +60,14 @@ public class IndirectDrawManager extends InstancerStorage>
@Override
protected IndirectInstancer> create(InstancerKey key) {
- return new IndirectInstancer<>(key.type(), key.embedding(), key.model());
+ return new IndirectInstancer<>(key.type(), key.environment(), key.model());
}
@SuppressWarnings("unchecked")
@Override
protected void initialize(InstancerKey key, IndirectInstancer> instancer) {
- var groupKey = new GroupKey<>(key.type(), key.embedding());
- var group = (IndirectCullingGroup) cullingGroups.computeIfAbsent(groupKey, t -> new IndirectCullingGroup<>(t.type, t.context, programs));
+ var groupKey = new GroupKey<>(key.type(), key.environment());
+ var group = (IndirectCullingGroup) cullingGroups.computeIfAbsent(groupKey, t -> new IndirectCullingGroup<>(t.type, t.environment, programs));
group.add((IndirectInstancer) instancer, key.model(), key.stage(), meshPool);
}
@@ -224,7 +222,7 @@ public class IndirectDrawManager extends InstancerStorage>
continue;
}
- byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.embedding), $ -> new Int2ObjectArrayMap<>())
+ byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.environment), $ -> new Int2ObjectArrayMap<>())
.computeIfAbsent(progress, $ -> new ArrayList<>())
.add(Pair.of(instancer, impl));
}
@@ -232,6 +230,6 @@ public class IndirectDrawManager extends InstancerStorage>
return byType;
}
- public record GroupKey(InstanceType type, @Nullable VisualEmbedding context) {
+ public record GroupKey(InstanceType type, Environment environment) {
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java
index 22ed21e5e..88362d85e 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java
@@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.engine.indirect;
import java.util.ArrayList;
import java.util.List;
-import org.jetbrains.annotations.Nullable;
import org.joml.Vector4fc;
import org.lwjgl.system.MemoryUtil;
@@ -11,8 +10,8 @@ import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.InstanceWriter;
import com.jozufozu.flywheel.api.model.Model;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
+import com.jozufozu.flywheel.backend.engine.Environment;
public class IndirectInstancer extends AbstractInstancer {
private final long objectStride;
@@ -26,8 +25,8 @@ public class IndirectInstancer extends AbstractInstancer
private int lastModelIndex = -1;
private long lastStartPos = -1;
- public IndirectInstancer(InstanceType type, @Nullable VisualEmbedding context, Model model) {
- super(type, context);
+ public IndirectInstancer(InstanceType type, Environment environment, Model model) {
+ super(type, environment);
this.objectStride = type.layout()
.byteSize() + IndirectBuffers.INT_SIZE;
writer = this.type.writer();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java
index be8600e31..3f0192921 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedDrawManager.java
@@ -130,12 +130,14 @@ public class InstancedDrawManager extends InstancerStorage
continue;
}
- var embedding = shader.embedding();
+ var environment = shader.environment();
var material = shader.material();
- var program = programs.get(shader.instanceType(), ContextShaders.forEmbedding(embedding));
+ var program = programs.get(shader.instanceType(), environment.contextShader());
program.bind();
+ environment.setupDraw(program);
+
uploadMaterialUniform(program, material);
MaterialRenderState.setup(material);
@@ -153,7 +155,7 @@ public class InstancedDrawManager extends InstancerStorage
@Override
protected InstancedInstancer create(InstancerKey key) {
- return new InstancedInstancer<>(key.type(), key.embedding());
+ return new InstancedInstancer<>(key.type(), key.environment());
}
@Override
@@ -167,7 +169,7 @@ public class InstancedDrawManager extends InstancerStorage
for (var entry : meshes) {
var mesh = meshPool.alloc(entry.mesh());
- ShaderState shaderState = new ShaderState(entry.material(), key.type(), key.embedding());
+ ShaderState shaderState = new ShaderState(entry.material(), key.type(), key.environment());
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
drawSet.put(shaderState, drawCall);
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java
index 1682a7011..85684ed92 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java
@@ -8,8 +8,8 @@ import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.InstanceWriter;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
+import com.jozufozu.flywheel.backend.engine.Environment;
import com.jozufozu.flywheel.backend.gl.TextureBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
@@ -25,8 +25,8 @@ public class InstancedInstancer extends AbstractInstancer
private final List drawCalls = new ArrayList<>();
- public InstancedInstancer(InstanceType type, @Nullable VisualEmbedding context) {
- super(type, context);
+ public InstancedInstancer(InstanceType type, Environment environment) {
+ super(type, environment);
var layout = type.layout();
// Align to one texel in the texture buffer
instanceStride = MoreMath.align16(layout.byteSize());
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java
index e70b6fb28..420fb7005 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java
@@ -1,10 +1,8 @@
package com.jozufozu.flywheel.backend.engine.instancing;
-import org.jetbrains.annotations.Nullable;
-
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.material.Material;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
+import com.jozufozu.flywheel.backend.engine.Environment;
-public record ShaderState(Material material, InstanceType> instanceType, @Nullable VisualEmbedding embedding) {
+public record ShaderState(Material material, InstanceType> instanceType, Environment environment) {
}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/InstancerProviderImpl.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/InstancerProviderImpl.java
deleted file mode 100644
index 2addd894d..000000000
--- a/src/main/java/com/jozufozu/flywheel/impl/visualization/InstancerProviderImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.jozufozu.flywheel.impl.visualization;
-
-import java.util.function.Supplier;
-
-import com.jozufozu.flywheel.api.backend.Engine;
-import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instance.Instance;
-import com.jozufozu.flywheel.api.instance.InstanceType;
-import com.jozufozu.flywheel.api.instance.Instancer;
-import com.jozufozu.flywheel.api.instance.InstancerProvider;
-import com.jozufozu.flywheel.api.model.Model;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
-import com.jozufozu.flywheel.api.visualization.VisualizationContext;
-
-public class InstancerProviderImpl implements InstancerProvider, Supplier {
- protected final Engine engine;
- protected final RenderStage renderStage;
-
- public InstancerProviderImpl(Engine engine, RenderStage renderStage) {
- this.engine = engine;
- this.renderStage = renderStage;
- }
-
- @Override
- public Instancer instancer(InstanceType type, Model model) {
- return engine.instancer(type, model, renderStage);
- }
-
- @Override
- public VisualizationContext get() {
- return new VisualizationContextImpl(this, engine.renderOrigin());
- }
-
- public Embedded embed(VisualEmbedding world) {
- return new Embedded(engine, world, renderStage);
- }
-
- @Override
- public String toString() {
- return "InstancerProviderImpl[" + "engine=" + engine + ", " + "renderStage=" + renderStage + ']';
- }
-
- public static final class Embedded extends InstancerProviderImpl {
- private final VisualEmbedding world;
-
- public Embedded(Engine engine, VisualEmbedding world, RenderStage renderStage) {
- super(engine, renderStage);
- this.world = world;
- }
-
- @Override
- public Instancer instancer(InstanceType type, Model model) {
- return engine.instancer(world, type, model, renderStage);
- }
-
- public VisualEmbedding world() {
- return world;
- }
-
- @Override
- public String toString() {
- return "InstancerProviderImpl.EmbeddedImpl[" + "world=" + world + ", " + "engine=" + engine + ", " + "renderStage=" + renderStage + ']';
- }
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationContextImpl.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationContextImpl.java
deleted file mode 100644
index d2a202212..000000000
--- a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationContextImpl.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.jozufozu.flywheel.impl.visualization;
-
-import com.jozufozu.flywheel.api.instance.InstancerProvider;
-import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
-import com.jozufozu.flywheel.api.visualization.VisualizationContext;
-
-import net.minecraft.core.Vec3i;
-
-/**
- * A context object passed on visual creation.
- *
- * @param instancerProvider The {@link InstancerProvider} that the visual can use to get instancers to render models.
- * @param renderOrigin The origin of the renderer as a world position.
- * All models render as if this position is (0, 0, 0).
- */
-public record VisualizationContextImpl(InstancerProviderImpl instancerProvider, Vec3i renderOrigin) implements VisualizationContext {
- @Override
- public VisualizationContext embed(VisualEmbedding world) {
- return new VisualizationContextImpl(instancerProvider.embed(world), renderOrigin);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationManagerImpl.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationManagerImpl.java
index e06ec0f8f..c90389c6d 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationManagerImpl.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationManagerImpl.java
@@ -3,6 +3,7 @@ package com.jozufozu.flywheel.impl.visualization;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
+import java.util.function.Supplier;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
@@ -22,6 +23,7 @@ import com.jozufozu.flywheel.api.visual.TickableVisual;
import com.jozufozu.flywheel.api.visual.VisualFrameContext;
import com.jozufozu.flywheel.api.visual.VisualTickContext;
import com.jozufozu.flywheel.api.visualization.VisualManager;
+import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationLevel;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.config.FlwConfig;
@@ -84,9 +86,9 @@ public class VisualizationManagerImpl implements VisualizationManager {
.createEngine(level);
taskExecutor = FlwTaskExecutor.get();
- var blockEntitiesStorage = new BlockEntityStorage(new InstancerProviderImpl(engine, RenderStage.AFTER_BLOCK_ENTITIES));
- var entitiesStorage = new EntityStorage(new InstancerProviderImpl(engine, RenderStage.AFTER_ENTITIES));
- var effectsStorage = new EffectStorage(new InstancerProviderImpl(engine, RenderStage.AFTER_PARTICLES));
+ var blockEntitiesStorage = new BlockEntityStorage(provider(engine, RenderStage.AFTER_BLOCK_ENTITIES));
+ var entitiesStorage = new EntityStorage(provider(engine, RenderStage.AFTER_ENTITIES));
+ var effectsStorage = new EffectStorage(provider(engine, RenderStage.AFTER_PARTICLES));
blockEntities = new VisualManagerImpl<>(blockEntitiesStorage);
entities = new VisualManagerImpl<>(entitiesStorage);
@@ -118,6 +120,11 @@ public class VisualizationManagerImpl implements VisualizationManager {
}
}
+ public static Supplier provider(Engine engine, RenderStage stage) {
+ var context = engine.createVisualizationContext(stage);
+ return () -> context;
+ }
+
private VisualFrameContext createVisualFrameContext(RenderContext ctx) {
Vec3i renderOrigin = engine.renderOrigin();
var cameraPos = ctx.camera()