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:
Jozufozu 2024-09-28 15:29:35 -07:00
parent bce657804a
commit 11ce4ac185
21 changed files with 115 additions and 258 deletions

View File

@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
import dev.engine_room.flywheel.api.backend.Backend;
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
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.EntityVisualizer;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
@ -18,8 +17,6 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
public interface FlwApiLink {
FlwApiLink INSTANCE = DependencyInjection.load(FlwApiLink.class, "dev.engine_room.flywheel.impl.FlwApiLinkImpl");
<T> Registry<T> createRegistry();
<T> IdRegistry<T> createIdRegistry();
Backend getCurrentBackend();

View File

@ -1,11 +1,7 @@
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;
public interface FogShader {
Registry<FogShader> REGISTRY = FlwApiLink.INSTANCE.createRegistry();
ResourceLocation source();
}

View File

@ -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();
}

View File

@ -1,14 +1,11 @@
package dev.engine_room.flywheel.backend;
import java.util.List;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import dev.engine_room.flywheel.api.material.CutoutShader;
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.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -16,25 +13,17 @@ import it.unimi.dsi.fastutil.objects.ObjectList;
import net.minecraft.resources.ResourceLocation;
public final class MaterialShaderIndices {
@Nullable
private static Index fogSources;
@Nullable
private static Index cutoutSources;
private static final Index fogSources = new Index();
private static final Index cutoutSources = new Index();
private MaterialShaderIndices() {
}
public static Index fogSources() {
if (fogSources == null) {
fogSources = indexFromRegistry(FogShader.REGISTRY, FogShader::source);
}
return fogSources;
}
public static Index cutoutSources() {
// if (cutoutSources == null) {
// cutoutSources = indexFromRegistry(CutoutShader.REGISTRY, CutoutShader::source);
// }
return cutoutSources;
}
@ -43,30 +32,23 @@ public final class MaterialShaderIndices {
}
public static int cutoutIndex(CutoutShader cutoutShader) {
return 0;//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();
return cutoutSources().index(cutoutShader.source());
}
public static class Index {
private final Object2IntMap<ResourceLocation> sources2Index;
private final ObjectList<ResourceLocation> sources;
private Index(IndexBuilder builder) {
this.sources2Index = new Object2IntOpenHashMap<>(builder.sources2Index);
this.sources = new ObjectArrayList<>(builder.sources);
private Index() {
this.sources2Index = new Object2IntOpenHashMap<>();
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) {
@ -82,27 +64,4 @@ public final class MaterialShaderIndices {
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);
}
}
}

View File

@ -2,19 +2,13 @@ package dev.engine_room.flywheel.backend.compile;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.SourceLoader;
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
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.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");
public static ShaderSources SOURCES;
private FlwPrograms() {
}
@ -32,52 +28,22 @@ public final class FlwPrograms {
IndirectPrograms.setInstance(null);
var sources = new ShaderSources(resourceManager);
SOURCES = sources;
var stats = new CompilerStats("ubershaders");
var loader = new SourceLoader(sources, stats);
var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG);
var fogComponent = createFogComponent(loader);
var fragmentComponentsHeader = sources.get(COMPONENTS_HEADER_FRAG);
// 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.
stats.emitErrorLog();
return;
}
List<SourceComponent> vertexComponents = List.of();
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fogComponent);
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader);
InstancingPrograms.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);
}
}

View File

@ -8,9 +8,8 @@ import com.google.common.collect.ImmutableList;
import dev.engine_room.flywheel.api.Flywheel;
import dev.engine_room.flywheel.api.instance.InstanceType;
import dev.engine_room.flywheel.api.material.CutoutShader;
import dev.engine_room.flywheel.api.material.LightShader;
import dev.engine_room.flywheel.api.material.MaterialShaders;
import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
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.core.CompilationHarness;
@ -151,7 +150,19 @@ public class IndirectPrograms extends AtomicReferenceCounted {
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()));
}

View File

@ -7,9 +7,8 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import dev.engine_room.flywheel.api.instance.InstanceType;
import dev.engine_room.flywheel.api.material.CutoutShader;
import dev.engine_room.flywheel.api.material.LightShader;
import dev.engine_room.flywheel.api.material.MaterialShaders;
import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
import dev.engine_room.flywheel.backend.gl.GlCompat;
@ -74,7 +73,20 @@ public class InstancingPrograms extends AtomicReferenceCounted {
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()));
}

View File

@ -6,8 +6,10 @@ import java.util.List;
import dev.engine_room.flywheel.api.Flywheel;
import dev.engine_room.flywheel.backend.BackendConfig;
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.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.Compile;
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.glsl.ShaderSources;
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.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
@ -23,6 +27,9 @@ import net.minecraft.resources.ResourceLocation;
public final class PipelineCompiler {
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_FRAG = Flywheel.rl("internal/api_impl.frag");
@ -98,6 +105,7 @@ public final class PipelineCompiler {
.withResource(key -> key.materialShaders()
.fragmentSource())
.withComponents(fragmentComponents)
.withComponent(key -> FOG)
.withResource(key -> key.light()
.source())
.withResource(key -> key.cutout()
@ -128,4 +136,30 @@ public final class PipelineCompiler {
})
.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);
}
}

View File

@ -11,7 +11,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
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.SourceFile;
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
@ -137,7 +137,7 @@ public class UberShaderComponent implements SourceComponent {
}
@Nullable
public UberShaderComponent build(SourceLoader sources) {
public UberShaderComponent build(ShaderSources sources) {
if (switchArg == null) {
throw new NullPointerException("Switch argument must be set");
}
@ -147,7 +147,7 @@ public class UberShaderComponent implements SourceComponent {
boolean errored = false;
int index = 0;
for (var rl : materialSources) {
SourceFile sourceFile = sources.find(rl);
SourceFile sourceFile = sources.get(rl);
if (sourceFile != null) {
final int finalIndex = index;
var adapterMap = createAdapterMap(adaptedFunctions, fnName -> "_" + fnName + "_" + finalIndex);

View File

@ -5,12 +5,13 @@ import java.util.Map;
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.glsl.ShaderSources;
public class CompilationHarness<K> {
private final ShaderSources sources;
private final KeyCompiler<K> compiler;
private final SourceLoader sourceLoader;
private final ShaderCache shaderCache;
private final ProgramLinker programLinker;
private final CompilerStats stats;
@ -18,9 +19,9 @@ public class CompilationHarness<K> {
private final Map<K, GlProgram> programs = new HashMap<>();
public CompilationHarness(String marker, ShaderSources sources, KeyCompiler<K> compiler) {
this.sources = sources;
this.compiler = compiler;
stats = new CompilerStats(marker);
sourceLoader = new SourceLoader(sources, stats);
shaderCache = new ShaderCache(stats);
programLinker = new ProgramLinker(stats);
}
@ -30,7 +31,7 @@ public class CompilationHarness<K> {
}
private GlProgram compile(K key) {
var out = compiler.compile(key, sourceLoader, shaderCache, programLinker);
var out = compiler.compile(key, sources, shaderCache, programLinker);
if (out == null) {
// TODO: populate exception with error details
@ -43,12 +44,13 @@ public class CompilationHarness<K> {
public void delete() {
shaderCache.delete();
for (var program : programs.values()) {
program.delete();
}
programs.values()
.forEach(GlObject::delete);
programs.clear();
}
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);
}
}

View File

@ -44,7 +44,7 @@ public class Compile<K> {
public static class ShaderCompiler<K> {
private final GlslVersion glslVersion;
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 Function<K, String> nameMapper = Object::toString;
@ -59,7 +59,7 @@ public class Compile<K> {
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);
return this;
}
@ -78,7 +78,7 @@ public class Compile<K> {
}
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) {
@ -123,7 +123,7 @@ public class Compile<K> {
}
@Nullable
private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) {
private GlShader compile(K key, ShaderCache compiler, ShaderSources loader) {
long start = System.nanoTime();
var components = new ArrayList<SourceComponent>();
@ -183,7 +183,7 @@ public class Compile<K> {
@Override
@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()) {
throw new IllegalStateException("No shader compilers were added!");
}

View File

@ -51,6 +51,7 @@ public class ShaderCache {
.map(ShaderResult::unwrap)
.filter(Objects::nonNull)
.forEach(GlShader::delete);
inner.clear();
}
private static void expand(List<SourceComponent> rootSources, Consumer<SourceComponent> out) {

View File

@ -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();
}
}

View File

@ -202,7 +202,7 @@ public class IndirectCullingGroup<I extends Instance> {
int baseDrawUniformLoc = -1;
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) {
lastProgram = drawProgram;
@ -220,7 +220,7 @@ public class IndirectCullingGroup<I extends Instance> {
}
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();

View File

@ -174,7 +174,7 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
for (InstancedDraw draw : instancer.draws()) {
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.setInt("_flw_baseInstance", index);
uploadMaterialUniform(program, crumblingMaterial);

View File

@ -57,7 +57,7 @@ public class InstancedRenderStage {
for (var drawCall : drawCalls.draws) {
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();
environment.setupDraw(program);

View File

@ -9,6 +9,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
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)));
}
@Nullable
public SourceFile get(ResourceLocation location) {
return find(location).unwrap();
}
private static boolean isShader(ResourceLocation loc) {
var path = loc.getPath();
return path.endsWith(".glsl") || path.endsWith(".vert") || path.endsWith(".frag") || path.endsWith(".comp");

View File

@ -1,19 +1,13 @@
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.material.FogShader;
public final class FogShaders {
public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(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_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl")));
public static final FogShader NONE = new SimpleFogShader(Flywheel.rl("fog/none.glsl"));
public static final FogShader LINEAR = new SimpleFogShader(Flywheel.rl("fog/linear.glsl"));
public static final FogShader LINEAR_FADE = new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl"));
private FogShaders() {
}
@ApiStatus.Internal
public static void init() {
}
}

View File

@ -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.layout.LayoutBuilder;
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.EntityVisualizer;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.impl.layout.LayoutBuilderImpl;
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.VisualizerRegistryImpl;
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;
public class FlwApiLinkImpl implements FlwApiLink {
@Override
public <T> Registry<T> createRegistry() {
return new RegistryImpl<>();
}
@Override
public <T> IdRegistry<T> createIdRegistry() {
return new IdRegistryImpl<>();

View File

@ -6,8 +6,6 @@ import org.slf4j.LoggerFactory;
import dev.engine_room.flywheel.api.Flywheel;
import dev.engine_room.flywheel.backend.FlwBackend;
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.vanilla.VanillaVisuals;
@ -24,7 +22,6 @@ public final class FlwImpl {
// lib
ShadersModHandler.init();
FogShaders.init();
// backend
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
@ -34,7 +31,6 @@ public final class FlwImpl {
}
public static void freezeRegistries() {
RegistryImpl.freezeAll();
IdRegistryImpl.freezeAll();
}
}

View File

@ -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();
}
}
}