mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-18 17:07:52 +01:00
Stay inline
- Inline all unnecessary context stuff - Move ContextShaders into backend.compile - Instancers are parameterized by a nullable VisualEmbedding - I don't like this, but the code currently compiles, so I want a checkpoint before I try my next idea
This commit is contained in:
parent
e55d506511
commit
2c3b4c54ca
35 changed files with 159 additions and 369 deletions
|
@ -11,7 +11,6 @@ import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||||
import com.jozufozu.flywheel.backend.Backends;
|
import com.jozufozu.flywheel.backend.Backends;
|
||||||
import com.jozufozu.flywheel.backend.ShaderIndices;
|
import com.jozufozu.flywheel.backend.ShaderIndices;
|
||||||
import com.jozufozu.flywheel.backend.compile.FlwPrograms;
|
import com.jozufozu.flywheel.backend.compile.FlwPrograms;
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShaders;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.config.BackendArgument;
|
import com.jozufozu.flywheel.config.BackendArgument;
|
||||||
import com.jozufozu.flywheel.config.FlwCommands;
|
import com.jozufozu.flywheel.config.FlwCommands;
|
||||||
|
@ -128,7 +127,6 @@ public class Flywheel {
|
||||||
CutoutShaders.init();
|
CutoutShaders.init();
|
||||||
FogShaders.init();
|
FogShaders.init();
|
||||||
StandardMaterialShaders.init();
|
StandardMaterialShaders.init();
|
||||||
ContextShaders.init();
|
|
||||||
|
|
||||||
ShaderIndices.init();
|
ShaderIndices.init();
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.api.task.Plan;
|
import com.jozufozu.flywheel.api.task.Plan;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -34,7 +34,7 @@ public interface Engine {
|
||||||
*/
|
*/
|
||||||
<I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage);
|
<I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage);
|
||||||
|
|
||||||
<I extends Instance> Instancer<I> instancer(EmbeddedLevel world, InstanceType<I> type, Model model, RenderStage stage);
|
<I extends Instance> Instancer<I> instancer(VisualEmbedding world, InstanceType<I> type, Model model, RenderStage stage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a plan that will be executed every frame.
|
* Create a plan that will be executed every frame.
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.jozufozu.flywheel.api.visualization;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
|
|
||||||
public interface EmbeddedLevel {
|
|
||||||
void transform(PoseStack stack);
|
|
||||||
|
|
||||||
AABB boundingBox();
|
|
||||||
}
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.jozufozu.flywheel.api.visualization;
|
||||||
|
|
||||||
|
import org.joml.Matrix3fc;
|
||||||
|
import org.joml.Matrix4fc;
|
||||||
|
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
|
public interface VisualEmbedding {
|
||||||
|
Matrix4fc pose();
|
||||||
|
|
||||||
|
Matrix3fc normal();
|
||||||
|
|
||||||
|
AABB boundingBox();
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package com.jozufozu.flywheel.api.visualization;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
|
||||||
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
|
||||||
|
@ -24,13 +23,6 @@ public interface VisualizationContext {
|
||||||
*/
|
*/
|
||||||
Vec3i renderOrigin();
|
Vec3i renderOrigin();
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link VisualizationContext} with the given {@link Context} and render origin.
|
|
||||||
*
|
|
||||||
* @param context The new context.
|
|
||||||
* @param renderOrigin The new render origin.
|
|
||||||
* @return A new {@link VisualizationContext} for use with child visuals.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
VisualizationContext embed(EmbeddedLevel world);
|
VisualizationContext embed(VisualEmbedding world);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.jozufozu.flywheel.backend.compile;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
public record ContextShader(ResourceLocation vertexShader, ResourceLocation fragmentShader) {
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.jozufozu.flywheel.backend.compile;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
|
import com.jozufozu.flywheel.api.internal.InternalFlywheelApi;
|
||||||
|
import com.jozufozu.flywheel.api.registry.Registry;
|
||||||
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
|
|
||||||
|
public class ContextShaders {
|
||||||
|
public static final Registry<ContextShader> REGISTRY = InternalFlywheelApi.INSTANCE.createRegistry();
|
||||||
|
public static final ContextShader DEFAULT = REGISTRY.registerAndGet(new ContextShader(Flywheel.rl("internal/context/default.vert"), Flywheel.rl("internal/context/default.frag")));
|
||||||
|
public static final ContextShader CRUMBLING = REGISTRY.registerAndGet(new ContextShader(Flywheel.rl("internal/context/crumbling.vert"), Flywheel.rl("internal/context/crumbling.frag")));
|
||||||
|
public static final ContextShader EMBEDDED = REGISTRY.registerAndGet(new ContextShader(Flywheel.rl("internal/context/embedded.vert"), Flywheel.rl("internal/context/embedded.frag")));
|
||||||
|
|
||||||
|
public static ContextShader forEmbedding(@Nullable VisualEmbedding level) {
|
||||||
|
if (level == null) {
|
||||||
|
return DEFAULT;
|
||||||
|
} else {
|
||||||
|
return EMBEDDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,6 @@ import com.jozufozu.flywheel.backend.ShaderIndices;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
|
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
|
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
|
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShader;
|
|
||||||
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
||||||
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;
|
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;
|
||||||
|
@ -58,7 +57,7 @@ public final class FlwPrograms {
|
||||||
|
|
||||||
private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
|
private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
|
||||||
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
|
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
|
||||||
for (ContextShader contextShader : ContextShader.REGISTRY) {
|
for (ContextShader contextShader : ContextShaders.REGISTRY) {
|
||||||
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
|
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
|
||||||
builder.add(new PipelineProgramKey(instanceType, contextShader));
|
builder.add(new PipelineProgramKey(instanceType, contextShader));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
|
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
|
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.Compile;
|
import com.jozufozu.flywheel.backend.compile.core.Compile;
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShader;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShader;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.compile;
|
package com.jozufozu.flywheel.backend.compile;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the entire context of a program's usage.
|
* Represents the entire context of a program's usage.
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
|
||||||
|
|
||||||
public interface Context {
|
|
||||||
ContextShader contextShader();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the shader for rendering with the given material and textures.
|
|
||||||
*
|
|
||||||
* @param material The material about to be rendered.
|
|
||||||
* @param shader The shader to prepare.
|
|
||||||
* @param textureSource Source of the textures to use.
|
|
||||||
*/
|
|
||||||
void prepare(Material material, GlProgram shader, TextureSource textureSource);
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.internal.InternalFlywheelApi;
|
|
||||||
import com.jozufozu.flywheel.api.registry.Registry;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public interface ContextShader {
|
|
||||||
static Registry<ContextShader> REGISTRY = InternalFlywheelApi.INSTANCE.createRegistry();
|
|
||||||
|
|
||||||
ResourceLocation vertexShader();
|
|
||||||
|
|
||||||
ResourceLocation fragmentShader();
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
|
|
||||||
public class ContextShaders {
|
|
||||||
public static final SimpleContextShader DEFAULT = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("internal/context/default.vert"), Flywheel.rl("internal/context/default.frag")));
|
|
||||||
public static final SimpleContextShader CRUMBLING = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("internal/context/crumbling.vert"), Flywheel.rl("internal/context/crumbling.frag")));
|
|
||||||
public static final SimpleContextShader EMBEDDED = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("internal/context/embedded.vert"), Flywheel.rl("internal/context/embedded.frag")));
|
|
||||||
|
|
||||||
private ContextShaders() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public static void init() {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
public final class Contexts {
|
|
||||||
public static final Context DEFAULT = SimpleContext.builder(ContextShaders.DEFAULT)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private Contexts() {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
|
||||||
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
public class EmbeddedContext implements Context {
|
|
||||||
private final EmbeddedLevel world;
|
|
||||||
|
|
||||||
public EmbeddedContext(EmbeddedLevel world) {
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContextShader contextShader() {
|
|
||||||
return ContextShaders.EMBEDDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void prepare(Material material, GlProgram shader, TextureSource textureSource) {
|
|
||||||
var stack = new PoseStack();
|
|
||||||
world.transform(stack);
|
|
||||||
|
|
||||||
// shader.setVec3("create_oneOverLightBoxSize");
|
|
||||||
// shader.setVec3("create_lightVolumeMin");
|
|
||||||
shader.setMat4("_flw_model", stack.last()
|
|
||||||
.pose());
|
|
||||||
shader.setMat3("_flw_normal", stack.last()
|
|
||||||
.normal());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
|
||||||
|
|
||||||
public class SimpleContext implements Context {
|
|
||||||
private final ContextShader contextShader;
|
|
||||||
private final Preparation preparation;
|
|
||||||
|
|
||||||
public SimpleContext(ContextShader contextShader, Preparation preparation) {
|
|
||||||
this.contextShader = contextShader;
|
|
||||||
this.preparation = preparation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Builder builder(ContextShader contextShader) {
|
|
||||||
return new Builder(contextShader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContextShader contextShader() {
|
|
||||||
return contextShader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void prepare(Material material, GlProgram shader, TextureSource textureSource) {
|
|
||||||
preparation.prepare(material, shader, textureSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Preparation {
|
|
||||||
void prepare(Material material, GlProgram shader, TextureSource textureSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
private final ContextShader contextShader;
|
|
||||||
@Nullable
|
|
||||||
private Preparation preparation;
|
|
||||||
|
|
||||||
public Builder(ContextShader contextShader) {
|
|
||||||
this.contextShader = contextShader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder preparation(Preparation preparation) {
|
|
||||||
this.preparation = preparation;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimpleContext build() {
|
|
||||||
if (preparation == null) {
|
|
||||||
preparation = (material, shader, textureSource) -> {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return new SimpleContext(contextShader, preparation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public record SimpleContextShader(ResourceLocation vertexShader,
|
|
||||||
ResourceLocation fragmentShader) implements ContextShader {
|
|
||||||
@Override
|
|
||||||
public ResourceLocation vertexShader() {
|
|
||||||
return vertexShader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation fragmentShader() {
|
|
||||||
return fragmentShader;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.context;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.BackendImplemented;
|
|
||||||
|
|
||||||
@BackendImplemented
|
|
||||||
public interface Texture {
|
|
||||||
void filter(boolean blur, boolean mipmap);
|
|
||||||
}
|
|
|
@ -6,9 +6,7 @@ import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.Instancer;
|
import com.jozufozu.flywheel.api.instance.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
import com.jozufozu.flywheel.backend.context.Contexts;
|
|
||||||
import com.jozufozu.flywheel.backend.context.EmbeddedContext;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -25,12 +23,12 @@ public abstract class AbstractEngine implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage) {
|
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage) {
|
||||||
return getStorage().getInstancer(type, Contexts.DEFAULT, model, stage);
|
return getStorage().getInstancer(null, type, model, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <I extends Instance> Instancer<I> instancer(EmbeddedLevel world, InstanceType<I> type, Model model, RenderStage stage) {
|
public <I extends Instance> Instancer<I> instancer(VisualEmbedding world, InstanceType<I> type, Model model, RenderStage stage) {
|
||||||
return getStorage().getInstancer(type, new EmbeddedContext(world), model, stage);
|
return getStorage().getInstancer(world, type, model, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,15 +2,18 @@ package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.Instancer;
|
import com.jozufozu.flywheel.api.instance.Instancer;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
import com.jozufozu.flywheel.lib.util.AtomicBitset;
|
import com.jozufozu.flywheel.lib.util.AtomicBitset;
|
||||||
|
|
||||||
public abstract class AbstractInstancer<I extends Instance> implements Instancer<I> {
|
public abstract class AbstractInstancer<I extends Instance> implements Instancer<I> {
|
||||||
public final InstanceType<I> type;
|
public final InstanceType<I> type;
|
||||||
public final Context context;
|
@Nullable
|
||||||
|
public final VisualEmbedding embedding;
|
||||||
|
|
||||||
// Lock for all instances, only needs to be used in methods that may run on the TaskExecutor.
|
// Lock for all instances, only needs to be used in methods that may run on the TaskExecutor.
|
||||||
protected final Object lock = new Object();
|
protected final Object lock = new Object();
|
||||||
|
@ -20,9 +23,9 @@ public abstract class AbstractInstancer<I extends Instance> implements Instancer
|
||||||
protected final AtomicBitset changed = new AtomicBitset();
|
protected final AtomicBitset changed = new AtomicBitset();
|
||||||
protected final AtomicBitset deleted = new AtomicBitset();
|
protected final AtomicBitset deleted = new AtomicBitset();
|
||||||
|
|
||||||
protected AbstractInstancer(InstanceType<I> type, Context context) {
|
protected AbstractInstancer(InstanceType<I> type, @Nullable VisualEmbedding embedding) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.context = context;
|
this.embedding = embedding;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,7 +41,7 @@ public abstract class AbstractInstancer<I extends Instance> implements Instancer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stealInstance(I instance) {
|
public void stealInstance(@Nullable I instance) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package com.jozufozu.flywheel.backend.engine;
|
package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
|
|
||||||
public record InstancerKey<I extends Instance>(InstanceType<I> type, Context context, Model model, RenderStage stage) {
|
public record InstancerKey<I extends Instance>(@Nullable VisualEmbedding embedding, InstanceType<I> type, Model model,
|
||||||
|
RenderStage stage) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,15 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.Instancer;
|
import com.jozufozu.flywheel.api.instance.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
|
|
||||||
public abstract class InstancerStorage<N extends AbstractInstancer<?>> {
|
public abstract class InstancerStorage<N extends AbstractInstancer<?>> {
|
||||||
/**
|
/**
|
||||||
|
@ -28,8 +30,8 @@ public abstract class InstancerStorage<N extends AbstractInstancer<?>> {
|
||||||
protected final List<UninitializedInstancer<N, ?>> initializationQueue = new ArrayList<>();
|
protected final List<UninitializedInstancer<N, ?>> initializationQueue = new ArrayList<>();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <I extends Instance> Instancer<I> getInstancer(InstanceType<I> type, Context context, Model model, RenderStage stage) {
|
public <I extends Instance> Instancer<I> getInstancer(@Nullable VisualEmbedding level, InstanceType<I> type, Model model, RenderStage stage) {
|
||||||
return (Instancer<I>) instancers.computeIfAbsent(new InstancerKey<>(type, context, model, stage), this::createAndDeferInit);
|
return (Instancer<I>) instancers.computeIfAbsent(new InstancerKey<>(level, type, model, stage), this::createAndDeferInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.textures;
|
package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class TextureBinder {
|
public class TextureBinder {
|
||||||
// TODO: some kind of cache eviction when the program changes
|
// TODO: some kind of cache eviction when the program changes
|
||||||
|
@ -69,4 +70,17 @@ public class TextureBinder {
|
||||||
gameRenderer.lightTexture()
|
gameRenderer.lightTexture()
|
||||||
.turnOffLightLayer();
|
.turnOffLightLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a built-in texture by its resource location.
|
||||||
|
*
|
||||||
|
* @param texture The texture's resource location.
|
||||||
|
* @return The texture.
|
||||||
|
*/
|
||||||
|
public static int byName(ResourceLocation texture) {
|
||||||
|
return Minecraft.getInstance()
|
||||||
|
.getTextureManager()
|
||||||
|
.getTexture(texture)
|
||||||
|
.getId();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,18 +16,20 @@ import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
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.compile.IndirectPrograms;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
|
||||||
import com.jozufozu.flywheel.backend.context.SimpleContextShader;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
import com.jozufozu.flywheel.backend.engine.MeshPool;
|
import com.jozufozu.flywheel.backend.engine.MeshPool;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
|
import com.jozufozu.flywheel.backend.engine.TextureBinder;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.Driver;
|
import com.jozufozu.flywheel.backend.gl.Driver;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
||||||
|
@ -40,7 +42,8 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
private static final int DRAW_BARRIER_BITS = GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT;
|
private static final int DRAW_BARRIER_BITS = GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT;
|
||||||
|
|
||||||
private final InstanceType<I> instanceType;
|
private final InstanceType<I> instanceType;
|
||||||
private final Context context;
|
@Nullable
|
||||||
|
private final VisualEmbedding embedding;
|
||||||
private final long objectStride;
|
private final long objectStride;
|
||||||
private final IndirectBuffers buffers;
|
private final IndirectBuffers buffers;
|
||||||
private final List<IndirectInstancer<?>> instancers = new ArrayList<>();
|
private final List<IndirectInstancer<?>> instancers = new ArrayList<>();
|
||||||
|
@ -56,18 +59,17 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
private boolean needsDrawSort;
|
private boolean needsDrawSort;
|
||||||
private int instanceCountThisFrame;
|
private int instanceCountThisFrame;
|
||||||
|
|
||||||
IndirectCullingGroup(InstanceType<I> instanceType, Context context, IndirectPrograms programs) {
|
IndirectCullingGroup(InstanceType<I> instanceType, @Nullable VisualEmbedding embedding, IndirectPrograms programs) {
|
||||||
this.instanceType = instanceType;
|
this.instanceType = instanceType;
|
||||||
this.context = context;
|
this.embedding = embedding;
|
||||||
objectStride = instanceType.layout()
|
objectStride = instanceType.layout()
|
||||||
.byteSize() + IndirectBuffers.INT_SIZE;
|
.byteSize() + IndirectBuffers.INT_SIZE;
|
||||||
buffers = new IndirectBuffers(objectStride);
|
buffers = new IndirectBuffers(objectStride);
|
||||||
|
|
||||||
this.programs = programs;
|
this.programs = programs;
|
||||||
// TODO: Culling programs need to be context aware.
|
|
||||||
cullProgram = programs.getCullingProgram(instanceType);
|
cullProgram = programs.getCullingProgram(instanceType);
|
||||||
applyProgram = programs.getApplyProgram();
|
applyProgram = programs.getApplyProgram();
|
||||||
drawProgram = programs.getIndirectProgram(instanceType, context.contextShader());
|
drawProgram = programs.getIndirectProgram(instanceType, ContextShaders.forEmbedding(embedding));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flushInstancers() {
|
public void flushInstancers() {
|
||||||
|
@ -128,6 +130,14 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
|
|
||||||
Uniforms.bindFrame();
|
Uniforms.bindFrame();
|
||||||
cullProgram.bind();
|
cullProgram.bind();
|
||||||
|
|
||||||
|
if (embedding != null) {
|
||||||
|
cullProgram.setBool("_flw_useEmbeddedModel", true);
|
||||||
|
cullProgram.setMat4("_flw_embeddedModel", embedding.pose());
|
||||||
|
} else {
|
||||||
|
cullProgram.setBool("_flw_useEmbeddedModel", false);
|
||||||
|
}
|
||||||
|
|
||||||
buffers.bindForCompute();
|
buffers.bindForCompute();
|
||||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
||||||
glDispatchCompute(GlCompat.getComputeGroupCount(instanceCountThisFrame), 1, 1);
|
glDispatchCompute(GlCompat.getComputeGroupCount(instanceCountThisFrame), 1, 1);
|
||||||
|
@ -191,7 +201,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
needsDrawSort = true;
|
needsDrawSort = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submit(RenderStage stage, TextureSource textures) {
|
public void submit(RenderStage stage) {
|
||||||
if (nothingToDo(stage)) {
|
if (nothingToDo(stage)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -199,6 +209,13 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
drawProgram.bind();
|
drawProgram.bind();
|
||||||
buffers.bindForDraw();
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
drawBarrier();
|
drawBarrier();
|
||||||
|
|
||||||
var flwBaseDraw = drawProgram.getUniformLocation("_flw_baseDraw");
|
var flwBaseDraw = drawProgram.getUniformLocation("_flw_baseDraw");
|
||||||
|
@ -206,7 +223,6 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
for (var multiDraw : multiDraws.get(stage)) {
|
for (var multiDraw : multiDraws.get(stage)) {
|
||||||
glUniform1ui(flwBaseDraw, multiDraw.start);
|
glUniform1ui(flwBaseDraw, multiDraw.start);
|
||||||
|
|
||||||
context.prepare(multiDraw.material, drawProgram, textures);
|
|
||||||
MaterialRenderState.setup(multiDraw.material);
|
MaterialRenderState.setup(multiDraw.material);
|
||||||
|
|
||||||
multiDraw.submit();
|
multiDraw.submit();
|
||||||
|
@ -214,7 +230,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram bindWithContextShader(SimpleContextShader override) {
|
public GlProgram bindWithContextShader(ContextShader override) {
|
||||||
var program = programs.getIndirectProgram(instanceType, override);
|
var program = programs.getIndirectProgram(instanceType, override);
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
|
@ -11,21 +11,22 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.backend.Engine;
|
import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
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.compile.IndirectPrograms;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShaders;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
|
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
import com.jozufozu.flywheel.backend.engine.MeshPool;
|
import com.jozufozu.flywheel.backend.engine.MeshPool;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
|
import com.jozufozu.flywheel.backend.engine.TextureBinder;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
|
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
|
||||||
|
@ -44,7 +45,6 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
private final StagingBuffer stagingBuffer;
|
private final StagingBuffer stagingBuffer;
|
||||||
private final MeshPool meshPool;
|
private final MeshPool meshPool;
|
||||||
private final GlVertexArray vertexArray;
|
private final GlVertexArray vertexArray;
|
||||||
private final TextureSource textures = new TextureSource();
|
|
||||||
private final Map<GroupKey<?>, IndirectCullingGroup<?>> cullingGroups = new HashMap<>();
|
private final Map<GroupKey<?>, IndirectCullingGroup<?>> cullingGroups = new HashMap<>();
|
||||||
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
|
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
|
||||||
|
|
||||||
|
@ -61,13 +61,13 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <I extends Instance> IndirectInstancer<?> create(InstancerKey<I> key) {
|
protected <I extends Instance> IndirectInstancer<?> create(InstancerKey<I> key) {
|
||||||
return new IndirectInstancer<>(key.type(), key.context(), key.model());
|
return new IndirectInstancer<>(key.type(), key.embedding(), key.model());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected <I extends Instance> void initialize(InstancerKey<I> key, IndirectInstancer<?> instancer) {
|
protected <I extends Instance> void initialize(InstancerKey<I> key, IndirectInstancer<?> instancer) {
|
||||||
var groupKey = new GroupKey<>(key.type(), key.context());
|
var groupKey = new GroupKey<>(key.type(), key.embedding());
|
||||||
var group = (IndirectCullingGroup<I>) cullingGroups.computeIfAbsent(groupKey, t -> new IndirectCullingGroup<>(t.type, t.context, programs));
|
var group = (IndirectCullingGroup<I>) cullingGroups.computeIfAbsent(groupKey, t -> new IndirectCullingGroup<>(t.type, t.context, programs));
|
||||||
group.add((IndirectInstancer<I>) instancer, key.model(), key.stage(), meshPool);
|
group.add((IndirectInstancer<I>) instancer, key.model(), key.stage(), meshPool);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
Uniforms.bindForDraw();
|
Uniforms.bindForDraw();
|
||||||
|
|
||||||
for (var group : cullingGroups.values()) {
|
for (var group : cullingGroups.values()) {
|
||||||
group.submit(stage, textures);
|
group.submit(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialRenderState.reset();
|
MaterialRenderState.reset();
|
||||||
|
@ -168,7 +168,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
.bindWithContextShader(ContextShaders.CRUMBLING);
|
.bindWithContextShader(ContextShaders.CRUMBLING);
|
||||||
|
|
||||||
for (var progressEntry : byProgress.int2ObjectEntrySet()) {
|
for (var progressEntry : byProgress.int2ObjectEntrySet()) {
|
||||||
program.setTexture("crumblingTex", textures.byName(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())));
|
program.setTexture("crumblingTex", TextureBinder.byName(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())));
|
||||||
|
|
||||||
for (var instanceHandlePair : progressEntry.getValue()) {
|
for (var instanceHandlePair : progressEntry.getValue()) {
|
||||||
IndirectInstancer<?> instancer = instanceHandlePair.first();
|
IndirectInstancer<?> instancer = instanceHandlePair.first();
|
||||||
|
@ -221,7 +221,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.context), $ -> new Int2ObjectArrayMap<>())
|
byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.embedding), $ -> new Int2ObjectArrayMap<>())
|
||||||
.computeIfAbsent(progress, $ -> new ArrayList<>())
|
.computeIfAbsent(progress, $ -> new ArrayList<>())
|
||||||
.add(Pair.of(instancer, impl));
|
.add(Pair.of(instancer, impl));
|
||||||
}
|
}
|
||||||
|
@ -229,6 +229,6 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
|
||||||
return byType;
|
return byType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record GroupKey<I extends Instance>(InstanceType<I> type, Context context) {
|
public record GroupKey<I extends Instance>(InstanceType<I> type, @Nullable VisualEmbedding context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.jozufozu.flywheel.backend.engine.indirect;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Vector4fc;
|
import org.joml.Vector4fc;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
|
|
||||||
public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I> {
|
public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
|
@ -25,7 +26,7 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
private int lastModelIndex = -1;
|
private int lastModelIndex = -1;
|
||||||
private long lastStartPos = -1;
|
private long lastStartPos = -1;
|
||||||
|
|
||||||
public IndirectInstancer(InstanceType<I> type, Context context, Model model) {
|
public IndirectInstancer(InstanceType<I> type, @Nullable VisualEmbedding context, Model model) {
|
||||||
super(type, context);
|
super(type, context);
|
||||||
this.objectStride = type.layout()
|
this.objectStride = type.layout()
|
||||||
.byteSize() + IndirectBuffers.INT_SIZE;
|
.byteSize() + IndirectBuffers.INT_SIZE;
|
||||||
|
|
|
@ -19,8 +19,8 @@ import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.backend.ShaderIndices;
|
import com.jozufozu.flywheel.backend.ShaderIndices;
|
||||||
|
import com.jozufozu.flywheel.backend.compile.ContextShaders;
|
||||||
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
|
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
|
||||||
import com.jozufozu.flywheel.backend.context.ContextShaders;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
|
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
|
@ -28,8 +28,7 @@ import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialEncoder;
|
import com.jozufozu.flywheel.backend.engine.MaterialEncoder;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
import com.jozufozu.flywheel.backend.engine.MeshPool;
|
import com.jozufozu.flywheel.backend.engine.MeshPool;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
|
import com.jozufozu.flywheel.backend.engine.TextureBinder;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
|
@ -53,7 +52,6 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
*/
|
*/
|
||||||
private final MeshPool meshPool;
|
private final MeshPool meshPool;
|
||||||
private final GlVertexArray vao;
|
private final GlVertexArray vao;
|
||||||
private final TextureSource textures;
|
|
||||||
private final TextureBuffer instanceTexture;
|
private final TextureBuffer instanceTexture;
|
||||||
|
|
||||||
public InstancedDrawManager(InstancingPrograms programs) {
|
public InstancedDrawManager(InstancingPrograms programs) {
|
||||||
|
@ -62,7 +60,6 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
|
|
||||||
meshPool = new MeshPool();
|
meshPool = new MeshPool();
|
||||||
vao = GlVertexArray.create();
|
vao = GlVertexArray.create();
|
||||||
textures = new TextureSource();
|
|
||||||
instanceTexture = new TextureBuffer();
|
instanceTexture = new TextureBuffer();
|
||||||
|
|
||||||
meshPool.bind(vao);
|
meshPool.bind(vao);
|
||||||
|
@ -133,15 +130,14 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var context = shader.context();
|
var embedding = shader.embedding();
|
||||||
var material = shader.material();
|
var material = shader.material();
|
||||||
|
|
||||||
var program = programs.get(shader.instanceType(), context.contextShader());
|
var program = programs.get(shader.instanceType(), ContextShaders.forEmbedding(embedding));
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
||||||
uploadMaterialUniform(program, material);
|
uploadMaterialUniform(program, material);
|
||||||
|
|
||||||
context.prepare(material, program, textures);
|
|
||||||
MaterialRenderState.setup(material);
|
MaterialRenderState.setup(material);
|
||||||
|
|
||||||
GlTextureUnit.T3.makeActive();
|
GlTextureUnit.T3.makeActive();
|
||||||
|
@ -160,7 +156,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <I extends Instance> InstancedInstancer<I> create(InstancerKey<I> key) {
|
protected <I extends Instance> InstancedInstancer<I> create(InstancerKey<I> key) {
|
||||||
return new InstancedInstancer<>(key.type(), key.context());
|
return new InstancedInstancer<>(key.type(), key.embedding());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,7 +170,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
for (var entry : meshes) {
|
for (var entry : meshes) {
|
||||||
var mesh = meshPool.alloc(entry.mesh());
|
var mesh = meshPool.alloc(entry.mesh());
|
||||||
|
|
||||||
ShaderState shaderState = new ShaderState(entry.material(), key.type(), key.context());
|
ShaderState shaderState = new ShaderState(entry.material(), key.type(), key.embedding());
|
||||||
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
|
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
|
||||||
|
|
||||||
drawSet.put(shaderState, drawCall);
|
drawSet.put(shaderState, drawCall);
|
||||||
|
@ -222,7 +218,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
program.setTexture("crumblingTex", textures.byName(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())));
|
program.setTexture("crumblingTex", TextureBinder.byName(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())));
|
||||||
|
|
||||||
GlTextureUnit.T3.makeActive();
|
GlTextureUnit.T3.makeActive();
|
||||||
program.setSamplerBinding("_flw_instances", 3);
|
program.setSamplerBinding("_flw_instances", 3);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
import com.jozufozu.flywheel.backend.gl.TextureBuffer;
|
import com.jozufozu.flywheel.backend.gl.TextureBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
|
@ -25,7 +25,7 @@ public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
|
|
||||||
private final List<DrawCall> drawCalls = new ArrayList<>();
|
private final List<DrawCall> drawCalls = new ArrayList<>();
|
||||||
|
|
||||||
public InstancedInstancer(InstanceType<I> type, Context context) {
|
public InstancedInstancer(InstanceType<I> type, @Nullable VisualEmbedding context) {
|
||||||
super(type, context);
|
super(type, context);
|
||||||
var layout = type.layout();
|
var layout = type.layout();
|
||||||
// Align to one texel in the texture buffer
|
// Align to one texel in the texture buffer
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.instancing;
|
package com.jozufozu.flywheel.backend.engine.instancing;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.backend.context.Context;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
|
|
||||||
public record ShaderState(Material material, InstanceType<?> instanceType, Context context) {
|
public record ShaderState(Material material, InstanceType<?> instanceType, @Nullable VisualEmbedding embedding) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.textures;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.context.Texture;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal base interface that {@link com.jozufozu.flywheel.backend.gl.shader.GlProgram GlProgram} expects.
|
|
||||||
*/
|
|
||||||
public interface IdentifiedTexture extends Texture {
|
|
||||||
/**
|
|
||||||
* @return The GL texture id of this texture.
|
|
||||||
*/
|
|
||||||
int id();
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.textures;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.context.Texture;
|
|
||||||
import com.jozufozu.flywheel.backend.mixin.LightTextureAccessor;
|
|
||||||
import com.jozufozu.flywheel.backend.mixin.OverlayTextureAccessor;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.texture.AbstractTexture;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class TextureSource {
|
|
||||||
|
|
||||||
private final DirectTexture lightTexture;
|
|
||||||
private final DirectTexture overlayTexture;
|
|
||||||
private final Map<ResourceLocation, WrappedTexture> wrappers = new HashMap<>();
|
|
||||||
|
|
||||||
public TextureSource() {
|
|
||||||
var gameRenderer = Minecraft.getInstance().gameRenderer;
|
|
||||||
|
|
||||||
this.lightTexture = new DirectTexture(((LightTextureAccessor) gameRenderer.lightTexture()).flywheel$texture()
|
|
||||||
.getId());
|
|
||||||
this.overlayTexture = new DirectTexture(((OverlayTextureAccessor) gameRenderer.overlayTexture()).flywheel$texture()
|
|
||||||
.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a built-in texture by its resource location.
|
|
||||||
*
|
|
||||||
* @param texture The texture's resource location.
|
|
||||||
* @return The texture.
|
|
||||||
*/
|
|
||||||
public Texture byName(ResourceLocation texture) {
|
|
||||||
return wrappers.computeIfAbsent(texture, key -> new WrappedTexture(Minecraft.getInstance()
|
|
||||||
.getTextureManager()
|
|
||||||
.getTexture(key)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the overlay texture.
|
|
||||||
*
|
|
||||||
* @return The overlay texture.
|
|
||||||
*/
|
|
||||||
public Texture overlay() {
|
|
||||||
return overlayTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the light texture.
|
|
||||||
*
|
|
||||||
* @return The light texture.
|
|
||||||
*/
|
|
||||||
public Texture light() {
|
|
||||||
return lightTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
public record WrappedTexture(AbstractTexture texture) implements IdentifiedTexture {
|
|
||||||
@Override
|
|
||||||
public void filter(boolean blur, boolean mipmap) {
|
|
||||||
texture.setFilter(blur, mipmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int id() {
|
|
||||||
return texture.getId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public record DirectTexture(int id) implements IdentifiedTexture {
|
|
||||||
@Override
|
|
||||||
public void filter(boolean blur, boolean mipmap) {
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,9 +18,7 @@ import org.joml.Matrix3fc;
|
||||||
import org.joml.Matrix4fc;
|
import org.joml.Matrix4fc;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.context.Texture;
|
import com.jozufozu.flywheel.backend.engine.TextureBinder;
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.IdentifiedTexture;
|
|
||||||
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlObject;
|
import com.jozufozu.flywheel.backend.gl.GlObject;
|
||||||
import com.mojang.blaze3d.shaders.ProgramManager;
|
import com.mojang.blaze3d.shaders.ProgramManager;
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
@ -45,19 +43,14 @@ public class GlProgram extends GlObject {
|
||||||
ProgramManager.glUseProgram(0);
|
ProgramManager.glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTexture(String glslName, Texture texture) {
|
public void setTexture(String glslName, int texture) {
|
||||||
if (!(texture instanceof IdentifiedTexture identified)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int uniform = getUniformLocation(glslName);
|
int uniform = getUniformLocation(glslName);
|
||||||
|
|
||||||
if (uniform < 0) {
|
if (uniform < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = identified.id();
|
int binding = TextureBinder.bindTexture(texture);
|
||||||
|
|
||||||
int binding = TextureBinder.bindTexture(id);
|
|
||||||
|
|
||||||
glUniform1i(uniform, binding);
|
glUniform1i(uniform, binding);
|
||||||
}
|
}
|
||||||
|
@ -122,6 +115,16 @@ public class GlProgram extends GlObject {
|
||||||
glUniformMatrix3fv(uniform, false, matrix.get(new float[9]));
|
glUniformMatrix3fv(uniform, false, matrix.get(new float[9]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBool(String glslName, boolean bool) {
|
||||||
|
int uniform = getUniformLocation(glslName);
|
||||||
|
|
||||||
|
if (uniform < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glUniform1i(uniform, bool ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the index of the uniform with the given name.
|
* Retrieves the index of the uniform with the given name.
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,7 +9,7 @@ import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.Instancer;
|
import com.jozufozu.flywheel.api.instance.Instancer;
|
||||||
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
||||||
|
|
||||||
public class InstancerProviderImpl implements InstancerProvider, Supplier<VisualizationContext> {
|
public class InstancerProviderImpl implements InstancerProvider, Supplier<VisualizationContext> {
|
||||||
|
@ -31,7 +31,7 @@ public class InstancerProviderImpl implements InstancerProvider, Supplier<Visual
|
||||||
return new VisualizationContextImpl(this, engine.renderOrigin());
|
return new VisualizationContextImpl(this, engine.renderOrigin());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Embedded embed(EmbeddedLevel world) {
|
public Embedded embed(VisualEmbedding world) {
|
||||||
return new Embedded(engine, world, renderStage);
|
return new Embedded(engine, world, renderStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@ public class InstancerProviderImpl implements InstancerProvider, Supplier<Visual
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Embedded extends InstancerProviderImpl {
|
public static final class Embedded extends InstancerProviderImpl {
|
||||||
private final EmbeddedLevel world;
|
private final VisualEmbedding world;
|
||||||
|
|
||||||
public Embedded(Engine engine, EmbeddedLevel world, RenderStage renderStage) {
|
public Embedded(Engine engine, VisualEmbedding world, RenderStage renderStage) {
|
||||||
super(engine, renderStage);
|
super(engine, renderStage);
|
||||||
this.world = world;
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ public class InstancerProviderImpl implements InstancerProvider, Supplier<Visual
|
||||||
return engine.instancer(world, type, model, renderStage);
|
return engine.instancer(world, type, model, renderStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbeddedLevel world() {
|
public VisualEmbedding world() {
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.impl.visualization;
|
package com.jozufozu.flywheel.impl.visualization;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||||
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
|
import com.jozufozu.flywheel.api.visualization.VisualEmbedding;
|
||||||
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
||||||
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraft.core.Vec3i;
|
||||||
*/
|
*/
|
||||||
public record VisualizationContextImpl(InstancerProviderImpl instancerProvider, Vec3i renderOrigin) implements VisualizationContext {
|
public record VisualizationContextImpl(InstancerProviderImpl instancerProvider, Vec3i renderOrigin) implements VisualizationContext {
|
||||||
@Override
|
@Override
|
||||||
public VisualizationContext embed(EmbeddedLevel world) {
|
public VisualizationContext embed(VisualEmbedding world) {
|
||||||
return new VisualizationContextImpl(instancerProvider.embed(world), renderOrigin);
|
return new VisualizationContextImpl(instancerProvider.embed(world), renderOrigin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue