mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 22:43:56 +01:00
Dynamic ubering
- Remove fog shader registry - Remove Registry and RegistryImpl - Make shader indices mutable - Track fog uber component in a static field in PipelineCompiler - When a new fog source is added, delete the pipeline compilation harness and recreate the fog uber component - Inline SourceLoader
This commit is contained in:
parent
bce657804a
commit
11ce4ac185
@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import dev.engine_room.flywheel.api.backend.Backend;
|
import dev.engine_room.flywheel.api.backend.Backend;
|
||||||
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
|
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
|
||||||
import dev.engine_room.flywheel.api.registry.IdRegistry;
|
import dev.engine_room.flywheel.api.registry.IdRegistry;
|
||||||
import dev.engine_room.flywheel.api.registry.Registry;
|
|
||||||
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||||
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
|
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
|
||||||
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
||||||
@ -18,8 +17,6 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
|||||||
public interface FlwApiLink {
|
public interface FlwApiLink {
|
||||||
FlwApiLink INSTANCE = DependencyInjection.load(FlwApiLink.class, "dev.engine_room.flywheel.impl.FlwApiLinkImpl");
|
FlwApiLink INSTANCE = DependencyInjection.load(FlwApiLink.class, "dev.engine_room.flywheel.impl.FlwApiLinkImpl");
|
||||||
|
|
||||||
<T> Registry<T> createRegistry();
|
|
||||||
|
|
||||||
<T> IdRegistry<T> createIdRegistry();
|
<T> IdRegistry<T> createIdRegistry();
|
||||||
|
|
||||||
Backend getCurrentBackend();
|
Backend getCurrentBackend();
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
package dev.engine_room.flywheel.api.material;
|
package dev.engine_room.flywheel.api.material;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.internal.FlwApiLink;
|
|
||||||
import dev.engine_room.flywheel.api.registry.Registry;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public interface FogShader {
|
public interface FogShader {
|
||||||
Registry<FogShader> REGISTRY = FlwApiLink.INSTANCE.createRegistry();
|
|
||||||
|
|
||||||
ResourceLocation source();
|
ResourceLocation source();
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.api.registry;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.UnmodifiableView;
|
|
||||||
|
|
||||||
@ApiStatus.NonExtendable
|
|
||||||
public interface Registry<T> extends Iterable<T> {
|
|
||||||
void register(T object);
|
|
||||||
|
|
||||||
<S extends T> S registerAndGet(S object);
|
|
||||||
|
|
||||||
@UnmodifiableView
|
|
||||||
Set<T> getAll();
|
|
||||||
|
|
||||||
boolean isFrozen();
|
|
||||||
}
|
|
@ -1,14 +1,11 @@
|
|||||||
package dev.engine_room.flywheel.backend;
|
package dev.engine_room.flywheel.backend;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
import dev.engine_room.flywheel.api.material.CutoutShader;
|
||||||
import dev.engine_room.flywheel.api.material.FogShader;
|
import dev.engine_room.flywheel.api.material.FogShader;
|
||||||
import dev.engine_room.flywheel.api.registry.Registry;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
@ -16,25 +13,17 @@ import it.unimi.dsi.fastutil.objects.ObjectList;
|
|||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public final class MaterialShaderIndices {
|
public final class MaterialShaderIndices {
|
||||||
@Nullable
|
private static final Index fogSources = new Index();
|
||||||
private static Index fogSources;
|
private static final Index cutoutSources = new Index();
|
||||||
@Nullable
|
|
||||||
private static Index cutoutSources;
|
|
||||||
|
|
||||||
private MaterialShaderIndices() {
|
private MaterialShaderIndices() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Index fogSources() {
|
public static Index fogSources() {
|
||||||
if (fogSources == null) {
|
|
||||||
fogSources = indexFromRegistry(FogShader.REGISTRY, FogShader::source);
|
|
||||||
}
|
|
||||||
return fogSources;
|
return fogSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Index cutoutSources() {
|
public static Index cutoutSources() {
|
||||||
// if (cutoutSources == null) {
|
|
||||||
// cutoutSources = indexFromRegistry(CutoutShader.REGISTRY, CutoutShader::source);
|
|
||||||
// }
|
|
||||||
return cutoutSources;
|
return cutoutSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,30 +32,23 @@ public final class MaterialShaderIndices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int cutoutIndex(CutoutShader cutoutShader) {
|
public static int cutoutIndex(CutoutShader cutoutShader) {
|
||||||
return 0;//cutoutSources().index(cutoutShader.source());
|
return cutoutSources().index(cutoutShader.source());
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> Index indexFromRegistry(Registry<T> registry, Function<T, ResourceLocation> sourceFunc) {
|
|
||||||
if (!registry.isFrozen()) {
|
|
||||||
throw new IllegalStateException("Cannot create index from registry that is not frozen!");
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = new IndexBuilder();
|
|
||||||
|
|
||||||
for (T object : registry) {
|
|
||||||
builder.add(sourceFunc.apply(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Index {
|
public static class Index {
|
||||||
private final Object2IntMap<ResourceLocation> sources2Index;
|
private final Object2IntMap<ResourceLocation> sources2Index;
|
||||||
private final ObjectList<ResourceLocation> sources;
|
private final ObjectList<ResourceLocation> sources;
|
||||||
|
|
||||||
private Index(IndexBuilder builder) {
|
private Index() {
|
||||||
this.sources2Index = new Object2IntOpenHashMap<>(builder.sources2Index);
|
this.sources2Index = new Object2IntOpenHashMap<>();
|
||||||
this.sources = new ObjectArrayList<>(builder.sources);
|
sources2Index.defaultReturnValue(-1);
|
||||||
|
this.sources = new ObjectArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(ResourceLocation source) {
|
||||||
|
if (sources2Index.putIfAbsent(source, sources.size()) == -1) {
|
||||||
|
sources.add(source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int index(ResourceLocation source) {
|
public int index(ResourceLocation source) {
|
||||||
@ -82,27 +64,4 @@ public final class MaterialShaderIndices {
|
|||||||
return sources;
|
return sources;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IndexBuilder {
|
|
||||||
private final Object2IntMap<ResourceLocation> sources2Index;
|
|
||||||
private final ObjectList<ResourceLocation> sources;
|
|
||||||
private int index = 0;
|
|
||||||
|
|
||||||
public IndexBuilder() {
|
|
||||||
sources2Index = new Object2IntOpenHashMap<>();
|
|
||||||
sources2Index.defaultReturnValue(-1);
|
|
||||||
sources = new ObjectArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(ResourceLocation source) {
|
|
||||||
if (sources2Index.putIfAbsent(source, index) == -1) {
|
|
||||||
sources.add(source);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Index build() {
|
|
||||||
return new Index(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,13 @@ package dev.engine_room.flywheel.backend.compile;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
|
||||||
import dev.engine_room.flywheel.backend.compile.component.UberShaderComponent;
|
|
||||||
import dev.engine_room.flywheel.backend.compile.core.CompilerStats;
|
import dev.engine_room.flywheel.backend.compile.core.CompilerStats;
|
||||||
import dev.engine_room.flywheel.backend.compile.core.SourceLoader;
|
|
||||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||||
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
||||||
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
|
||||||
import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
|
|
||||||
@ -23,6 +17,8 @@ public final class FlwPrograms {
|
|||||||
|
|
||||||
private static final ResourceLocation COMPONENTS_HEADER_FRAG = Flywheel.rl("internal/components_header.frag");
|
private static final ResourceLocation COMPONENTS_HEADER_FRAG = Flywheel.rl("internal/components_header.frag");
|
||||||
|
|
||||||
|
public static ShaderSources SOURCES;
|
||||||
|
|
||||||
private FlwPrograms() {
|
private FlwPrograms() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,52 +28,22 @@ public final class FlwPrograms {
|
|||||||
IndirectPrograms.setInstance(null);
|
IndirectPrograms.setInstance(null);
|
||||||
|
|
||||||
var sources = new ShaderSources(resourceManager);
|
var sources = new ShaderSources(resourceManager);
|
||||||
|
SOURCES = sources;
|
||||||
var stats = new CompilerStats("ubershaders");
|
var stats = new CompilerStats("ubershaders");
|
||||||
var loader = new SourceLoader(sources, stats);
|
|
||||||
|
|
||||||
var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG);
|
var fragmentComponentsHeader = sources.get(COMPONENTS_HEADER_FRAG);
|
||||||
|
|
||||||
var fogComponent = createFogComponent(loader);
|
|
||||||
|
|
||||||
// TODO: separate compilation for cutout OFF, but keep the rest uber'd?
|
// TODO: separate compilation for cutout OFF, but keep the rest uber'd?
|
||||||
if (stats.errored() || fragmentComponentsHeader == null || fogComponent == null) {
|
if (stats.errored() || fragmentComponentsHeader == null) {
|
||||||
// Probably means the shader sources are missing.
|
// Probably means the shader sources are missing.
|
||||||
stats.emitErrorLog();
|
stats.emitErrorLog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SourceComponent> vertexComponents = List.of();
|
List<SourceComponent> vertexComponents = List.of();
|
||||||
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fogComponent);
|
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader);
|
||||||
|
|
||||||
InstancingPrograms.reload(sources, vertexComponents, fragmentComponents);
|
InstancingPrograms.reload(sources, vertexComponents, fragmentComponents);
|
||||||
IndirectPrograms.reload(sources, vertexComponents, fragmentComponents);
|
IndirectPrograms.reload(sources, vertexComponents, fragmentComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static UberShaderComponent createFogComponent(SourceLoader loader) {
|
|
||||||
return UberShaderComponent.builder(Flywheel.rl("fog"))
|
|
||||||
.materialSources(MaterialShaderIndices.fogSources()
|
|
||||||
.all())
|
|
||||||
.adapt(FnSignature.create()
|
|
||||||
.returnType("vec4")
|
|
||||||
.name("flw_fogFilter")
|
|
||||||
.arg("vec4", "color")
|
|
||||||
.build(), GlslExpr.variable("color"))
|
|
||||||
.switchOn(GlslExpr.variable("_flw_uberFogIndex"))
|
|
||||||
.build(loader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static UberShaderComponent createCutoutComponent(SourceLoader loader) {
|
|
||||||
return UberShaderComponent.builder(Flywheel.rl("cutout"))
|
|
||||||
.materialSources(MaterialShaderIndices.cutoutSources()
|
|
||||||
.all())
|
|
||||||
.adapt(FnSignature.create()
|
|
||||||
.returnType("bool")
|
|
||||||
.name("flw_discardPredicate")
|
|
||||||
.arg("vec4", "color")
|
|
||||||
.build(), GlslExpr.boolLiteral(false))
|
|
||||||
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
|
|
||||||
.build(loader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,8 @@ import com.google.common.collect.ImmutableList;
|
|||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
import dev.engine_room.flywheel.api.material.Material;
|
||||||
import dev.engine_room.flywheel.api.material.LightShader;
|
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||||
import dev.engine_room.flywheel.api.material.MaterialShaders;
|
|
||||||
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
|
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
|
||||||
import dev.engine_room.flywheel.backend.compile.component.SsboInstanceComponent;
|
import dev.engine_room.flywheel.backend.compile.component.SsboInstanceComponent;
|
||||||
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
||||||
@ -151,7 +150,19 @@ public class IndirectPrograms extends AtomicReferenceCounted {
|
|||||||
setInstance(null);
|
setInstance(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders shaders) {
|
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
|
||||||
|
var light = material.light();
|
||||||
|
var cutout = material.cutout();
|
||||||
|
var shaders = material.shaders();
|
||||||
|
var fog = material.fog();
|
||||||
|
|
||||||
|
var fogIndex = MaterialShaderIndices.fogSources();
|
||||||
|
if (fogIndex.index(fog.source()) == -1) {
|
||||||
|
fogIndex.add(fog.source());
|
||||||
|
pipeline.delete();
|
||||||
|
PipelineCompiler.createFogComponent();
|
||||||
|
}
|
||||||
|
|
||||||
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, shaders, FrameUniforms.debugOn()));
|
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, shaders, FrameUniforms.debugOn()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,8 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
import dev.engine_room.flywheel.api.material.Material;
|
||||||
import dev.engine_room.flywheel.api.material.LightShader;
|
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||||
import dev.engine_room.flywheel.api.material.MaterialShaders;
|
|
||||||
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
||||||
import dev.engine_room.flywheel.backend.gl.GlCompat;
|
import dev.engine_room.flywheel.backend.gl.GlCompat;
|
||||||
@ -74,7 +73,20 @@ public class InstancingPrograms extends AtomicReferenceCounted {
|
|||||||
setInstance(null);
|
setInstance(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders materialShaders) {
|
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
|
||||||
|
var light = material.light();
|
||||||
|
var cutout = material.cutout();
|
||||||
|
var materialShaders = material.shaders();
|
||||||
|
|
||||||
|
var fog = material.fog();
|
||||||
|
|
||||||
|
var fogIndex = MaterialShaderIndices.fogSources();
|
||||||
|
if (fogIndex.index(fog.source()) == -1) {
|
||||||
|
fogIndex.add(fog.source());
|
||||||
|
pipeline.delete();
|
||||||
|
PipelineCompiler.createFogComponent();
|
||||||
|
}
|
||||||
|
|
||||||
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, materialShaders, FrameUniforms.debugOn()));
|
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, materialShaders, FrameUniforms.debugOn()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,10 @@ import java.util.List;
|
|||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.backend.BackendConfig;
|
import dev.engine_room.flywheel.backend.BackendConfig;
|
||||||
import dev.engine_room.flywheel.backend.InternalVertex;
|
import dev.engine_room.flywheel.backend.InternalVertex;
|
||||||
|
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||||
import dev.engine_room.flywheel.backend.Samplers;
|
import dev.engine_room.flywheel.backend.Samplers;
|
||||||
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
|
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
|
||||||
|
import dev.engine_room.flywheel.backend.compile.component.UberShaderComponent;
|
||||||
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
||||||
import dev.engine_room.flywheel.backend.compile.core.Compile;
|
import dev.engine_room.flywheel.backend.compile.core.Compile;
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
||||||
@ -16,6 +18,8 @@ import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
|||||||
import dev.engine_room.flywheel.backend.gl.shader.ShaderType;
|
import dev.engine_room.flywheel.backend.gl.shader.ShaderType;
|
||||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||||
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
||||||
|
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
||||||
|
import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr;
|
||||||
import dev.engine_room.flywheel.lib.material.CutoutShaders;
|
import dev.engine_room.flywheel.lib.material.CutoutShaders;
|
||||||
import dev.engine_room.flywheel.lib.util.ResourceUtil;
|
import dev.engine_room.flywheel.lib.util.ResourceUtil;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@ -23,6 +27,9 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
public final class PipelineCompiler {
|
public final class PipelineCompiler {
|
||||||
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
||||||
|
|
||||||
|
private static UberShaderComponent FOG;
|
||||||
|
private static UberShaderComponent CUTOUT;
|
||||||
|
|
||||||
private static final ResourceLocation API_IMPL_VERT = Flywheel.rl("internal/api_impl.vert");
|
private static final ResourceLocation API_IMPL_VERT = Flywheel.rl("internal/api_impl.vert");
|
||||||
private static final ResourceLocation API_IMPL_FRAG = Flywheel.rl("internal/api_impl.frag");
|
private static final ResourceLocation API_IMPL_FRAG = Flywheel.rl("internal/api_impl.frag");
|
||||||
|
|
||||||
@ -98,6 +105,7 @@ public final class PipelineCompiler {
|
|||||||
.withResource(key -> key.materialShaders()
|
.withResource(key -> key.materialShaders()
|
||||||
.fragmentSource())
|
.fragmentSource())
|
||||||
.withComponents(fragmentComponents)
|
.withComponents(fragmentComponents)
|
||||||
|
.withComponent(key -> FOG)
|
||||||
.withResource(key -> key.light()
|
.withResource(key -> key.light()
|
||||||
.source())
|
.source())
|
||||||
.withResource(key -> key.cutout()
|
.withResource(key -> key.cutout()
|
||||||
@ -128,4 +136,30 @@ public final class PipelineCompiler {
|
|||||||
})
|
})
|
||||||
.harness(pipeline.compilerMarker(), sources);
|
.harness(pipeline.compilerMarker(), sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void createFogComponent() {
|
||||||
|
FOG = UberShaderComponent.builder(Flywheel.rl("fog"))
|
||||||
|
.materialSources(MaterialShaderIndices.fogSources()
|
||||||
|
.all())
|
||||||
|
.adapt(FnSignature.create()
|
||||||
|
.returnType("vec4")
|
||||||
|
.name("flw_fogFilter")
|
||||||
|
.arg("vec4", "color")
|
||||||
|
.build(), GlslExpr.variable("color"))
|
||||||
|
.switchOn(GlslExpr.variable("_flw_uberFogIndex"))
|
||||||
|
.build(FlwPrograms.SOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createCutoutComponent() {
|
||||||
|
CUTOUT = UberShaderComponent.builder(Flywheel.rl("cutout"))
|
||||||
|
.materialSources(MaterialShaderIndices.cutoutSources()
|
||||||
|
.all())
|
||||||
|
.adapt(FnSignature.create()
|
||||||
|
.returnType("bool")
|
||||||
|
.name("flw_discardPredicate")
|
||||||
|
.arg("vec4", "color")
|
||||||
|
.build(), GlslExpr.boolLiteral(false))
|
||||||
|
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
|
||||||
|
.build(FlwPrograms.SOURCES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.backend.compile.core.SourceLoader;
|
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||||
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
||||||
import dev.engine_room.flywheel.backend.glsl.SourceFile;
|
import dev.engine_room.flywheel.backend.glsl.SourceFile;
|
||||||
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
||||||
@ -137,7 +137,7 @@ public class UberShaderComponent implements SourceComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public UberShaderComponent build(SourceLoader sources) {
|
public UberShaderComponent build(ShaderSources sources) {
|
||||||
if (switchArg == null) {
|
if (switchArg == null) {
|
||||||
throw new NullPointerException("Switch argument must be set");
|
throw new NullPointerException("Switch argument must be set");
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ public class UberShaderComponent implements SourceComponent {
|
|||||||
boolean errored = false;
|
boolean errored = false;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (var rl : materialSources) {
|
for (var rl : materialSources) {
|
||||||
SourceFile sourceFile = sources.find(rl);
|
SourceFile sourceFile = sources.get(rl);
|
||||||
if (sourceFile != null) {
|
if (sourceFile != null) {
|
||||||
final int finalIndex = index;
|
final int finalIndex = index;
|
||||||
var adapterMap = createAdapterMap(adaptedFunctions, fnName -> "_" + fnName + "_" + finalIndex);
|
var adapterMap = createAdapterMap(adaptedFunctions, fnName -> "_" + fnName + "_" + finalIndex);
|
||||||
|
@ -5,12 +5,13 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.backend.gl.GlObject;
|
||||||
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
||||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||||
|
|
||||||
public class CompilationHarness<K> {
|
public class CompilationHarness<K> {
|
||||||
|
private final ShaderSources sources;
|
||||||
private final KeyCompiler<K> compiler;
|
private final KeyCompiler<K> compiler;
|
||||||
private final SourceLoader sourceLoader;
|
|
||||||
private final ShaderCache shaderCache;
|
private final ShaderCache shaderCache;
|
||||||
private final ProgramLinker programLinker;
|
private final ProgramLinker programLinker;
|
||||||
private final CompilerStats stats;
|
private final CompilerStats stats;
|
||||||
@ -18,9 +19,9 @@ public class CompilationHarness<K> {
|
|||||||
private final Map<K, GlProgram> programs = new HashMap<>();
|
private final Map<K, GlProgram> programs = new HashMap<>();
|
||||||
|
|
||||||
public CompilationHarness(String marker, ShaderSources sources, KeyCompiler<K> compiler) {
|
public CompilationHarness(String marker, ShaderSources sources, KeyCompiler<K> compiler) {
|
||||||
|
this.sources = sources;
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
stats = new CompilerStats(marker);
|
stats = new CompilerStats(marker);
|
||||||
sourceLoader = new SourceLoader(sources, stats);
|
|
||||||
shaderCache = new ShaderCache(stats);
|
shaderCache = new ShaderCache(stats);
|
||||||
programLinker = new ProgramLinker(stats);
|
programLinker = new ProgramLinker(stats);
|
||||||
}
|
}
|
||||||
@ -30,7 +31,7 @@ public class CompilationHarness<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private GlProgram compile(K key) {
|
private GlProgram compile(K key) {
|
||||||
var out = compiler.compile(key, sourceLoader, shaderCache, programLinker);
|
var out = compiler.compile(key, sources, shaderCache, programLinker);
|
||||||
|
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
// TODO: populate exception with error details
|
// TODO: populate exception with error details
|
||||||
@ -43,12 +44,13 @@ public class CompilationHarness<K> {
|
|||||||
public void delete() {
|
public void delete() {
|
||||||
shaderCache.delete();
|
shaderCache.delete();
|
||||||
|
|
||||||
for (var program : programs.values()) {
|
programs.values()
|
||||||
program.delete();
|
.forEach(GlObject::delete);
|
||||||
}
|
|
||||||
|
programs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface KeyCompiler<K> {
|
public interface KeyCompiler<K> {
|
||||||
@Nullable GlProgram compile(K key, SourceLoader loader, ShaderCache shaderCache, ProgramLinker programLinker);
|
@Nullable GlProgram compile(K key, ShaderSources loader, ShaderCache shaderCache, ProgramLinker programLinker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class Compile<K> {
|
|||||||
public static class ShaderCompiler<K> {
|
public static class ShaderCompiler<K> {
|
||||||
private final GlslVersion glslVersion;
|
private final GlslVersion glslVersion;
|
||||||
private final ShaderType shaderType;
|
private final ShaderType shaderType;
|
||||||
private final List<BiFunction<K, SourceLoader, @Nullable SourceComponent>> fetchers = new ArrayList<>();
|
private final List<BiFunction<K, ShaderSources, @Nullable SourceComponent>> fetchers = new ArrayList<>();
|
||||||
private BiConsumer<K, Compilation> compilationCallbacks = ($, $$) -> {
|
private BiConsumer<K, Compilation> compilationCallbacks = ($, $$) -> {
|
||||||
};
|
};
|
||||||
private Function<K, String> nameMapper = Object::toString;
|
private Function<K, String> nameMapper = Object::toString;
|
||||||
@ -59,7 +59,7 @@ public class Compile<K> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderCompiler<K> with(BiFunction<K, SourceLoader, @Nullable SourceComponent> fetch) {
|
public ShaderCompiler<K> with(BiFunction<K, ShaderSources, @Nullable SourceComponent> fetch) {
|
||||||
fetchers.add(fetch);
|
fetchers.add(fetch);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ public class Compile<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ShaderCompiler<K> withResource(Function<K, ResourceLocation> sourceFetcher) {
|
public ShaderCompiler<K> withResource(Function<K, ResourceLocation> sourceFetcher) {
|
||||||
return with((key, loader) -> loader.find(sourceFetcher.apply(key)));
|
return with((key, loader) -> loader.get(sourceFetcher.apply(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderCompiler<K> withResource(ResourceLocation resourceLocation) {
|
public ShaderCompiler<K> withResource(ResourceLocation resourceLocation) {
|
||||||
@ -123,7 +123,7 @@ public class Compile<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) {
|
private GlShader compile(K key, ShaderCache compiler, ShaderSources loader) {
|
||||||
long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
|
|
||||||
var components = new ArrayList<SourceComponent>();
|
var components = new ArrayList<SourceComponent>();
|
||||||
@ -183,7 +183,7 @@ public class Compile<K> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public GlProgram compile(K key, SourceLoader loader, ShaderCache shaderCache, ProgramLinker programLinker) {
|
public GlProgram compile(K key, ShaderSources loader, ShaderCache shaderCache, ProgramLinker programLinker) {
|
||||||
if (compilers.isEmpty()) {
|
if (compilers.isEmpty()) {
|
||||||
throw new IllegalStateException("No shader compilers were added!");
|
throw new IllegalStateException("No shader compilers were added!");
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ public class ShaderCache {
|
|||||||
.map(ShaderResult::unwrap)
|
.map(ShaderResult::unwrap)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.forEach(GlShader::delete);
|
.forEach(GlShader::delete);
|
||||||
|
inner.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void expand(List<SourceComponent> rootSources, Consumer<SourceComponent> out) {
|
private static void expand(List<SourceComponent> rootSources, Consumer<SourceComponent> out) {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.backend.compile.core;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
|
||||||
import dev.engine_room.flywheel.backend.glsl.SourceFile;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class SourceLoader {
|
|
||||||
private final ShaderSources sources;
|
|
||||||
private final CompilerStats stats;
|
|
||||||
|
|
||||||
public SourceLoader(ShaderSources sources, CompilerStats stats) {
|
|
||||||
this.sources = sources;
|
|
||||||
this.stats = stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public SourceFile find(ResourceLocation location) {
|
|
||||||
var out = sources.find(location);
|
|
||||||
stats.loadResult(out);
|
|
||||||
return out.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
@ -202,7 +202,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||||||
int baseDrawUniformLoc = -1;
|
int baseDrawUniformLoc = -1;
|
||||||
|
|
||||||
for (var multiDraw : multiDraws.get(visualType)) {
|
for (var multiDraw : multiDraws.get(visualType)) {
|
||||||
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material.light(), multiDraw.material.cutout(), multiDraw.material.shaders());
|
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material);
|
||||||
if (drawProgram != lastProgram) {
|
if (drawProgram != lastProgram) {
|
||||||
lastProgram = drawProgram;
|
lastProgram = drawProgram;
|
||||||
|
|
||||||
@ -220,7 +220,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void bindWithContextShader(ContextShader override, Material material) {
|
public void bindWithContextShader(ContextShader override, Material material) {
|
||||||
var program = programs.getIndirectProgram(instanceType, override, material.light(), material.cutout(), material.shaders());
|
var program = programs.getIndirectProgram(instanceType, override, material);
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
|||||||
|
|
||||||
for (InstancedDraw draw : instancer.draws()) {
|
for (InstancedDraw draw : instancer.draws()) {
|
||||||
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
|
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
|
||||||
var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, crumblingMaterial.light(), crumblingMaterial.cutout(), crumblingMaterial.shaders());
|
var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, crumblingMaterial);
|
||||||
program.bind();
|
program.bind();
|
||||||
program.setInt("_flw_baseInstance", index);
|
program.setInt("_flw_baseInstance", index);
|
||||||
uploadMaterialUniform(program, crumblingMaterial);
|
uploadMaterialUniform(program, crumblingMaterial);
|
||||||
|
@ -57,7 +57,7 @@ public class InstancedRenderStage {
|
|||||||
for (var drawCall : drawCalls.draws) {
|
for (var drawCall : drawCalls.draws) {
|
||||||
var material = drawCall.material();
|
var material = drawCall.material();
|
||||||
|
|
||||||
var program = programs.get(shader.instanceType(), environment.contextShader(), material.light(), material.cutout(), material.shaders());
|
var program = programs.get(shader.instanceType(), environment.contextShader(), material);
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
||||||
environment.setupDraw(program);
|
environment.setupDraw(program);
|
||||||
|
@ -9,6 +9,7 @@ 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 org.jetbrains.annotations.VisibleForTesting;
|
import org.jetbrains.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.backend.compile.FlwPrograms;
|
import dev.engine_room.flywheel.backend.compile.FlwPrograms;
|
||||||
@ -49,6 +50,11 @@ public class ShaderSources {
|
|||||||
return cache.computeIfAbsent(location, loc -> new LoadResult.Failure(new LoadError.ResourceError(loc)));
|
return cache.computeIfAbsent(location, loc -> new LoadResult.Failure(new LoadError.ResourceError(loc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public SourceFile get(ResourceLocation location) {
|
||||||
|
return find(location).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isShader(ResourceLocation loc) {
|
private static boolean isShader(ResourceLocation loc) {
|
||||||
var path = loc.getPath();
|
var path = loc.getPath();
|
||||||
return path.endsWith(".glsl") || path.endsWith(".vert") || path.endsWith(".frag") || path.endsWith(".comp");
|
return path.endsWith(".glsl") || path.endsWith(".vert") || path.endsWith(".frag") || path.endsWith(".comp");
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
package dev.engine_room.flywheel.lib.material;
|
package dev.engine_room.flywheel.lib.material;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.api.material.FogShader;
|
import dev.engine_room.flywheel.api.material.FogShader;
|
||||||
|
|
||||||
public final class FogShaders {
|
public final class FogShaders {
|
||||||
public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/none.glsl")));
|
public static final FogShader NONE = new SimpleFogShader(Flywheel.rl("fog/none.glsl"));
|
||||||
public static final FogShader LINEAR = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear.glsl")));
|
public static final FogShader LINEAR = new SimpleFogShader(Flywheel.rl("fog/linear.glsl"));
|
||||||
public static final FogShader LINEAR_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl")));
|
public static final FogShader LINEAR_FADE = new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl"));
|
||||||
|
|
||||||
private FogShaders() {
|
private FogShaders() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public static void init() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,11 @@ import dev.engine_room.flywheel.api.backend.Backend;
|
|||||||
import dev.engine_room.flywheel.api.internal.FlwApiLink;
|
import dev.engine_room.flywheel.api.internal.FlwApiLink;
|
||||||
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
|
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
|
||||||
import dev.engine_room.flywheel.api.registry.IdRegistry;
|
import dev.engine_room.flywheel.api.registry.IdRegistry;
|
||||||
import dev.engine_room.flywheel.api.registry.Registry;
|
|
||||||
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||||
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
|
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
|
||||||
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
||||||
import dev.engine_room.flywheel.impl.layout.LayoutBuilderImpl;
|
import dev.engine_room.flywheel.impl.layout.LayoutBuilderImpl;
|
||||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||||
import dev.engine_room.flywheel.impl.registry.RegistryImpl;
|
|
||||||
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
|
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||||
import dev.engine_room.flywheel.impl.visualization.VisualizerRegistryImpl;
|
import dev.engine_room.flywheel.impl.visualization.VisualizerRegistryImpl;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
@ -22,11 +20,6 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
||||||
public class FlwApiLinkImpl implements FlwApiLink {
|
public class FlwApiLinkImpl implements FlwApiLink {
|
||||||
@Override
|
|
||||||
public <T> Registry<T> createRegistry() {
|
|
||||||
return new RegistryImpl<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> IdRegistry<T> createIdRegistry() {
|
public <T> IdRegistry<T> createIdRegistry() {
|
||||||
return new IdRegistryImpl<>();
|
return new IdRegistryImpl<>();
|
||||||
|
@ -6,8 +6,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||||
import dev.engine_room.flywheel.impl.registry.RegistryImpl;
|
|
||||||
import dev.engine_room.flywheel.lib.material.FogShaders;
|
|
||||||
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
||||||
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
||||||
|
|
||||||
@ -24,7 +22,6 @@ public final class FlwImpl {
|
|||||||
|
|
||||||
// lib
|
// lib
|
||||||
ShadersModHandler.init();
|
ShadersModHandler.init();
|
||||||
FogShaders.init();
|
|
||||||
|
|
||||||
// backend
|
// backend
|
||||||
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
||||||
@ -34,7 +31,6 @@ public final class FlwImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void freezeRegistries() {
|
public static void freezeRegistries() {
|
||||||
RegistryImpl.freezeAll();
|
|
||||||
IdRegistryImpl.freezeAll();
|
IdRegistryImpl.freezeAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.impl.registry;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.UnmodifiableView;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.registry.Registry;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectList;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSets;
|
|
||||||
|
|
||||||
public class RegistryImpl<T> implements Registry<T> {
|
|
||||||
private static final ObjectList<RegistryImpl<?>> ALL = new ObjectArrayList<>();
|
|
||||||
|
|
||||||
private final ObjectSet<T> set = ObjectSets.synchronize(new ObjectOpenHashSet<>());
|
|
||||||
private final ObjectSet<T> setView = ObjectSets.unmodifiable(set);
|
|
||||||
private boolean frozen;
|
|
||||||
|
|
||||||
public RegistryImpl() {
|
|
||||||
ALL.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(T object) {
|
|
||||||
if (frozen) {
|
|
||||||
throw new IllegalStateException("Cannot register to frozen registry!");
|
|
||||||
}
|
|
||||||
boolean added = set.add(object);
|
|
||||||
if (!added) {
|
|
||||||
throw new IllegalArgumentException("Cannot override registration!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <S extends T> S registerAndGet(S object) {
|
|
||||||
register(object);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@UnmodifiableView
|
|
||||||
public Set<T> getAll() {
|
|
||||||
return setView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFrozen() {
|
|
||||||
return frozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<T> iterator() {
|
|
||||||
return getAll().iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void freeze() {
|
|
||||||
frozen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void freezeAll() {
|
|
||||||
for (RegistryImpl<?> registry : ALL) {
|
|
||||||
registry.freeze();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user