mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-06 18:24:59 +01:00
Registry refactors and namespaced backends
This commit is contained in:
parent
59773125b2
commit
2c010ffa06
111 changed files with 1214 additions and 884 deletions
|
@ -3,17 +3,21 @@ package com.jozufozu.flywheel;
|
|||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.backend.Loader;
|
||||
import com.jozufozu.flywheel.backend.engine.batching.DrawBuffer;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.config.BackendTypeArgument;
|
||||
import com.jozufozu.flywheel.config.BackendArgument;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.handler.EntityWorldHandler;
|
||||
import com.jozufozu.flywheel.handler.ForgeEvents;
|
||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||
import com.jozufozu.flywheel.impl.IdRegistryImpl;
|
||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||
import com.jozufozu.flywheel.lib.backend.Backends;
|
||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||
import com.jozufozu.flywheel.lib.format.Formats;
|
||||
import com.jozufozu.flywheel.lib.material.MaterialIndicies;
|
||||
import com.jozufozu.flywheel.lib.material.Materials;
|
||||
import com.jozufozu.flywheel.lib.model.Models;
|
||||
import com.jozufozu.flywheel.lib.model.PartialModel;
|
||||
|
@ -61,7 +65,7 @@ public class Flywheel {
|
|||
.getModEventBus();
|
||||
modEventBus.addListener(Flywheel::setup);
|
||||
|
||||
FlwConfig.init();
|
||||
FlwConfig.get().registerSpecs(modLoadingContext);
|
||||
|
||||
modLoadingContext.registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(
|
||||
() -> NetworkConstants.IGNORESERVERONLY,
|
||||
|
@ -72,12 +76,6 @@ public class Flywheel {
|
|||
}
|
||||
|
||||
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor);
|
||||
|
||||
ShadersModHandler.init();
|
||||
BackendTypes.init();
|
||||
Backend.init();
|
||||
|
||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||
|
||||
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onReloadRenderers);
|
||||
|
@ -102,14 +100,23 @@ public class Flywheel {
|
|||
// forgeEventBus.addListener(ExampleEffect::tick);
|
||||
// forgeEventBus.addListener(ExampleEffect::onReload);
|
||||
|
||||
ShadersModHandler.init();
|
||||
|
||||
Backends.init();
|
||||
Loader.init();
|
||||
|
||||
Formats.init();
|
||||
StructTypes.init();
|
||||
Materials.init();
|
||||
Contexts.init();
|
||||
Pipelines.init();
|
||||
|
||||
MaterialIndicies.init();
|
||||
|
||||
VanillaInstances.init();
|
||||
|
||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManager::getBackendDescriptor);
|
||||
|
||||
// https://github.com/Jozufozu/Flywheel/issues/69
|
||||
// Weird issue with accessor loading.
|
||||
// Only thing I've seen that's close to a fix is to force the class to load before trying to use it.
|
||||
|
@ -119,7 +126,10 @@ public class Flywheel {
|
|||
}
|
||||
|
||||
private static void setup(final FMLCommonSetupEvent event) {
|
||||
ArgumentTypes.register(rl("engine").toString(), BackendTypeArgument.class, new EmptyArgumentSerializer<>(BackendTypeArgument::getInstance));
|
||||
ArgumentTypes.register(rl("backend").toString(), BackendArgument.class, new EmptyArgumentSerializer<>(BackendArgument::getInstance));
|
||||
|
||||
RegistryImpl.freezeAll();
|
||||
IdRegistryImpl.freezeAll();
|
||||
}
|
||||
|
||||
public static ArtifactVersion getVersion() {
|
||||
|
|
26
src/main/java/com/jozufozu/flywheel/api/backend/Backend.java
Normal file
26
src/main/java/com/jozufozu/flywheel/api/backend/Backend.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package com.jozufozu.flywheel.api.backend;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.api.registry.IdRegistry;
|
||||
import com.jozufozu.flywheel.impl.IdRegistryImpl;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public interface Backend {
|
||||
static IdRegistry<Backend> REGISTRY = IdRegistryImpl.create();
|
||||
|
||||
// TODO: remove and use ID instead? Currently this is only used for the crash log string.
|
||||
String getProperName();
|
||||
|
||||
Component getEngineMessage();
|
||||
|
||||
Engine createEngine();
|
||||
|
||||
Backend findFallback();
|
||||
|
||||
boolean isSupported();
|
||||
|
||||
@Nullable Pipeline pipelineShader();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.jozufozu.flywheel.api.backend;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.impl.BackendManagerImpl;
|
||||
|
||||
public final class BackendManager {
|
||||
/**
|
||||
* Get the current backend.
|
||||
*/
|
||||
@Nullable
|
||||
public static Backend getBackend() {
|
||||
return BackendManagerImpl.getBackend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string describing the current backend.
|
||||
*/
|
||||
public static String getBackendDescriptor() {
|
||||
return BackendManagerImpl.getBackendDescriptor();
|
||||
}
|
||||
|
||||
public static boolean isOn() {
|
||||
return BackendManagerImpl.isOn();
|
||||
}
|
||||
|
||||
// TODO: definitively sort existing calls to this method into API (include behavior in javadoc) or default backend code
|
||||
public static void refresh() {
|
||||
BackendManagerImpl.refresh();
|
||||
}
|
||||
|
||||
public static Backend getDefaultBackend() {
|
||||
return BackendManagerImpl.getDefaultBackend();
|
||||
}
|
||||
|
||||
private BackendManager() {
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.backend;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public interface BackendType {
|
||||
|
||||
String getProperName();
|
||||
|
||||
String getShortName();
|
||||
|
||||
Component getEngineMessage();
|
||||
|
||||
Engine createEngine();
|
||||
|
||||
BackendType findFallback();
|
||||
|
||||
boolean supported();
|
||||
|
||||
@Nullable Pipeline pipelineShader();
|
||||
}
|
|
@ -2,10 +2,10 @@ package com.jozufozu.flywheel.api.backend;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
|
||||
public interface Engine extends RenderDispatcher, InstancerManager {
|
||||
public interface Engine extends RenderDispatcher, InstancerProvider {
|
||||
void attachManagers(InstanceManager<?>... listener);
|
||||
|
||||
void addDebugInfo(List<String> info);
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.context.Context;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class ComponentRegistry {
|
||||
private static final Registry<ShaderUniforms> uniformProviders = new Registry<>();
|
||||
|
||||
public static final MaterialRegistry materials = new MaterialRegistry();
|
||||
public static final Set<StructType<?>> structTypes = new HashSet<>();
|
||||
public static final Set<VertexType> vertexTypes = new HashSet<>();
|
||||
public static final Set<Context> contextShaders = new HashSet<>();
|
||||
|
||||
// TODO: fill out the rest of the registry
|
||||
|
||||
public static <T extends Material> T register(T material) {
|
||||
return materials.add(material);
|
||||
}
|
||||
|
||||
public static <T extends StructType<?>> T register(T type) {
|
||||
structTypes.add(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
public static <T extends VertexType> T register(T vertexType) {
|
||||
vertexTypes.add(vertexType);
|
||||
return vertexType;
|
||||
}
|
||||
|
||||
public static <T extends Context> T register(T contextShader) {
|
||||
contextShaders.add(contextShader);
|
||||
return contextShader;
|
||||
}
|
||||
|
||||
public static <T extends ShaderUniforms> T register(T provider) {
|
||||
return uniformProviders.register(provider.uniformShader(), provider);
|
||||
}
|
||||
|
||||
public static Collection<ShaderUniforms> getAllUniformProviders() {
|
||||
return Collections.unmodifiableCollection(uniformProviders.objects);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ShaderUniforms getUniformProvider(ResourceLocation loc) {
|
||||
return uniformProviders.get(loc);
|
||||
}
|
||||
|
||||
private static class Registry<T> {
|
||||
private final Map<ResourceLocation, T> files = new HashMap<>();
|
||||
private final List<T> objects = new ArrayList<>();
|
||||
|
||||
public <O extends T> O register(ResourceLocation loc, O object) {
|
||||
if (files.containsKey(loc)) {
|
||||
throw new IllegalArgumentException("Shader file already registered: " + loc);
|
||||
}
|
||||
files.put(loc, object);
|
||||
objects.add(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T get(ResourceLocation loc) {
|
||||
return files.get(loc);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MaterialRegistry {
|
||||
|
||||
private final Set<Material> materials = new HashSet<>();
|
||||
private final List<Material> materialsOrdered = new ArrayList<>();
|
||||
private final MaterialSources vertexSources = new MaterialSources();
|
||||
private final MaterialSources fragmentSources = new MaterialSources();
|
||||
|
||||
public <T extends Material> T add(T material) {
|
||||
if (materials.add(material)) {
|
||||
materialsOrdered.add(material);
|
||||
vertexSources.register(material.vertexShader());
|
||||
fragmentSources.register(material.fragmentShader());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Material already registered: " + material);
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of vertex shader sources where the index in the list is the shader's ID.
|
||||
*/
|
||||
public List<ResourceLocation> vertexSources() {
|
||||
return vertexSources.sourceView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of fragment shader sources where the index in the list is the shader's ID.
|
||||
*/
|
||||
public List<ResourceLocation> fragmentSources() {
|
||||
return fragmentSources.sourceView;
|
||||
}
|
||||
|
||||
public int getVertexID(Material material) {
|
||||
return vertexSources.orderedSources.indexOf(material.vertexShader());
|
||||
}
|
||||
|
||||
public int getFragmentID(Material material) {
|
||||
return fragmentSources.orderedSources.indexOf(material.fragmentShader());
|
||||
}
|
||||
|
||||
public int getMaterialID(Material material) {
|
||||
return materialsOrdered.indexOf(material);
|
||||
}
|
||||
|
||||
private static class MaterialSources {
|
||||
private final Set<ResourceLocation> registered = new HashSet<>();
|
||||
private final List<ResourceLocation> orderedSources = new ArrayList<>();
|
||||
private final List<ResourceLocation> sourceView = Collections.unmodifiableList(orderedSources);
|
||||
|
||||
public void register(ResourceLocation vertexShader) {
|
||||
if (registered.add(vertexShader)) {
|
||||
orderedSources.add(vertexShader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.component;
|
||||
|
||||
public enum ComponentType {
|
||||
MATERIAL,
|
||||
INSTANCE,
|
||||
LAYOUT,
|
||||
CONTEXT,
|
||||
UNIFORM_PROVIDER
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package com.jozufozu.flywheel.api.context;
|
||||
|
||||
import com.jozufozu.flywheel.api.registry.Registry;
|
||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface Context {
|
||||
static Registry<Context> REGISTRY = RegistryImpl.create();
|
||||
|
||||
void onProgramLink(GlProgram program);
|
||||
|
||||
ResourceLocation vertexShader();
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
package com.jozufozu.flywheel.backend.instancing;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
package com.jozufozu.flywheel.api.instance;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.SimpleBlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.SimpleEntityInstancingController;
|
||||
import com.jozufozu.flywheel.extension.BlockEntityTypeExtension;
|
||||
import com.jozufozu.flywheel.extension.EntityTypeExtension;
|
||||
|
||||
|
@ -54,7 +48,7 @@ public class InstancedRenderRegistry {
|
|||
* @return An instance of the block entity, or {@code null} if the block entity cannot be instanced.
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends BlockEntity> BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity) {
|
||||
public static <T extends BlockEntity> BlockEntityInstance<? super T> createInstance(InstancerProvider instancerManager, T blockEntity) {
|
||||
BlockEntityInstancingController<? super T> controller = getController(getType(blockEntity));
|
||||
if (controller == null) {
|
||||
return null;
|
||||
|
@ -70,7 +64,7 @@ public class InstancedRenderRegistry {
|
|||
* @return An instance of the entity, or {@code null} if the entity cannot be instanced.
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends Entity> EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity) {
|
||||
public static <T extends Entity> EntityInstance<? super T> createInstance(InstancerProvider instancerManager, T entity) {
|
||||
EntityInstancingController<? super T> controller = getController(getType(entity));
|
||||
if (controller == null) {
|
||||
return null;
|
||||
|
@ -106,26 +100,6 @@ public class InstancedRenderRegistry {
|
|||
return controller.shouldSkipRender(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object to configure the instancing controller for the given block entity type.
|
||||
* @param type The block entity type to configure.
|
||||
* @param <T> The type of the block entity.
|
||||
* @return The configuration object.
|
||||
*/
|
||||
public static <T extends BlockEntity> BlockEntityConfig<T> configure(BlockEntityType<T> type) {
|
||||
return new BlockEntityConfig<>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object to configure the instancing controller for the given entity type.
|
||||
* @param type The entity type to configure.
|
||||
* @param <T> The type of the entity.
|
||||
* @return The configuration object.
|
||||
*/
|
||||
public static <T extends Entity> EntityConfig<T> configure(EntityType<T> type) {
|
||||
return new EntityConfig<>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instancing controller for the given block entity type, if one exists.
|
||||
* @param type The block entity type to get the instancing controller for.
|
||||
|
@ -187,118 +161,4 @@ public class InstancedRenderRegistry {
|
|||
public static <T extends Entity> EntityType<? super T> getType(T entity) {
|
||||
return (EntityType<? super T>) entity.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* An object to configure the instancing controller for a block entity.
|
||||
* @param <T> The type of the block entity.
|
||||
*/
|
||||
public static class BlockEntityConfig<T extends BlockEntity> {
|
||||
protected BlockEntityType<T> type;
|
||||
protected BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public BlockEntityConfig(BlockEntityType<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance factory for the block entity.
|
||||
* @param instanceFactory The instance factory.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public BlockEntityConfig<T> factory(BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to determine whether to skip rendering a block entity.
|
||||
* @param skipRender The predicate.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public BlockEntityConfig<T> skipRender(Predicate<T> skipRender) {
|
||||
this.skipRender = skipRender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to always skip rendering for block entities of this type.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public BlockEntityConfig<T> alwaysSkipRender() {
|
||||
this.skipRender = be -> true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the block entity instancing controller, and sets it for the block entity type.
|
||||
* @return The block entity instancing controller.
|
||||
*/
|
||||
public SimpleBlockEntityInstancingController<T> apply() {
|
||||
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
|
||||
if (skipRender == null) {
|
||||
skipRender = be -> false;
|
||||
}
|
||||
SimpleBlockEntityInstancingController<T> controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender);
|
||||
setController(type, controller);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An object to configure the instancing controller for an entity.
|
||||
* @param <T> The type of the entity.
|
||||
*/
|
||||
public static class EntityConfig<T extends Entity> {
|
||||
protected EntityType<T> type;
|
||||
protected BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public EntityConfig(EntityType<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance factory for the entity.
|
||||
* @param instanceFactory The instance factory.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public EntityConfig<T> factory(BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to determine whether to skip rendering an entity.
|
||||
* @param skipRender The predicate.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public EntityConfig<T> skipRender(Predicate<T> skipRender) {
|
||||
this.skipRender = skipRender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to always skip rendering for entities of this type.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public EntityConfig<T> alwaysSkipRender() {
|
||||
this.skipRender = entity -> true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the entity instancing controller, and sets it for the entity type.
|
||||
* @return The entity instancing controller.
|
||||
*/
|
||||
public SimpleEntityInstancingController<T> apply() {
|
||||
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
|
||||
if (skipRender == null) {
|
||||
skipRender = entity -> false;
|
||||
}
|
||||
SimpleEntityInstancingController<T> controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender);
|
||||
setController(type, controller);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||
package com.jozufozu.flywheel.api.instance.blockentity;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
/**
|
||||
* An instancing controller that will be keyed to a block entity type.
|
||||
* @param <T> The type of block entity this controller is for.
|
||||
* @param <T> The block entity type.
|
||||
*/
|
||||
public interface BlockEntityInstancingController<T extends BlockEntity> {
|
||||
/**
|
||||
|
@ -15,7 +16,7 @@ public interface BlockEntityInstancingController<T extends BlockEntity> {
|
|||
* @param blockEntity The block entity to construct an instance for.
|
||||
* @return The instance.
|
||||
*/
|
||||
BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity);
|
||||
BlockEntityInstance<? super T> createInstance(InstancerProvider instancerManager, T blockEntity);
|
||||
|
||||
/**
|
||||
* Checks if the given block entity should not be rendered normally.
|
|
@ -1,6 +1,7 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||
package com.jozufozu.flywheel.api.instance.entity;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
|
@ -15,7 +16,7 @@ public interface EntityInstancingController<T extends Entity> {
|
|||
* @param entity The entity to construct an instance for.
|
||||
* @return The instance.
|
||||
*/
|
||||
EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity);
|
||||
EntityInstance<? super T> createInstance(InstancerProvider instancerManager, T entity);
|
||||
|
||||
/**
|
||||
* Checks if the given entity should not render normally.
|
|
@ -1,20 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.instancer;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.model.Model;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public interface InstancerManager {
|
||||
|
||||
/**
|
||||
* Get an instancer for the given struct type and model. Calling this method twice with the same arguments will return the same instancer.
|
||||
*
|
||||
* @return An instancer for the given struct type and model.
|
||||
*/
|
||||
<D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model, RenderStage stage);
|
||||
|
||||
Vec3i getOriginCoordinate();
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.jozufozu.flywheel.api.instancer;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.model.Model;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public interface InstancerProvider {
|
||||
/**
|
||||
* Get an instancer for the given struct type, model, and render stage. Calling this method twice with the same arguments will return the same instancer.
|
||||
*
|
||||
* @return An instancer for the given struct type, model, and render stage.
|
||||
*/
|
||||
<D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model, RenderStage stage);
|
||||
|
||||
// TODO: this method does not belong in the interface
|
||||
Vec3i getOriginCoordinate();
|
||||
}
|
|
@ -5,7 +5,6 @@ import java.util.List;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.gl.array.VertexAttribute;
|
||||
import com.jozufozu.flywheel.lib.layout.LayoutItem;
|
||||
|
||||
/**
|
||||
* Classic Vertex Format struct with a clever name.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.lib.layout;
|
||||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.InputType;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslStruct;
|
||||
|
|
@ -1,12 +1,16 @@
|
|||
package com.jozufozu.flywheel.api.material;
|
||||
|
||||
import com.jozufozu.flywheel.api.registry.Registry;
|
||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface Material {
|
||||
static Registry<Material> REGISTRY = RegistryImpl.create();
|
||||
|
||||
ResourceLocation vertexShader();
|
||||
|
||||
ResourceLocation fragmentShader();
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.joml.Vector4fc;
|
|||
|
||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.engine.instancing.ElementBuffer;
|
||||
import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
|
||||
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.jozufozu.flywheel.api.struct.StructType;
|
|||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.jozufozu.flywheel.api.registry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface IdRegistry<T> extends Iterable<T> {
|
||||
void register(ResourceLocation id, T object);
|
||||
|
||||
<S extends T> S registerAndGet(ResourceLocation id, S object);
|
||||
|
||||
@Nullable
|
||||
T get(ResourceLocation id);
|
||||
|
||||
@Nullable
|
||||
ResourceLocation getId(T object);
|
||||
|
||||
@Unmodifiable
|
||||
Set<ResourceLocation> getAllIds();
|
||||
|
||||
@Unmodifiable
|
||||
Collection<T> getAll();
|
||||
|
||||
void addFreezeCallback(Runnable callback);
|
||||
|
||||
boolean isFrozen();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.jozufozu.flywheel.api.registry;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface Registry<T> extends Iterable<T> {
|
||||
void register(T object);
|
||||
|
||||
<S extends T> S registerAndGet(S object);
|
||||
|
||||
@Unmodifiable
|
||||
Set<T> getAll();
|
||||
|
||||
void addFreezeCallback(Runnable callback);
|
||||
|
||||
boolean isFrozen();
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.struct;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
|
||||
public interface StorageBufferWriter<T extends InstancedPart> {
|
||||
|
||||
void write(final long ptr, final T instance);
|
||||
|
||||
int getAlignment();
|
||||
}
|
|
@ -2,7 +2,9 @@ package com.jozufozu.flywheel.api.struct;
|
|||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.api.registry.Registry;
|
||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -12,6 +14,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||
* @param <S> The java representation of the instance struct.
|
||||
*/
|
||||
public interface StructType<S extends InstancedPart> {
|
||||
static Registry<StructType<?>> REGISTRY = RegistryImpl.create();
|
||||
|
||||
/**
|
||||
* @return A new, zeroed instance of S.
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package com.jozufozu.flywheel.api.uniform;
|
||||
|
||||
import com.jozufozu.flywheel.api.registry.Registry;
|
||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface ShaderUniforms {
|
||||
static Registry<ShaderUniforms> REGISTRY = RegistryImpl.createForShaderUniforms();
|
||||
|
||||
Provider activate(long ptr);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.jozufozu.flywheel.api.vertex;
|
||||
|
||||
import com.jozufozu.flywheel.backend.vertex.InferredVertexListProviderImpl;
|
||||
import com.jozufozu.flywheel.extension.VertexFormatExtension;
|
||||
import com.jozufozu.flywheel.impl.vertex.InferredVertexListProviderImpl;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
public interface VertexListProvider {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.jozufozu.flywheel.api.vertex;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.api.registry.Registry;
|
||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
|
@ -8,6 +10,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||
* A vertex type containing metadata about a specific vertex layout.
|
||||
*/
|
||||
public interface VertexType extends VertexListProvider {
|
||||
static Registry<VertexType> REGISTRY = RegistryImpl.create();
|
||||
|
||||
/**
|
||||
* The layout of this type of vertex when buffered.
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.api.FlywheelLevel;
|
||||
import com.jozufozu.flywheel.api.backend.BackendType;
|
||||
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
public class Backend {
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static final boolean DUMP_SHADER_SOURCE = System.getProperty("flw.dumpShaderSource") != null;
|
||||
|
||||
private static BackendType TYPE;
|
||||
|
||||
private static ParallelTaskExecutor EXECUTOR;
|
||||
|
||||
private static final Loader LOADER = new Loader();
|
||||
|
||||
/**
|
||||
* Get the current Flywheel backend type.
|
||||
*/
|
||||
public static BackendType getBackendType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a thread pool for running Flywheel related work in parallel.
|
||||
* @return A global Flywheel thread pool.
|
||||
*/
|
||||
public static ParallelTaskExecutor getTaskExecutor() {
|
||||
if (EXECUTOR == null) {
|
||||
EXECUTOR = new ParallelTaskExecutor("Flywheel");
|
||||
EXECUTOR.startWorkers();
|
||||
}
|
||||
|
||||
return EXECUTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string describing the Flywheel backend. When there are eventually multiple backends
|
||||
* (Meshlet, MDI, GL31 Draw Instanced are planned), this will name which one is in use.
|
||||
*/
|
||||
public static String getBackendDescriptor() {
|
||||
return TYPE == null ? "Uninitialized" : TYPE.getProperName();
|
||||
}
|
||||
|
||||
public static void refresh() {
|
||||
TYPE = chooseEngine();
|
||||
}
|
||||
|
||||
public static boolean isOn() {
|
||||
return TYPE != BackendTypes.OFF;
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
public static boolean canUseInstancing(@Nullable Level level) {
|
||||
return isOn() && isFlywheelLevel(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to avoid calling Flywheel functions on (fake) levels that don't specifically support it.
|
||||
*/
|
||||
public static boolean isFlywheelLevel(@Nullable LevelAccessor level) {
|
||||
if (level == null) return false;
|
||||
|
||||
if (!level.isClientSide()) return false;
|
||||
|
||||
if (level instanceof FlywheelLevel && ((FlywheelLevel) level).supportsFlywheel()) return true;
|
||||
|
||||
return level == Minecraft.getInstance().level;
|
||||
}
|
||||
|
||||
public static boolean isGameActive() {
|
||||
return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null);
|
||||
}
|
||||
|
||||
public static void reloadWorldRenderers() {
|
||||
Minecraft.getInstance().levelRenderer.allChanged();
|
||||
}
|
||||
|
||||
private static BackendType chooseEngine() {
|
||||
var preferred = FlwConfig.get()
|
||||
.getBackendType();
|
||||
if (preferred == null) {
|
||||
return BackendTypes.defaultForCurrentPC();
|
||||
}
|
||||
var actual = preferred.findFallback();
|
||||
|
||||
if (preferred != actual) {
|
||||
LOGGER.warn("Flywheel backend fell back from '{}' to '{}'", preferred.getShortName(), actual.getShortName());
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
}
|
||||
|
||||
private Backend() {
|
||||
throw new UnsupportedOperationException("Backend is a static class!");
|
||||
}
|
||||
|
||||
}
|
57
src/main/java/com/jozufozu/flywheel/backend/BackendUtil.java
Normal file
57
src/main/java/com/jozufozu/flywheel/backend/BackendUtil.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.FlywheelLevel;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
public class BackendUtil {
|
||||
public static final boolean DUMP_SHADER_SOURCE = System.getProperty("flw.dumpShaderSource") != null;
|
||||
|
||||
private static ParallelTaskExecutor executor;
|
||||
|
||||
/**
|
||||
* Get a thread pool for running Flywheel related work in parallel.
|
||||
* @return A global Flywheel thread pool.
|
||||
*/
|
||||
public static ParallelTaskExecutor getTaskExecutor() {
|
||||
if (executor == null) {
|
||||
executor = new ParallelTaskExecutor("Flywheel");
|
||||
executor.startWorkers();
|
||||
}
|
||||
|
||||
return executor;
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
public static boolean canUseInstancing(@Nullable Level level) {
|
||||
return BackendManager.isOn() && isFlywheelLevel(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to avoid calling Flywheel functions on (fake) levels that don't specifically support it.
|
||||
*/
|
||||
public static boolean isFlywheelLevel(@Nullable LevelAccessor level) {
|
||||
if (level == null) return false;
|
||||
|
||||
if (!level.isClientSide()) return false;
|
||||
|
||||
if (level instanceof FlywheelLevel && ((FlywheelLevel) level).supportsFlywheel()) return true;
|
||||
|
||||
return level == Minecraft.getInstance().level;
|
||||
}
|
||||
|
||||
public static boolean isGameActive() {
|
||||
return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null);
|
||||
}
|
||||
|
||||
public static void reloadWorldRenderers() {
|
||||
Minecraft.getInstance().levelRenderer.allChanged();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||
|
@ -19,22 +20,14 @@ import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
|||
* </p>
|
||||
*/
|
||||
public class Loader implements ResourceManagerReloadListener {
|
||||
public static final Loader INSTANCE = new Loader();
|
||||
|
||||
Loader() {
|
||||
// Can be null when running datagenerators due to the unfortunate time we call this
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
if (minecraft == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (minecraft.getResourceManager() instanceof ReloadableResourceManager reloadable) {
|
||||
reloadable.registerReloadListener(this);
|
||||
}
|
||||
private Loader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(ResourceManager manager) {
|
||||
Backend.refresh();
|
||||
BackendManager.refresh();
|
||||
|
||||
var errorReporter = new ErrorReporter();
|
||||
ShaderSources sources = new ShaderSources(errorReporter, manager);
|
||||
|
@ -46,9 +39,20 @@ public class Loader implements ResourceManagerReloadListener {
|
|||
FlwCompiler.INSTANCE = new FlwCompiler(sources);
|
||||
|
||||
ClientLevel level = Minecraft.getInstance().level;
|
||||
if (Backend.canUseInstancing(level)) {
|
||||
if (BackendUtil.canUseInstancing(level)) {
|
||||
InstancedRenderDispatcher.resetInstanceLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// Can be null when running datagenerators due to the unfortunate time we call this
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
if (minecraft == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (minecraft.getResourceManager() instanceof ReloadableResourceManager reloadable) {
|
||||
reloadable.registerReloadListener(INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,13 @@ import java.util.stream.Collectors;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.gl.shader.GlShader;
|
||||
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
||||
import com.jozufozu.flywheel.gl.versioned.GlCompat;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||
import com.jozufozu.flywheel.util.StringUtil;
|
||||
|
||||
|
@ -130,7 +131,7 @@ public class Compilation {
|
|||
}
|
||||
|
||||
private static void dumpSource(String source, String fileName) {
|
||||
if (!Backend.DUMP_SHADER_SOURCE) {
|
||||
if (!BackendUtil.DUMP_SHADER_SOURCE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -140,7 +141,7 @@ public class Compilation {
|
|||
try (FileWriter writer = new FileWriter(file)) {
|
||||
writer.write(source);
|
||||
} catch (Exception e) {
|
||||
Backend.LOGGER.error("Could not dump source.", e);
|
||||
Flywheel.LOGGER.error("Could not dump source.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||
|
@ -76,7 +76,7 @@ public class CompileUtil {
|
|||
String log = glGetProgramInfoLog(handle);
|
||||
|
||||
if (!log.isEmpty()) {
|
||||
Backend.LOGGER.debug("Program link log: " + log);
|
||||
Flywheel.LOGGER.debug("Program link log: " + log);
|
||||
}
|
||||
|
||||
int result = glGetProgrami(handle, GL_LINK_STATUS);
|
||||
|
|
|
@ -4,13 +4,12 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
|
||||
public class CullingContextSet {
|
||||
static CullingContextSet create() {
|
||||
var builder = new CullingContextSet();
|
||||
for (StructType<?> structType : ComponentRegistry.structTypes) {
|
||||
for (StructType<?> structType : StructType.REGISTRY.getAll()) {
|
||||
builder.add(structType);
|
||||
}
|
||||
return builder;
|
||||
|
|
|
@ -12,22 +12,21 @@ import java.util.stream.Collectors;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.context.Context;
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
|
||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
||||
import com.jozufozu.flywheel.glsl.ShaderLoadingException;
|
||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
||||
import com.jozufozu.flywheel.lib.material.MaterialIndicies;
|
||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
||||
import com.jozufozu.flywheel.util.StringUtil;
|
||||
|
||||
|
@ -56,12 +55,12 @@ public class FlwCompiler {
|
|||
|
||||
this.sources = sources;
|
||||
this.vertexMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("vertex_material_adapter"))
|
||||
.materialSources(ComponentRegistry.materials.vertexSources())
|
||||
.materialSources(MaterialIndicies.getAllVertexShaders())
|
||||
.adapt(FnSignature.ofVoid("flw_materialVertex"))
|
||||
.switchOn(GlslExpr.variable("flw_materialVertexID"))
|
||||
.build(sources);
|
||||
this.fragmentMaterialComponent = MaterialAdapterComponent.builder(Flywheel.rl("fragment_material_adapter"))
|
||||
.materialSources(ComponentRegistry.materials.fragmentSources())
|
||||
.materialSources(MaterialIndicies.getAllFragmentShaders())
|
||||
.adapt(FnSignature.ofVoid("flw_materialFragment"))
|
||||
.adapt(FnSignature.create()
|
||||
.returnType("bool")
|
||||
|
@ -76,7 +75,7 @@ public class FlwCompiler {
|
|||
.switchOn(GlslExpr.variable("flw_materialFragmentID"))
|
||||
.build(sources);
|
||||
this.uniformComponent = UniformComponent.builder(Flywheel.rl("uniforms"))
|
||||
.sources(ComponentRegistry.getAllUniformProviders()
|
||||
.sources(ShaderUniforms.REGISTRY.getAll()
|
||||
.stream()
|
||||
.map(ShaderUniforms::uniformShader)
|
||||
.toList())
|
||||
|
@ -102,12 +101,12 @@ public class FlwCompiler {
|
|||
|
||||
private void finish() {
|
||||
long compileEnd = System.nanoTime();
|
||||
int programCount = pipelineContexts.size() + ComponentRegistry.structTypes.size();
|
||||
int programCount = pipelineContexts.size() + StructType.REGISTRY.getAll().size();
|
||||
int shaderCount = shaderCompiler.shaderCount();
|
||||
int errorCount = errors.size();
|
||||
var elapsed = StringUtil.formatTime(compileEnd - compileStart);
|
||||
|
||||
Backend.LOGGER.info("Compiled " + programCount + " programs and " + shaderCount + " shaders in " + elapsed + " with " + errorCount + " errors.");
|
||||
Flywheel.LOGGER.info("Compiled " + programCount + " programs and " + shaderCount + " shaders in " + elapsed + " with " + errorCount + " errors.");
|
||||
|
||||
if (errorCount > 0) {
|
||||
var details = errors.stream()
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.compile;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
|
||||
/**
|
||||
* A component of a ShaderCompiler, responsible for expanding root sources into the complete set of included sources.
|
||||
|
|
|
@ -11,8 +11,8 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
|
||||
|
|
|
@ -1,23 +1,31 @@
|
|||
package com.jozufozu.flywheel.backend.compile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.context.Context;
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||
|
||||
public class PipelineContextSet {
|
||||
private final List<PipelineContext> contexts = new ArrayList<>();
|
||||
private final List<PipelineContext> contextView = Collections.unmodifiableList(contexts);
|
||||
|
||||
PipelineContextSet() {
|
||||
}
|
||||
|
||||
static PipelineContextSet create() {
|
||||
var builder = new PipelineContextSet();
|
||||
for (Pipeline pipelineShader : BackendTypes.availablePipelineShaders()) {
|
||||
for (StructType<?> structType : ComponentRegistry.structTypes) {
|
||||
for (VertexType vertexType : ComponentRegistry.vertexTypes) {
|
||||
for (Pipeline pipelineShader : availablePipelineShaders()) {
|
||||
for (StructType<?> structType : StructType.REGISTRY.getAll()) {
|
||||
for (VertexType vertexType : VertexType.REGISTRY.getAll()) {
|
||||
builder.add(vertexType, structType, Contexts.WORLD, pipelineShader);
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +33,13 @@ public class PipelineContextSet {
|
|||
return builder;
|
||||
}
|
||||
|
||||
private final List<PipelineContext> contexts = new ArrayList<>();
|
||||
private final List<PipelineContext> contextView = Collections.unmodifiableList(contexts);
|
||||
|
||||
PipelineContextSet() {
|
||||
private static Collection<Pipeline> availablePipelineShaders() {
|
||||
return Backend.REGISTRY.getAll()
|
||||
.stream()
|
||||
.filter(Backend::isSupported)
|
||||
.map(Backend::pipelineShader)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<PipelineContext> all() {
|
||||
|
@ -42,7 +53,6 @@ public class PipelineContextSet {
|
|||
private void add(VertexType vertexType, StructType<?> structType, Context world, Pipeline pipelineShader) {
|
||||
var ctx = new PipelineContext(vertexType, structType, world, pipelineShader);
|
||||
|
||||
|
||||
contexts.add(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Set;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
|
||||
public class RecursiveIncluder implements Includer {
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.gl.shader.GlShader;
|
||||
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
|
||||
public class ShaderCompiler {
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.compile;
|
|||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
|
|
@ -5,8 +5,8 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public class BatchingEngine implements Engine {
|
|||
protected final BatchingDrawTracker drawTracker = new BatchingDrawTracker();
|
||||
|
||||
@Override
|
||||
public <D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model, RenderStage stage) {
|
||||
public <D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model, RenderStage stage) {
|
||||
return transformManager.getInstancer(type, model, stage);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,16 +5,16 @@ import java.util.List;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.layout.LayoutItem;
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
||||
import com.jozufozu.flywheel.lib.layout.LayoutItem;
|
||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
||||
import com.jozufozu.flywheel.backend.uniform.UniformBuffer;
|
||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
||||
|
@ -112,7 +113,7 @@ public class IndirectCullingGroup<T extends InstancedPart> {
|
|||
uploadInstanceData();
|
||||
uploadIndirectCommands();
|
||||
|
||||
compute.bind();
|
||||
UniformBuffer.syncAndBind(compute);
|
||||
buffers.bindForCompute();
|
||||
|
||||
var groupCount = (instanceCountThisFrame + 31) >> 5; // ceil(instanceCount / 32)
|
||||
|
@ -125,7 +126,7 @@ public class IndirectCullingGroup<T extends InstancedPart> {
|
|||
return;
|
||||
}
|
||||
|
||||
draw.bind();
|
||||
UniformBuffer.syncAndBind(draw);
|
||||
glBindVertexArray(vertexArray);
|
||||
buffers.bindForDraw();
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ package com.jozufozu.flywheel.backend.engine.indirect;
|
|||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.lib.material.MaterialIndicies;
|
||||
|
||||
public final class IndirectDraw<T extends InstancedPart> {
|
||||
private final IndirectInstancer<T> instancer;
|
||||
|
@ -25,8 +25,8 @@ public final class IndirectDraw<T extends InstancedPart> {
|
|||
this.stage = stage;
|
||||
this.mesh = mesh;
|
||||
|
||||
this.vertexMaterialID = ComponentRegistry.materials.getVertexID(material);
|
||||
this.fragmentMaterialID = ComponentRegistry.materials.getFragmentID(material);
|
||||
this.vertexMaterialID = MaterialIndicies.getVertexShaderIndex(material.vertexShader());
|
||||
this.fragmentMaterialID = MaterialIndicies.getFragmentShaderIndex(material.fragmentShader());
|
||||
}
|
||||
|
||||
public void prepare(int baseInstance) {
|
||||
|
|
|
@ -10,10 +10,10 @@ import java.util.EnumMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.lib.material.MaterialIndicies;
|
||||
import com.jozufozu.flywheel.util.Textures;
|
||||
|
||||
public class IndirectDrawSet<T extends InstancedPart> {
|
||||
|
@ -50,7 +50,7 @@ public class IndirectDrawSet<T extends InstancedPart> {
|
|||
multiDraws.clear();
|
||||
// sort by stage, then material
|
||||
indirectDraws.sort(Comparator.comparing(IndirectDraw<T>::stage)
|
||||
.thenComparing(draw -> ComponentRegistry.materials.getMaterialID(draw.material())));
|
||||
.thenComparing(draw -> MaterialIndicies.getMaterialIndex(draw.material())));
|
||||
|
||||
for (int start = 0, i = 0; i < indirectDraws.size(); i++) {
|
||||
var draw = indirectDraws.get(i);
|
||||
|
|
|
@ -48,7 +48,7 @@ public class IndirectEngine implements Engine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model, RenderStage stage) {
|
||||
public <D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model, RenderStage stage) {
|
||||
return drawManager.getInstancer(type, model, stage);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.layout.LayoutItem;
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
|
||||
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
||||
import com.jozufozu.flywheel.lib.layout.LayoutItem;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.jozufozu.flywheel.api.model.Mesh;
|
|||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.gl.GlPrimitive;
|
||||
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||
import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
||||
|
@ -234,9 +235,9 @@ public class InstancedMeshPool {
|
|||
|
||||
private void draw(int instanceCount) {
|
||||
if (instanceCount > 1) {
|
||||
GL32.glDrawElementsInstanced(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0, instanceCount);
|
||||
GL32.glDrawElementsInstanced(GlPrimitive.TRIANGLES.glEnum, ebo.getElementCount(), ebo.getEboIndexType().asGLType, 0, instanceCount);
|
||||
} else {
|
||||
GL32.glDrawElements(GlPrimitive.TRIANGLES.glEnum, ebo.elementCount, ebo.eboIndexType.asGLType, 0);
|
||||
GL32.glDrawElements(GlPrimitive.TRIANGLES.glEnum, ebo.getElementCount(), ebo.getEboIndexType().asGLType, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Set;
|
|||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.Engine;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.context.Context;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
|
@ -18,8 +17,10 @@ import com.jozufozu.flywheel.api.struct.StructType;
|
|||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.uniform.UniformBuffer;
|
||||
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
||||
import com.jozufozu.flywheel.lib.material.MaterialIndicies;
|
||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
@ -51,7 +52,7 @@ public class InstancingEngine implements Engine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model, RenderStage stage) {
|
||||
public <D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model, RenderStage stage) {
|
||||
return drawManager.getInstancer(type, model, stage);
|
||||
}
|
||||
|
||||
|
@ -117,11 +118,11 @@ public class InstancingEngine implements Engine {
|
|||
var material = desc.material();
|
||||
|
||||
var program = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, structType, context, Pipelines.INSTANCED_ARRAYS);
|
||||
program.bind();
|
||||
UniformBuffer.syncAndBind(program);
|
||||
|
||||
var uniformLocation = program.getUniformLocation("_flw_materialID_instancing");
|
||||
var vertexID = ComponentRegistry.materials.getVertexID(material);
|
||||
var fragmentID = ComponentRegistry.materials.getFragmentID(material);
|
||||
var vertexID = MaterialIndicies.getVertexShaderIndex(material.vertexShader());
|
||||
var fragmentID = MaterialIndicies.getFragmentShaderIndex(material.fragmentShader());
|
||||
GL32.glUniform2ui(uniformLocation, vertexID, fragmentID);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
|||
import com.jozufozu.flywheel.api.instance.Instance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.api.instancer.FlatLit;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||
import com.jozufozu.flywheel.lib.light.LightListener;
|
||||
|
||||
|
@ -22,11 +22,11 @@ import net.minecraft.world.level.LightLayer;
|
|||
*/
|
||||
public abstract class AbstractInstance implements Instance, LightListener {
|
||||
|
||||
protected final InstancerManager instancerManager;
|
||||
protected final InstancerProvider instancerManager;
|
||||
public final Level level;
|
||||
protected boolean removed = false;
|
||||
|
||||
public AbstractInstance(InstancerManager instancerManager, Level level) {
|
||||
public AbstractInstance(InstancerProvider instancerManager, Level level) {
|
||||
this.instancerManager = instancerManager;
|
||||
this.level = level;
|
||||
}
|
||||
|
|
|
@ -9,11 +9,11 @@ import java.util.function.Consumer;
|
|||
|
||||
import org.joml.FrustumIntersection;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.ratelimit.BandedPrimeLimiter;
|
||||
import com.jozufozu.flywheel.backend.instancing.ratelimit.DistanceUpdateLimiter;
|
||||
import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter;
|
||||
|
@ -164,7 +164,7 @@ public abstract class InstanceManager<T> {
|
|||
}
|
||||
|
||||
public void add(T obj) {
|
||||
if (!Backend.isOn()) return;
|
||||
if (!BackendManager.isOn()) return;
|
||||
|
||||
if (canCreateInstance(obj)) {
|
||||
getStorage().add(obj);
|
||||
|
@ -172,7 +172,7 @@ public abstract class InstanceManager<T> {
|
|||
}
|
||||
|
||||
public void queueAdd(T obj) {
|
||||
if (!Backend.isOn()) {
|
||||
if (!BackendManager.isOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ public abstract class InstanceManager<T> {
|
|||
}
|
||||
|
||||
public void queueUpdate(T obj) {
|
||||
if (!Backend.isOn()) return;
|
||||
if (!BackendManager.isOn()) return;
|
||||
|
||||
if (!canCreateInstance(obj)) {
|
||||
return;
|
||||
|
@ -209,7 +209,7 @@ public abstract class InstanceManager<T> {
|
|||
* @param obj the object to update.
|
||||
*/
|
||||
public void update(T obj) {
|
||||
if (!Backend.isOn()) return;
|
||||
if (!BackendManager.isOn()) return;
|
||||
|
||||
if (canCreateInstance(obj)) {
|
||||
getStorage().update(obj);
|
||||
|
@ -217,7 +217,7 @@ public abstract class InstanceManager<T> {
|
|||
}
|
||||
|
||||
public void remove(T obj) {
|
||||
if (!Backend.isOn()) return;
|
||||
if (!BackendManager.isOn()) return;
|
||||
|
||||
getStorage().remove(obj);
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ public abstract class InstanceManager<T> {
|
|||
}
|
||||
|
||||
public void queueAddAll(Collection<? extends T> objects) {
|
||||
if (!Backend.isOn() || objects.isEmpty()) {
|
||||
if (!BackendManager.isOn() || objects.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package com.jozufozu.flywheel.backend.instancing;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.api.backend.Engine;
|
||||
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.effect.Effect;
|
||||
import com.jozufozu.flywheel.backend.instancing.effect.EffectInstanceManager;
|
||||
|
@ -35,7 +36,7 @@ public class InstanceWorld implements AutoCloseable {
|
|||
private final InstanceManager<Effect> effects;
|
||||
|
||||
public static InstanceWorld create(LevelAccessor level) {
|
||||
var engine = Backend.getBackendType()
|
||||
var engine = BackendManager.getBackend()
|
||||
.createEngine();
|
||||
|
||||
var entities = new EntityInstanceManager(engine);
|
||||
|
@ -53,7 +54,7 @@ public class InstanceWorld implements AutoCloseable {
|
|||
this.entities = entities;
|
||||
this.blockEntities = blockEntities;
|
||||
this.effects = effects;
|
||||
this.taskExecutor = Backend.getTaskExecutor();
|
||||
this.taskExecutor = BackendUtil.getTaskExecutor();
|
||||
}
|
||||
|
||||
public InstanceManager<Entity> getEntities() {
|
||||
|
|
|
@ -2,10 +2,11 @@ package com.jozufozu.flywheel.backend.instancing;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.backend.instancing.effect.Effect;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
|
@ -29,7 +30,7 @@ public class InstancedRenderDispatcher {
|
|||
* @param blockEntity The block entity whose instance you want to update.
|
||||
*/
|
||||
public static void enqueueUpdate(BlockEntity blockEntity) {
|
||||
if (Backend.isOn() && blockEntity.hasLevel() && blockEntity.getLevel() instanceof ClientLevel) {
|
||||
if (BackendManager.isOn() && blockEntity.hasLevel() && blockEntity.getLevel() instanceof ClientLevel) {
|
||||
instanceWorlds.get(blockEntity.getLevel())
|
||||
.getBlockEntities()
|
||||
.queueUpdate(blockEntity);
|
||||
|
@ -41,7 +42,7 @@ public class InstancedRenderDispatcher {
|
|||
* @param entity The entity whose instance you want to update.
|
||||
*/
|
||||
public static void enqueueUpdate(Entity entity) {
|
||||
if (Backend.isOn()) {
|
||||
if (BackendManager.isOn()) {
|
||||
instanceWorlds.get(entity.level)
|
||||
.getEntities()
|
||||
.queueUpdate(entity);
|
||||
|
@ -65,7 +66,7 @@ public class InstancedRenderDispatcher {
|
|||
* @throws NullPointerException if the backend is off
|
||||
*/
|
||||
public static InstanceWorld getInstanceWorld(LevelAccessor world) {
|
||||
if (Backend.isOn()) {
|
||||
if (BackendManager.isOn()) {
|
||||
return instanceWorlds.get(world);
|
||||
} else {
|
||||
throw new NullPointerException("Backend is off, cannot retrieve instance world.");
|
||||
|
@ -73,21 +74,21 @@ public class InstancedRenderDispatcher {
|
|||
}
|
||||
|
||||
public static void tick(TickEvent.ClientTickEvent event) {
|
||||
if (!Backend.isGameActive() || event.phase == TickEvent.Phase.START) {
|
||||
if (!BackendUtil.isGameActive() || event.phase == TickEvent.Phase.START) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ClientLevel level = mc.level;
|
||||
AnimationTickHolder.tick();
|
||||
|
||||
if (Backend.isOn()) {
|
||||
if (BackendManager.isOn()) {
|
||||
instanceWorlds.get(level)
|
||||
.tick();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onBeginFrame(BeginFrameEvent event) {
|
||||
if (Backend.isGameActive() && Backend.isOn()) {
|
||||
if (BackendUtil.isGameActive() && BackendManager.isOn()) {
|
||||
instanceWorlds.get(event.getContext().level())
|
||||
.beginFrame(event);
|
||||
}
|
||||
|
@ -95,14 +96,14 @@ public class InstancedRenderDispatcher {
|
|||
|
||||
public static void onRenderStage(RenderStageEvent event) {
|
||||
ClientLevel level = event.getContext().level();
|
||||
if (!Backend.canUseInstancing(level)) return;
|
||||
if (!BackendUtil.canUseInstancing(level)) return;
|
||||
|
||||
instanceWorlds.get(level).renderStage(event.getContext(), event.getStage());
|
||||
}
|
||||
|
||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
ClientLevel level = event.getLevel();
|
||||
if (Backend.isOn() && level != null) {
|
||||
if (BackendManager.isOn() && level != null) {
|
||||
resetInstanceLevel(level);
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +114,7 @@ public class InstancedRenderDispatcher {
|
|||
}
|
||||
|
||||
public static void getDebugString(List<String> debug) {
|
||||
if (Backend.isOn()) {
|
||||
if (BackendManager.isOn()) {
|
||||
InstanceWorld instanceWorld = instanceWorlds.get(Minecraft.getInstance().level);
|
||||
|
||||
debug.add("Update limiting: " + FlwCommands.boolToText(FlwConfig.get().limitUpdates()).getString());
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.joml.FrustumIntersection;
|
|||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||
|
@ -41,7 +41,7 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
|||
protected final BlockPos instancePos;
|
||||
protected final BlockState blockState;
|
||||
|
||||
public BlockEntityInstance(InstancerManager instancerManager, T blockEntity) {
|
||||
public BlockEntityInstance(InstancerProvider instancerManager, T blockEntity) {
|
||||
super(instancerManager, blockEntity.getLevel());
|
||||
this.blockEntity = blockEntity;
|
||||
this.pos = blockEntity.getBlockPos();
|
||||
|
|
|
@ -2,11 +2,11 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage;
|
||||
import com.jozufozu.flywheel.backend.instancing.storage.Storage;
|
||||
|
||||
|
@ -21,7 +21,7 @@ public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
|||
|
||||
private final BlockEntityStorage storage;
|
||||
|
||||
public BlockEntityInstanceManager(InstancerManager instancerManager) {
|
||||
public BlockEntityInstanceManager(InstancerProvider instancerManager) {
|
||||
storage = new BlockEntityStorage(instancerManager);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Backend.isFlywheelLevel(level)) {
|
||||
if (BackendUtil.isFlywheelLevel(level)) {
|
||||
BlockPos pos = blockEntity.getBlockPos();
|
||||
|
||||
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
|
||||
|
@ -73,7 +73,7 @@ public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
|||
final Long2ObjectMap<BlockEntityInstance<?>> posLookup = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
|
||||
public BlockEntityStorage(InstancerManager manager) {
|
||||
public BlockEntityStorage(InstancerProvider manager) {
|
||||
super(manager);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public class SimpleBlockEntityInstancingController<T extends BlockEntity> implements BlockEntityInstancingController<T> {
|
||||
protected BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public SimpleBlockEntityInstancingController(BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
this.skipRender = skipRender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity) {
|
||||
return instanceFactory.apply(instancerManager, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipRender(T blockEntity) {
|
||||
return skipRender.test(blockEntity);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,10 @@ package com.jozufozu.flywheel.backend.instancing.effect;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
|
||||
public interface Effect {
|
||||
|
||||
Collection<AbstractInstance> createInstances(InstancerManager instancerManager);
|
||||
Collection<AbstractInstance> createInstances(InstancerProvider instancerManager);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.ArrayList;
|
|||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.storage.AbstractStorage;
|
||||
|
@ -15,7 +15,7 @@ public class EffectInstanceManager extends InstanceManager<Effect> {
|
|||
|
||||
private final EffectStorage<Effect> storage;
|
||||
|
||||
public EffectInstanceManager(InstancerManager instancerManager) {
|
||||
public EffectInstanceManager(InstancerProvider instancerManager) {
|
||||
storage = new EffectStorage<>(instancerManager);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class EffectInstanceManager extends InstanceManager<Effect> {
|
|||
|
||||
private final Multimap<T, AbstractInstance> instances;
|
||||
|
||||
public EffectStorage(InstancerManager manager) {
|
||||
public EffectStorage(InstancerProvider manager) {
|
||||
super(manager);
|
||||
this.instances = HashMultimap.create();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.joml.FrustumIntersection;
|
|||
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||
|
@ -40,7 +40,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
|||
protected final E entity;
|
||||
protected final MutableBox bounds;
|
||||
|
||||
public EntityInstance(InstancerManager instancerManager, E entity) {
|
||||
public EntityInstance(InstancerProvider instancerManager, E entity) {
|
||||
super(instancerManager, entity.level);
|
||||
this.entity = entity;
|
||||
bounds = MutableBox.from(entity.getBoundingBox());
|
||||
|
|
|
@ -2,11 +2,11 @@ package com.jozufozu.flywheel.backend.instancing.entity;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
@ -16,7 +16,7 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
|||
|
||||
private final One2OneStorage<Entity> storage;
|
||||
|
||||
public EntityInstanceManager(InstancerManager instancerManager) {
|
||||
public EntityInstanceManager(InstancerProvider instancerManager) {
|
||||
storage = new One2OneStorage<>(instancerManager) {
|
||||
@Override
|
||||
protected @Nullable AbstractInstance createRaw(Entity obj) {
|
||||
|
@ -42,6 +42,6 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
|||
|
||||
Level level = entity.level;
|
||||
|
||||
return Backend.isFlywheelLevel(level);
|
||||
return BackendUtil.isFlywheelLevel(level);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public class SimpleEntityInstancingController<T extends Entity> implements EntityInstancingController<T> {
|
||||
protected BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public SimpleEntityInstancingController(BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
this.skipRender = skipRender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity) {
|
||||
return instanceFactory.apply(instancerManager, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipRender(T entity) {
|
||||
return skipRender.test(entity);
|
||||
}
|
||||
}
|
|
@ -5,16 +5,16 @@ import java.util.List;
|
|||
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||
|
||||
public abstract class AbstractStorage<T> implements Storage<T> {
|
||||
protected final List<TickableInstance> tickableInstances;
|
||||
protected final List<DynamicInstance> dynamicInstances;
|
||||
protected final InstancerManager instancerManager;
|
||||
protected final InstancerProvider instancerManager;
|
||||
|
||||
protected AbstractStorage(InstancerManager instancerManager) {
|
||||
protected AbstractStorage(InstancerProvider instancerManager) {
|
||||
this.instancerManager = instancerManager;
|
||||
|
||||
this.dynamicInstances = new ArrayList<>();
|
||||
|
|
|
@ -5,14 +5,14 @@ import java.util.Map;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||
|
||||
public abstract class One2OneStorage<T> extends AbstractStorage<T> {
|
||||
private final Map<T, AbstractInstance> instances;
|
||||
|
||||
public One2OneStorage(InstancerManager instancerManager) {
|
||||
public One2OneStorage(InstancerProvider instancerManager) {
|
||||
super(instancerManager);
|
||||
this.instances = new HashMap<>();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package com.jozufozu.flywheel.backend.uniform;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.jozufozu.flywheel.util.RenderMath;
|
||||
|
@ -35,7 +35,12 @@ public class UniformBuffer {
|
|||
|
||||
private UniformBuffer() {
|
||||
buffer = new GlBuffer(GlBufferType.UNIFORM_BUFFER);
|
||||
providerSet = new ProviderSet(ComponentRegistry.getAllUniformProviders());
|
||||
providerSet = new ProviderSet(ShaderUniforms.REGISTRY.getAll());
|
||||
}
|
||||
|
||||
public static void syncAndBind(GlProgram program) {
|
||||
getInstance().sync();
|
||||
program.bind();
|
||||
}
|
||||
|
||||
public void sync() {
|
||||
|
@ -84,7 +89,7 @@ public class UniformBuffer {
|
|||
|
||||
private final MemoryBlock data;
|
||||
|
||||
private ProviderSet(final Collection<ShaderUniforms> providers) {
|
||||
private ProviderSet(final Set<ShaderUniforms> providers) {
|
||||
var builder = ImmutableList.<LiveProvider>builder();
|
||||
int totalBytes = 0;
|
||||
for (ShaderUniforms provider : providers) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendType;
|
||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
|
@ -15,38 +15,41 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
|||
|
||||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public enum BackendTypeArgument implements ArgumentType<BackendType> {
|
||||
public enum BackendArgument implements ArgumentType<Backend> {
|
||||
INSTANCE;
|
||||
|
||||
private static final List<String> STRING_IDS = Backend.REGISTRY.getAllIds().stream().map(ResourceLocation::toString).toList();
|
||||
|
||||
private static final Dynamic2CommandExceptionType INVALID = new Dynamic2CommandExceptionType((found, constants) -> {
|
||||
// TODO: don't steal lang
|
||||
return new TranslatableComponent("commands.forge.arguments.enum.invalid", constants, found);
|
||||
});
|
||||
|
||||
@Override
|
||||
public BackendType parse(StringReader reader) throws CommandSyntaxException {
|
||||
String string = reader.readUnquotedString();
|
||||
|
||||
BackendType engine = BackendTypes.getBackendType(string);
|
||||
|
||||
if (engine == null) {
|
||||
throw INVALID.createWithContext(reader, string, BackendTypes.validNames());
|
||||
}
|
||||
|
||||
return engine;
|
||||
public static BackendArgument getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Backend parse(StringReader reader) throws CommandSyntaxException {
|
||||
ResourceLocation id = ResourceLocation.read(reader);
|
||||
Backend backend = Backend.REGISTRY.get(id);
|
||||
|
||||
if (backend == null) {
|
||||
throw INVALID.createWithContext(reader, id.toString(), STRING_IDS);
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
|
||||
return SharedSuggestionProvider.suggest(BackendTypes.validNames(), builder);
|
||||
return SharedSuggestionProvider.suggest(STRING_IDS, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExamples() {
|
||||
return BackendTypes.validNames();
|
||||
}
|
||||
|
||||
public static BackendTypeArgument getInstance() {
|
||||
return INSTANCE;
|
||||
return STRING_IDS;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,8 @@ package com.jozufozu.flywheel.config;
|
|||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendType;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||
import com.jozufozu.flywheel.lib.backend.SimpleBackendType;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.lib.uniform.FlwShaderUniforms;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
@ -15,6 +11,7 @@ import com.mojang.brigadier.arguments.IntegerArgumentType;
|
|||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
@ -24,6 +21,7 @@ import net.minecraft.core.BlockPos;
|
|||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraftforge.client.event.RegisterClientCommandsEvent;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
|
@ -39,22 +37,38 @@ public class FlwCommands {
|
|||
.executes(context -> {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player != null) {
|
||||
player.displayClientMessage(BackendTypes.getBackendType(value.get())
|
||||
.getEngineMessage(), false);
|
||||
String backendIdStr = value.get();
|
||||
|
||||
ResourceLocation backendId;
|
||||
try {
|
||||
backendId = new ResourceLocation(backendIdStr);
|
||||
} catch (ResourceLocationException e) {
|
||||
player.displayClientMessage(new TextComponent("Config contains invalid backend ID '" + backendIdStr + "'!"), false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend backend = Backend.REGISTRY.get(backendId);
|
||||
if (backend == null) {
|
||||
player.displayClientMessage(new TextComponent("Config contains non-existent backend with ID '" + backendId + "'!"), false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Component message = backend.getEngineMessage();
|
||||
player.displayClientMessage(message, false);
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(Commands.argument("type", BackendTypeArgument.INSTANCE)
|
||||
.then(Commands.argument("id", BackendArgument.INSTANCE)
|
||||
.executes(context -> {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player != null) {
|
||||
BackendType type = context.getArgument("type", SimpleBackendType.class);
|
||||
value.set(type.getShortName());
|
||||
Backend backend = context.getArgument("id", Backend.class);
|
||||
value.set(Backend.REGISTRY.getId(backend).toString());
|
||||
|
||||
Component message = getEngineMessage(type);
|
||||
Component message = backend.getEngineMessage();
|
||||
player.displayClientMessage(message, false);
|
||||
|
||||
Backend.reloadWorldRenderers();
|
||||
BackendUtil.reloadWorldRenderers();
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
@ -74,7 +88,7 @@ public class FlwCommands {
|
|||
Component text = boolToText(bool).append(new TextComponent(" update limiting.").withStyle(ChatFormatting.WHITE));
|
||||
player.displayClientMessage(text, false);
|
||||
|
||||
Backend.reloadWorldRenderers();
|
||||
BackendUtil.reloadWorldRenderers();
|
||||
}
|
||||
));
|
||||
|
||||
|
@ -152,10 +166,6 @@ public class FlwCommands {
|
|||
return b ? new TextComponent("enabled").withStyle(ChatFormatting.DARK_GREEN) : new TextComponent("disabled").withStyle(ChatFormatting.RED);
|
||||
}
|
||||
|
||||
public static Component getEngineMessage(@NotNull BackendType type) {
|
||||
return type.getEngineMessage();
|
||||
}
|
||||
|
||||
public static class ConfigCommandBuilder {
|
||||
protected LiteralArgumentBuilder<CommandSourceStack> command;
|
||||
|
||||
|
|
|
@ -2,54 +2,82 @@ package com.jozufozu.flywheel.config;
|
|||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendType;
|
||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
public class FlwConfig {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final FlwConfig INSTANCE = new FlwConfig();
|
||||
|
||||
public final ClientConfig client;
|
||||
private final ForgeConfigSpec clientSpec;
|
||||
|
||||
public FlwConfig() {
|
||||
Pair<ClientConfig, ForgeConfigSpec> client = new ForgeConfigSpec.Builder().configure(ClientConfig::new);
|
||||
|
||||
this.client = client.getLeft();
|
||||
|
||||
ModLoadingContext.get()
|
||||
.registerConfig(ModConfig.Type.CLIENT, client.getRight());
|
||||
clientSpec = client.getRight();
|
||||
}
|
||||
|
||||
public static FlwConfig get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public Backend getBackend() {
|
||||
Backend backend = parseBackend(client.backend.get());
|
||||
if (backend == null) {
|
||||
backend = BackendManager.getDefaultBackend();
|
||||
client.backend.set(Backend.REGISTRY.getId(backend).toString());
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BackendType getBackendType() {
|
||||
return BackendTypes.getBackendType(client.backend.get());
|
||||
private static Backend parseBackend(String idStr) {
|
||||
ResourceLocation backendId;
|
||||
try {
|
||||
backendId = new ResourceLocation(idStr);
|
||||
} catch (ResourceLocationException e) {
|
||||
LOGGER.warn("Config contains invalid backend ID '" + idStr + "'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
Backend backend = Backend.REGISTRY.get(backendId);
|
||||
if (backend == null) {
|
||||
LOGGER.warn("Config contains non-existent backend with ID '" + backendId + "'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
public boolean limitUpdates() {
|
||||
return client.limitUpdates.get();
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
public void registerSpecs(ModLoadingContext context) {
|
||||
context.registerConfig(ModConfig.Type.CLIENT, clientSpec);
|
||||
}
|
||||
|
||||
public static class ClientConfig {
|
||||
public final ForgeConfigSpec.ConfigValue<String> backend;
|
||||
public final ConfigValue<String> backend;
|
||||
public final BooleanValue limitUpdates;
|
||||
|
||||
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
backend = builder.comment("Select the backend to use.")
|
||||
.define("backend", BackendTypes.defaultForCurrentPC()
|
||||
.getShortName());
|
||||
.define("backend", Backend.REGISTRY.getId(BackendManager.getDefaultBackend()).toString());
|
||||
|
||||
limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
|
||||
.define("limitUpdates", true);
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.extension;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.extension;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.backend.engine.instancing;
|
||||
package com.jozufozu.flywheel.gl.buffer;
|
||||
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
public class ElementBuffer {
|
|
@ -4,21 +4,20 @@ import static org.lwjgl.opengl.GL20.glDeleteProgram;
|
|||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.uniform.UniformBuffer;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.gl.GlObject;
|
||||
import com.mojang.blaze3d.shaders.ProgramManager;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
public class GlProgram extends GlObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public GlProgram(int handle) {
|
||||
setHandle(handle);
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
// TODO: bind textures?
|
||||
UniformBuffer.getInstance()
|
||||
.sync();
|
||||
ProgramManager.glUseProgram(handle());
|
||||
}
|
||||
|
||||
|
@ -36,7 +35,7 @@ public class GlProgram extends GlObject {
|
|||
int index = glGetUniformLocation(this.handle(), uniform);
|
||||
|
||||
if (index < 0) {
|
||||
Backend.LOGGER.debug("No active uniform '{}' exists. Could be unused.", uniform);
|
||||
LOGGER.debug("No active uniform '{}' exists. Could be unused.", uniform);
|
||||
}
|
||||
|
||||
return index;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.api.pipeline;
|
||||
package com.jozufozu.flywheel.glsl;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
@ -9,7 +9,6 @@ import java.util.regex.Matcher;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.glsl.parse.Import;
|
||||
import com.jozufozu.flywheel.glsl.parse.ShaderField;
|
||||
import com.jozufozu.flywheel.glsl.parse.ShaderFunction;
|
||||
|
|
|
@ -4,14 +4,17 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.glsl.ShaderLoadingException;
|
||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||
import com.jozufozu.flywheel.glsl.span.Span;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.jozufozu.flywheel.util.StringUtil;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
public class ErrorReporter {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final List<ErrorBuilder> reportedErrors = new ArrayList<>();
|
||||
|
||||
|
@ -107,7 +110,7 @@ public class ErrorReporter {
|
|||
.append('\n');
|
||||
}
|
||||
|
||||
Flywheel.LOGGER.error(builder.toString());
|
||||
LOGGER.error(builder.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.glsl.error;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
@ -1,20 +1,19 @@
|
|||
package com.jozufozu.flywheel.handler;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.event.entity.EntityLeaveWorldEvent;
|
||||
|
||||
public class EntityWorldHandler {
|
||||
|
||||
public static void onEntityJoinWorld(EntityJoinWorldEvent event) {
|
||||
if (event.getWorld().isClientSide && Backend.isOn()) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
if (event.getWorld().isClientSide && BackendManager.isOn()) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
.queueAdd(event.getEntity());
|
||||
}
|
||||
|
||||
public static void onEntityLeaveWorld(EntityLeaveWorldEvent event) {
|
||||
if (event.getWorld().isClientSide && Backend.isOn()) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
if (event.getWorld().isClientSide && BackendManager.isOn()) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
.remove(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.handler;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
||||
|
@ -34,7 +34,7 @@ public class ForgeEvents {
|
|||
}
|
||||
|
||||
public static void tickLight(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.END && Backend.isGameActive()) {
|
||||
if (event.phase == TickEvent.Phase.END && BackendUtil.isGameActive()) {
|
||||
LightUpdater.get(Minecraft.getInstance().level)
|
||||
.tick();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package com.jozufozu.flywheel.impl;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.lib.backend.Backends;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
public final class BackendManagerImpl {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Backend DEFAULT_BACKEND = findDefaultBackend();
|
||||
private static Backend backend;
|
||||
|
||||
@Nullable
|
||||
public static Backend getBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
public static String getBackendDescriptor() {
|
||||
return backend == null ? "Uninitialized" : backend.getProperName();
|
||||
}
|
||||
|
||||
public static boolean isOn() {
|
||||
return backend != null && backend != Backends.OFF;
|
||||
}
|
||||
|
||||
public static void refresh() {
|
||||
backend = chooseBackend();
|
||||
}
|
||||
|
||||
public static Backend getDefaultBackend() {
|
||||
return DEFAULT_BACKEND;
|
||||
}
|
||||
|
||||
private static Backend chooseBackend() {
|
||||
var preferred = FlwConfig.get().getBackend();
|
||||
var actual = preferred.findFallback();
|
||||
|
||||
if (preferred != actual) {
|
||||
LOGGER.warn("Flywheel backend fell back from '{}' to '{}'", Backend.REGISTRY.getId(preferred), Backend.REGISTRY.getId(actual));
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
private static Backend findDefaultBackend() {
|
||||
// TODO: Automatically select the best default config based on the user's driver
|
||||
// TODO: Figure out how this will work if custom backends are registered
|
||||
return Backends.INDIRECT;
|
||||
}
|
||||
|
||||
private BackendManagerImpl() {
|
||||
}
|
||||
}
|
117
src/main/java/com/jozufozu/flywheel/impl/IdRegistryImpl.java
Normal file
117
src/main/java/com/jozufozu/flywheel/impl/IdRegistryImpl.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
package com.jozufozu.flywheel.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import com.jozufozu.flywheel.api.registry.IdRegistry;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSets;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceCollection;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceCollections;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class IdRegistryImpl<T> implements IdRegistry<T> {
|
||||
private static final ObjectList<IdRegistryImpl<?>> ALL = new ObjectArrayList<>();
|
||||
|
||||
private final Object2ReferenceMap<ResourceLocation, T> map = new Object2ReferenceOpenHashMap<>();
|
||||
private final Reference2ObjectMap<T, ResourceLocation> reverseMap = new Reference2ObjectOpenHashMap<>();
|
||||
private final ObjectSet<ResourceLocation> keysView = ObjectSets.unmodifiable(map.keySet());
|
||||
private final ReferenceCollection<T> valuesView = ReferenceCollections.unmodifiable(map.values());
|
||||
private final ObjectList<Runnable> freezeCallbacks = new ObjectArrayList<>();
|
||||
private boolean frozen;
|
||||
|
||||
private IdRegistryImpl() {
|
||||
ALL.add(this);
|
||||
}
|
||||
|
||||
public static <T> IdRegistry<T> create() {
|
||||
return new IdRegistryImpl<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(ResourceLocation id, T object) {
|
||||
if (frozen) {
|
||||
throw new IllegalStateException("Cannot register to frozen registry!");
|
||||
}
|
||||
T oldValue = map.put(id, object);
|
||||
if (oldValue != null) {
|
||||
throw new IllegalArgumentException("Cannot override registration for ID '" + id + "'!");
|
||||
}
|
||||
ResourceLocation oldId = reverseMap.put(object, id);
|
||||
if (oldId != null) {
|
||||
throw new IllegalArgumentException("Cannot override ID '" + id + "' with registration for ID '" + oldId + "'!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends T> S registerAndGet(ResourceLocation id, S object) {
|
||||
register(id, object);
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T get(ResourceLocation id) {
|
||||
return map.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getId(T object) {
|
||||
return reverseMap.get(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unmodifiable
|
||||
public Set<ResourceLocation> getAllIds() {
|
||||
return keysView;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unmodifiable
|
||||
public Collection<T> getAll() {
|
||||
return valuesView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFreezeCallback(Runnable callback) {
|
||||
if (frozen) {
|
||||
throw new IllegalStateException("Cannot add freeze callback to frozen registry!");
|
||||
}
|
||||
freezeCallbacks.add(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFrozen() {
|
||||
return frozen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return getAll().iterator();
|
||||
}
|
||||
|
||||
public void freeze() {
|
||||
frozen = true;
|
||||
for (Runnable runnable : freezeCallbacks) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static void freezeAll() {
|
||||
for (IdRegistryImpl<?> registry : ALL) {
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
}
|
101
src/main/java/com/jozufozu/flywheel/impl/RegistryImpl.java
Normal file
101
src/main/java/com/jozufozu/flywheel/impl/RegistryImpl.java
Normal file
|
@ -0,0 +1,101 @@
|
|||
package com.jozufozu.flywheel.impl;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import com.jozufozu.flywheel.api.registry.Registry;
|
||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||
|
||||
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;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class RegistryImpl<T> implements Registry<T> {
|
||||
private static final ObjectList<RegistryImpl<?>> ALL = new ObjectArrayList<>();
|
||||
|
||||
private final ObjectSet<T> set = new ObjectOpenHashSet<>();
|
||||
private final ObjectSet<T> setView = ObjectSets.unmodifiable(set);
|
||||
private final ObjectList<Runnable> freezeCallbacks = new ObjectArrayList<>();
|
||||
private boolean frozen;
|
||||
|
||||
private RegistryImpl() {
|
||||
ALL.add(this);
|
||||
}
|
||||
|
||||
public static <T> Registry<T> create() {
|
||||
return new RegistryImpl<>();
|
||||
}
|
||||
|
||||
public static <T extends ShaderUniforms> Registry<T> createForShaderUniforms() {
|
||||
return new RegistryImpl<>() {
|
||||
private final ObjectSet<ResourceLocation> files = new ObjectOpenHashSet<>();
|
||||
|
||||
@Override
|
||||
public void register(T object) {
|
||||
if (!files.add(object.uniformShader())) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
super.register(object);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@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
|
||||
@Unmodifiable
|
||||
public Set<T> getAll() {
|
||||
return setView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFreezeCallback(Runnable callback) {
|
||||
if (frozen) {
|
||||
throw new IllegalStateException("Cannot add freeze callback to frozen registry!");
|
||||
}
|
||||
freezeCallbacks.add(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFrozen() {
|
||||
return frozen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return getAll().iterator();
|
||||
}
|
||||
|
||||
public void freeze() {
|
||||
frozen = true;
|
||||
for (Runnable runnable : freezeCallbacks) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static void freezeAll() {
|
||||
for (RegistryImpl<?> registry : ALL) {
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.vertex;
|
||||
package com.jozufozu.flywheel.impl.vertex;
|
||||
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.vertex;
|
||||
package com.jozufozu.flywheel.impl.vertex;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.vertex;
|
||||
package com.jozufozu.flywheel.impl.vertex;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
|
@ -1,16 +1,7 @@
|
|||
package com.jozufozu.flywheel.lib.backend;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendType;
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.engine.batching.BatchingEngine;
|
||||
import com.jozufozu.flywheel.backend.engine.indirect.IndirectEngine;
|
||||
import com.jozufozu.flywheel.backend.engine.instancing.InstancingEngine;
|
||||
|
@ -22,90 +13,54 @@ import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
|||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
|
||||
public class BackendTypes {
|
||||
public static final Map<String, BackendType> BACKEND_TYPES = new HashMap<>();
|
||||
|
||||
public static final BackendType OFF = SimpleBackendType.builder()
|
||||
public class Backends {
|
||||
public static final Backend OFF = SimpleBackend.builder()
|
||||
.properName("Off")
|
||||
.shortName("off")
|
||||
.engineMessage(new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED))
|
||||
.engineSupplier(() -> {
|
||||
throw new IllegalStateException("Cannot create engine when backend is off.");
|
||||
})
|
||||
.fallback(() -> BackendTypes.OFF)
|
||||
.fallback(() -> Backends.OFF)
|
||||
.supported(() -> true)
|
||||
.register();
|
||||
.register(Flywheel.rl("off"));
|
||||
|
||||
/**
|
||||
* Use a thread pool to buffer instances in parallel on the CPU.
|
||||
*/
|
||||
public static final BackendType BATCHING = SimpleBackendType.builder()
|
||||
public static final Backend BATCHING = SimpleBackend.builder()
|
||||
.properName("Parallel Batching")
|
||||
.shortName("batching")
|
||||
.engineMessage(new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN))
|
||||
.engineSupplier(BatchingEngine::new)
|
||||
.fallback(() -> BackendTypes.OFF)
|
||||
.fallback(() -> Backends.OFF)
|
||||
.supported(() -> !ShadersModHandler.isShaderPackInUse())
|
||||
.register();
|
||||
.register(Flywheel.rl("batching"));
|
||||
|
||||
/**
|
||||
* Use GPU instancing to render everything.
|
||||
*/
|
||||
public static final BackendType INSTANCING = SimpleBackendType.builder()
|
||||
public static final Backend INSTANCING = SimpleBackend.builder()
|
||||
.properName("GL33 Instanced Arrays")
|
||||
.shortName("instancing")
|
||||
.engineMessage(new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN))
|
||||
.engineSupplier(() -> new InstancingEngine(Contexts.WORLD, 100 * 100))
|
||||
.fallback(() -> BackendTypes.BATCHING)
|
||||
.fallback(() -> Backends.BATCHING)
|
||||
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
|
||||
.instancedArraysSupported())
|
||||
.pipelineShader(Pipelines.INSTANCED_ARRAYS)
|
||||
.register();
|
||||
.register(Flywheel.rl("instancing"));
|
||||
|
||||
/**
|
||||
* Use Compute shaders to cull instances.
|
||||
*/
|
||||
public static final BackendType INDIRECT = SimpleBackendType.builder()
|
||||
public static final Backend INDIRECT = SimpleBackend.builder()
|
||||
.properName("GL46 Compute Culling")
|
||||
.shortName("indirect")
|
||||
.engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
|
||||
.engineSupplier(() -> new IndirectEngine(Contexts.WORLD, 100 * 100))
|
||||
.fallback(() -> BackendTypes.INSTANCING)
|
||||
.fallback(() -> Backends.INSTANCING)
|
||||
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
|
||||
.supportsIndirect())
|
||||
.pipelineShader(Pipelines.INDIRECT)
|
||||
.register();
|
||||
|
||||
public static BackendType register(BackendType type) {
|
||||
BACKEND_TYPES.put(type.getShortName(), type);
|
||||
return type;
|
||||
}
|
||||
|
||||
public static BackendType defaultForCurrentPC() {
|
||||
// TODO: Automatically select the best default config based on the user's driver
|
||||
return INDIRECT;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BackendType getBackendType(String name) {
|
||||
return BACKEND_TYPES.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static Collection<String> validNames() {
|
||||
return BACKEND_TYPES.keySet();
|
||||
}
|
||||
.register(Flywheel.rl("indirect"));
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
}
|
||||
|
||||
|
||||
public static Collection<Pipeline> availablePipelineShaders() {
|
||||
return BACKEND_TYPES.values()
|
||||
.stream()
|
||||
.filter(BackendType::supported)
|
||||
.map(BackendType::pipelineShader)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -5,26 +5,23 @@ import java.util.function.Supplier;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendType;
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.Engine;
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class SimpleBackendType implements BackendType {
|
||||
|
||||
|
||||
public class SimpleBackend implements Backend {
|
||||
private final String properName;
|
||||
private final String shortName;
|
||||
private final Component engineMessage;
|
||||
private final Supplier<Engine> engineSupplier;
|
||||
private final Supplier<BackendType> fallback;
|
||||
private final Supplier<Backend> fallback;
|
||||
private final BooleanSupplier isSupported;
|
||||
private final Pipeline pipelineShader;
|
||||
|
||||
public SimpleBackendType(String properName, String shortName, Component engineMessage, Supplier<Engine> engineSupplier, Supplier<BackendType> fallback, BooleanSupplier isSupported, @Nullable Pipeline pipelineShader) {
|
||||
public SimpleBackend(String properName, Component engineMessage, Supplier<Engine> engineSupplier, Supplier<Backend> fallback, BooleanSupplier isSupported, @Nullable Pipeline pipelineShader) {
|
||||
this.properName = properName;
|
||||
this.shortName = shortName;
|
||||
this.engineMessage = engineMessage;
|
||||
this.engineSupplier = engineSupplier;
|
||||
this.fallback = fallback;
|
||||
|
@ -41,11 +38,6 @@ public class SimpleBackendType implements BackendType {
|
|||
return properName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getEngineMessage() {
|
||||
return engineMessage;
|
||||
|
@ -57,8 +49,8 @@ public class SimpleBackendType implements BackendType {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BackendType findFallback() {
|
||||
if (this.supported()) {
|
||||
public Backend findFallback() {
|
||||
if (this.isSupported()) {
|
||||
return this;
|
||||
} else {
|
||||
return fallback.get()
|
||||
|
@ -67,7 +59,7 @@ public class SimpleBackendType implements BackendType {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supported() {
|
||||
public boolean isSupported() {
|
||||
return isSupported.getAsBoolean();
|
||||
}
|
||||
|
||||
|
@ -78,10 +70,9 @@ public class SimpleBackendType implements BackendType {
|
|||
|
||||
public static class Builder {
|
||||
private String properName;
|
||||
private String shortName;
|
||||
private Component engineMessage;
|
||||
private Supplier<Engine> engineSupplier;
|
||||
private Supplier<BackendType> fallback;
|
||||
private Supplier<Backend> fallback;
|
||||
private BooleanSupplier isSupported;
|
||||
private Pipeline pipelineShader;
|
||||
|
||||
|
@ -90,11 +81,6 @@ public class SimpleBackendType implements BackendType {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder shortName(String shortName) {
|
||||
this.shortName = shortName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder engineMessage(Component engineMessage) {
|
||||
this.engineMessage = engineMessage;
|
||||
return this;
|
||||
|
@ -105,7 +91,7 @@ public class SimpleBackendType implements BackendType {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder fallback(Supplier<BackendType> fallback) {
|
||||
public Builder fallback(Supplier<Backend> fallback) {
|
||||
this.fallback = fallback;
|
||||
return this;
|
||||
}
|
||||
|
@ -120,8 +106,8 @@ public class SimpleBackendType implements BackendType {
|
|||
return this;
|
||||
}
|
||||
|
||||
public BackendType register() {
|
||||
return BackendTypes.register(new SimpleBackendType(properName, shortName, engineMessage, engineSupplier, fallback, isSupported, pipelineShader));
|
||||
public Backend register(ResourceLocation id) {
|
||||
return Backend.REGISTRY.registerAndGet(id, new SimpleBackend(properName, engineMessage, engineSupplier, fallback, isSupported, pipelineShader));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
package com.jozufozu.flywheel.lib.context;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.context.Context;
|
||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class Contexts {
|
||||
public static final SimpleContext WORLD = ComponentRegistry.register(new SimpleContext(Files.WORLD_VERTEX, Files.WORLD_FRAGMENT));
|
||||
public static final SimpleContext CRUMBLING = ComponentRegistry.register(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
|
||||
public static final SimpleContext WORLD = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.WORLD_FRAGMENT));
|
||||
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package com.jozufozu.flywheel.lib.format;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class Formats {
|
||||
public static final BlockVertex BLOCK = ComponentRegistry.register(new BlockVertex());
|
||||
public static final PosTexNormalVertex POS_TEX_NORMAL = ComponentRegistry.register(new PosTexNormalVertex());
|
||||
public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex());
|
||||
public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex());
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package com.jozufozu.flywheel.lib.instance;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public class SimpleBlockEntityInstancingController<T extends BlockEntity> implements BlockEntityInstancingController<T> {
|
||||
protected BiFunction<InstancerProvider, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public SimpleBlockEntityInstancingController(BiFunction<InstancerProvider, T, BlockEntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
this.skipRender = skipRender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityInstance<? super T> createInstance(InstancerProvider instancerManager, T blockEntity) {
|
||||
return instanceFactory.apply(instancerManager, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipRender(T blockEntity) {
|
||||
return skipRender.test(blockEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object to configure the instancing controller for the given block entity type.
|
||||
* @param type The block entity type to configure.
|
||||
* @param <T> The type of the block entity.
|
||||
* @return The configuration object.
|
||||
*/
|
||||
public static <T extends BlockEntity> BlockEntityConfig<T> configure(BlockEntityType<T> type) {
|
||||
return new BlockEntityConfig<>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object to configure the instancing controller for a block entity.
|
||||
* @param <T> The type of the block entity.
|
||||
*/
|
||||
public static class BlockEntityConfig<T extends BlockEntity> {
|
||||
protected BlockEntityType<T> type;
|
||||
protected BiFunction<InstancerProvider, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public BlockEntityConfig(BlockEntityType<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance factory for the block entity.
|
||||
* @param instanceFactory The instance factory.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public BlockEntityConfig<T> factory(BiFunction<InstancerProvider, T, BlockEntityInstance<? super T>> instanceFactory) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to determine whether to skip rendering a block entity.
|
||||
* @param skipRender The predicate.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public BlockEntityConfig<T> skipRender(Predicate<T> skipRender) {
|
||||
this.skipRender = skipRender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to always skip rendering for block entities of this type.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public BlockEntityConfig<T> alwaysSkipRender() {
|
||||
this.skipRender = be -> true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the block entity instancing controller, and sets it for the block entity type.
|
||||
* @return The block entity instancing controller.
|
||||
*/
|
||||
public SimpleBlockEntityInstancingController<T> apply() {
|
||||
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
|
||||
if (skipRender == null) {
|
||||
skipRender = be -> false;
|
||||
}
|
||||
SimpleBlockEntityInstancingController<T> controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender);
|
||||
InstancedRenderRegistry.setController(type, controller);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package com.jozufozu.flywheel.lib.instance;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancerProvider;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
public class SimpleEntityInstancingController<T extends Entity> implements EntityInstancingController<T> {
|
||||
protected BiFunction<InstancerProvider, T, EntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public SimpleEntityInstancingController(BiFunction<InstancerProvider, T, EntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
this.skipRender = skipRender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInstance<? super T> createInstance(InstancerProvider instancerManager, T entity) {
|
||||
return instanceFactory.apply(instancerManager, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipRender(T entity) {
|
||||
return skipRender.test(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object to configure the instancing controller for the given entity type.
|
||||
* @param type The entity type to configure.
|
||||
* @param <T> The type of the entity.
|
||||
* @return The configuration object.
|
||||
*/
|
||||
public static <T extends Entity> EntityConfig<T> configure(EntityType<T> type) {
|
||||
return new EntityConfig<>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object to configure the instancing controller for an entity.
|
||||
* @param <T> The type of the entity.
|
||||
*/
|
||||
public static class EntityConfig<T extends Entity> {
|
||||
protected EntityType<T> type;
|
||||
protected BiFunction<InstancerProvider, T, EntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public EntityConfig(EntityType<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instance factory for the entity.
|
||||
* @param instanceFactory The instance factory.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public EntityConfig<T> factory(BiFunction<InstancerProvider, T, EntityInstance<? super T>> instanceFactory) {
|
||||
this.instanceFactory = instanceFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to determine whether to skip rendering an entity.
|
||||
* @param skipRender The predicate.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public EntityConfig<T> skipRender(Predicate<T> skipRender) {
|
||||
this.skipRender = skipRender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate to always skip rendering for entities of this type.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public EntityConfig<T> alwaysSkipRender() {
|
||||
this.skipRender = entity -> true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the entity instancing controller, and sets it for the entity type.
|
||||
* @return The entity instancing controller.
|
||||
*/
|
||||
public SimpleEntityInstancingController<T> apply() {
|
||||
Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!");
|
||||
if (skipRender == null) {
|
||||
skipRender = entity -> false;
|
||||
}
|
||||
SimpleEntityInstancingController<T> controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender);
|
||||
InstancedRenderRegistry.setController(type, controller);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,9 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.task.WorkGroup;
|
||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
||||
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||
import com.jozufozu.flywheel.lib.task.WorkGroup;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.jozufozu.flywheel.util.WorldAttached;
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class LightUpdater {
|
|||
}
|
||||
})
|
||||
.onComplete(() -> listeners.forEach(this::addListener))
|
||||
.execute(Backend.getTaskExecutor());
|
||||
.execute(BackendUtil.getTaskExecutor());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package com.jozufozu.flywheel.lib.material;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLists;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
// TODO: add messages to exceptions
|
||||
public class MaterialIndicies {
|
||||
private static Reference2IntMap<Material> materialIndicies;
|
||||
private static Object2IntMap<ResourceLocation> vertexShaderIndicies;
|
||||
private static Object2IntMap<ResourceLocation> fragmentShaderIndicies;
|
||||
private static ObjectList<Material> materialsByIndex;
|
||||
private static ObjectList<ResourceLocation> vertexShadersByIndex;
|
||||
private static ObjectList<ResourceLocation> fragmentShadersByIndex;
|
||||
private static boolean initialized;
|
||||
|
||||
public static int getMaterialIndex(Material material) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return materialIndicies.getInt(material);
|
||||
}
|
||||
|
||||
public static int getVertexShaderIndex(ResourceLocation vertexShader) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return vertexShaderIndicies.getInt(vertexShader);
|
||||
}
|
||||
|
||||
public static int getFragmentShaderIndex(ResourceLocation fragmentShader) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return fragmentShaderIndicies.getInt(fragmentShader);
|
||||
}
|
||||
|
||||
public static Material getMaterial(int index) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return materialsByIndex.get(index);
|
||||
}
|
||||
|
||||
public static ResourceLocation getVertexShader(int index) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return vertexShadersByIndex.get(index);
|
||||
}
|
||||
|
||||
public static ResourceLocation getFragmentShader(int index) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return fragmentShadersByIndex.get(index);
|
||||
}
|
||||
|
||||
@Unmodifiable
|
||||
public static List<Material> getAllMaterials() {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return materialsByIndex;
|
||||
}
|
||||
|
||||
@Unmodifiable
|
||||
public static List<ResourceLocation> getAllVertexShaders() {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return vertexShadersByIndex;
|
||||
}
|
||||
|
||||
@Unmodifiable
|
||||
public static List<ResourceLocation> getAllFragmentShaders() {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return fragmentShadersByIndex;
|
||||
}
|
||||
|
||||
private static void initInner() {
|
||||
int amount = Material.REGISTRY.getAll().size();
|
||||
|
||||
Reference2IntMap<Material> materialIndicies = new Reference2IntOpenHashMap<>();
|
||||
Object2IntMap<ResourceLocation> vertexShaderIndicies = new Object2IntOpenHashMap<>();
|
||||
Object2IntMap<ResourceLocation> fragmentShaderIndicies = new Object2IntOpenHashMap<>();
|
||||
ObjectList<Material> materialsByIndex = new ObjectArrayList<>(amount);
|
||||
ObjectList<ResourceLocation> vertexShadersByIndex = new ObjectArrayList<>(amount);
|
||||
ObjectList<ResourceLocation> fragmentShadersByIndex = new ObjectArrayList<>(amount);
|
||||
|
||||
ObjectSet<ResourceLocation> allVertexShaders = new ObjectOpenHashSet<>();
|
||||
ObjectSet<ResourceLocation> allFragmentShaders = new ObjectOpenHashSet<>();
|
||||
|
||||
int materialIndex = 0;
|
||||
int vertexShaderIndex = 0;
|
||||
int fragmentShaderIndex = 0;
|
||||
for (Material material : Material.REGISTRY) {
|
||||
materialIndicies.put(material, materialIndex);
|
||||
materialsByIndex.add(material);
|
||||
materialIndex++;
|
||||
ResourceLocation vertexShader = material.vertexShader();
|
||||
if (allVertexShaders.add(vertexShader)) {
|
||||
vertexShaderIndicies.put(vertexShader, vertexShaderIndex);
|
||||
vertexShadersByIndex.add(vertexShader);
|
||||
vertexShaderIndex++;
|
||||
}
|
||||
ResourceLocation fragmentShader = material.fragmentShader();
|
||||
if (allFragmentShaders.add(fragmentShader)) {
|
||||
fragmentShaderIndicies.put(fragmentShader, fragmentShaderIndex);
|
||||
fragmentShadersByIndex.add(fragmentShader);
|
||||
fragmentShaderIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
MaterialIndicies.materialIndicies = Reference2IntMaps.unmodifiable(materialIndicies);
|
||||
MaterialIndicies.vertexShaderIndicies = Object2IntMaps.unmodifiable(vertexShaderIndicies);
|
||||
MaterialIndicies.fragmentShaderIndicies = Object2IntMaps.unmodifiable(fragmentShaderIndicies);
|
||||
MaterialIndicies.materialsByIndex = ObjectLists.unmodifiable(materialsByIndex);
|
||||
MaterialIndicies.vertexShadersByIndex = ObjectLists.unmodifiable(vertexShadersByIndex);
|
||||
MaterialIndicies.fragmentShadersByIndex = ObjectLists.unmodifiable(fragmentShadersByIndex);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void init() {
|
||||
Material.REGISTRY.addFreezeCallback(MaterialIndicies::initInner);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.lib.material;
|
||||
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
|
||||
import net.minecraft.client.renderer.RenderStateShard;
|
||||
|
@ -107,7 +106,7 @@ public class SimpleMaterial implements Material {
|
|||
}
|
||||
|
||||
public SimpleMaterial register() {
|
||||
return ComponentRegistry.register(new SimpleMaterial(vertexShader, fragmentShader, setup, clear, batchingRenderType, vertexTransformer));
|
||||
return Material.REGISTRY.registerAndGet(new SimpleMaterial(vertexShader, fragmentShader, setup, clear, batchingRenderType, vertexTransformer));
|
||||
}
|
||||
|
||||
private static Runnable chain(Runnable runnable1, Runnable runnable2) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.jozufozu.flywheel.lib.pipeline;
|
||||
|
||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||
import com.jozufozu.flywheel.api.pipeline.SourceComponent;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package com.jozufozu.flywheel.lib.struct;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class StructTypes {
|
||||
public static final StructType<TransformedPart> TRANSFORMED = ComponentRegistry.register(new TransformedType());
|
||||
public static final StructType<OrientedPart> ORIENTED = ComponentRegistry.register(new OrientedType());
|
||||
public static final StructType<TransformedPart> TRANSFORMED = StructType.REGISTRY.registerAndGet(new TransformedType());
|
||||
public static final StructType<OrientedPart> ORIENTED = StructType.REGISTRY.registerAndGet(new OrientedType());
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.backend.task;
|
||||
package com.jozufozu.flywheel.lib.task;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Executor;
|
|
@ -5,7 +5,6 @@ import java.util.function.Consumer;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.component.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||
|
@ -20,7 +19,7 @@ import net.minecraft.world.phys.Vec3;
|
|||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
public class FlwShaderUniforms implements ShaderUniforms {
|
||||
public static final FlwShaderUniforms INSTANCE = ComponentRegistry.register(new FlwShaderUniforms());
|
||||
public static final FlwShaderUniforms INSTANCE = ShaderUniforms.REGISTRY.registerAndGet(new FlwShaderUniforms());
|
||||
|
||||
public static final ResourceLocation FILE = Flywheel.rl("uniform/flywheel.glsl");
|
||||
public static final int SIZE = 224;
|
||||
|
|
|
@ -7,8 +7,8 @@ import org.lwjgl.opengl.GL32C;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.backend.engine.instancing.ElementBuffer;
|
||||
import com.jozufozu.flywheel.gl.GlNumericType;
|
||||
import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.gl.buffer.GlBufferUsage;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
|
|
@ -6,7 +6,9 @@ import java.util.function.BooleanSupplier;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.client.Camera;
|
||||
|
@ -14,6 +16,8 @@ import net.minecraft.client.renderer.culling.Frustum;
|
|||
import net.minecraftforge.fml.ModList;
|
||||
|
||||
public final class ShadersModHandler {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
|
||||
public static final String SHADER_PACKAGE = "net.optifine.shaders";
|
||||
|
||||
|
@ -30,13 +34,13 @@ public final class ShadersModHandler {
|
|||
// optfine and oculus are assumed to be mutually exclusive
|
||||
|
||||
if (isOptifineInstalled) {
|
||||
Backend.LOGGER.info("Optifine detected.");
|
||||
LOGGER.info("Optifine detected.");
|
||||
internalHandler = new Optifine();
|
||||
} else if (isOculusLoaded) {
|
||||
Backend.LOGGER.info("Oculus detected.");
|
||||
LOGGER.info("Oculus detected.");
|
||||
internalHandler = new Oculus();
|
||||
} else {
|
||||
Backend.LOGGER.info("No shaders mod detected.");
|
||||
LOGGER.info("No shaders mod detected.");
|
||||
internalHandler = new InternalHandler() {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instance.blockentity.BlockEntityInstancingController;
|
||||
import com.jozufozu.flywheel.extension.BlockEntityTypeExtension;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
|
|
@ -9,8 +9,8 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.api.instance.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.extension.ClientLevelExtension;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
@ -29,7 +29,7 @@ public abstract class ClientLevelMixin implements ClientLevelExtension {
|
|||
|
||||
@Inject(method = "entitiesForRendering", at = @At("RETURN"), cancellable = true)
|
||||
private void flywheel$filterEntities(CallbackInfoReturnable<Iterable<Entity>> cir) {
|
||||
if (Backend.isOn()) {
|
||||
if (BackendManager.isOn()) {
|
||||
Iterable<Entity> entities = cir.getReturnValue();
|
||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.api.instance.entity.EntityInstancingController;
|
||||
import com.jozufozu.flywheel.extension.EntityTypeExtension;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue