diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index a48b1b1a6..2fc8897dc 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -59,6 +59,8 @@ body: label: Mod Version description: The version of the mod you were using when the bug occured options: + - "0.5.1" + - "0.5.0a" - "0.5.0" - "0.4.2-rc" - "0.4.1" diff --git a/.gitignore b/.gitignore index 0123b6707..fe6afb8ac 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ run/ .gradle/ build/ gradle-app.setting +out/ ## IntelliJ IDEA diff --git a/gradle.properties b/gradle.properties index fb86b8d59..570812746 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G org.gradle.daemon = false # mod version info -mod_version = 0.5.0a +mod_version = 0.5.1 mc_update_version = 1.18 minecraft_version = 1.18.1 forge_version = 39.0.8 diff --git a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java index 3d7f7adb5..d3a46a9a7 100644 --- a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java +++ b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java @@ -15,7 +15,6 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; public class FlywheelClient { public static void clientInit() { - CrashReportCallables.registerCrashCallable("Flywheel Backend", () -> Backend.getInstance().getBackendDescriptor()); diff --git a/src/main/java/com/jozufozu/flywheel/api/FlywheelRendered.java b/src/main/java/com/jozufozu/flywheel/api/FlywheelRendered.java deleted file mode 100644 index 7ccb6149c..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/FlywheelRendered.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.jozufozu.flywheel.api; - -/** - * Something (a BlockEntity or Entity) that can be rendered using the instancing API. - */ -public interface FlywheelRendered { - - /** - * @return true if there are parts of the renderer that cannot be implemented with Flywheel. - */ - default boolean shouldRenderNormally() { - return false; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/api/FlywheelWorld.java b/src/main/java/com/jozufozu/flywheel/api/FlywheelWorld.java index 5cfa5320b..968535ed0 100644 --- a/src/main/java/com/jozufozu/flywheel/api/FlywheelWorld.java +++ b/src/main/java/com/jozufozu/flywheel/api/FlywheelWorld.java @@ -2,7 +2,8 @@ package com.jozufozu.flywheel.api; /** * A marker interface custom worlds can override to indicate - * that tiles inside the world should render with Flywheel. + * that block entities and entities inside the world should + * render with Flywheel. * * {@link net.minecraft.client.Minecraft#level Minecraft#level} is special cased and will support Flywheel by default. */ diff --git a/src/main/java/com/jozufozu/flywheel/api/Instancer.java b/src/main/java/com/jozufozu/flywheel/api/Instancer.java index 8ea0c3f70..5b6ac1cb4 100644 --- a/src/main/java/com/jozufozu/flywheel/api/Instancer.java +++ b/src/main/java/com/jozufozu/flywheel/api/Instancer.java @@ -50,4 +50,14 @@ public interface Instancer { *

*/ void notifyRemoval(); + + /** + * Populate arr with new instances of this model. + * @param arr An array to fill. + */ + default void createInstances(D[] arr) { + for (int i = 0; i < arr.length; i++) { + arr[i] = createInstance(); + } + } } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/IDynamicInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java similarity index 74% rename from src/main/java/com/jozufozu/flywheel/api/instance/IDynamicInstance.java rename to src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java index 75b4bdc15..86e43e77b 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/IDynamicInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java @@ -2,18 +2,18 @@ package com.jozufozu.flywheel.api.instance; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; -import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; /** - * An interface giving {@link TileEntityInstance}s a hook to have a function called at - * the start of a frame. By implementing {@link IDynamicInstance}, a {@link TileEntityInstance} + * An interface giving {@link BlockEntityInstance}s a hook to have a function called at + * the start of a frame. By implementing {@link DynamicInstance}, a {@link BlockEntityInstance} * can animate its models in ways that could not be easily achieved by shader attribute * parameterization. * *

If your goal is offloading work to shaders, but you're unsure exactly how you need * to parameterize the instances, you're encouraged to implement this for prototyping. */ -public interface IDynamicInstance extends IInstance { +public interface DynamicInstance extends Instance { /** * Called every frame, and after initialization. *
@@ -30,7 +30,7 @@ public interface IDynamicInstance extends IInstance { *
You might want to opt out of this if you want your animations to remain smooth * even when far away from the camera. It is recommended to keep this as is, however. * - * @return true if your instance should be slow ticked. + * @return {@code true} if your instance should be slow ticked. */ default boolean decreaseFramerateWithDistance() { return true; diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/IInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java similarity index 80% rename from src/main/java/com/jozufozu/flywheel/api/instance/IInstance.java rename to src/main/java/com/jozufozu/flywheel/api/instance/Instance.java index 843cfb147..88a49c4fc 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/IInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java @@ -2,6 +2,6 @@ package com.jozufozu.flywheel.api.instance; import net.minecraft.core.BlockPos; -public interface IInstance { +public interface Instance { BlockPos getWorldPosition(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/ITickableInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java similarity index 75% rename from src/main/java/com/jozufozu/flywheel/api/instance/ITickableInstance.java rename to src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java index c0d32cb29..488ba8697 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/ITickableInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java @@ -2,13 +2,13 @@ package com.jozufozu.flywheel.api.instance; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; -import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; /** - * An interface giving {@link TileEntityInstance}s a hook to have a function called at - * the end of every tick. By implementing {@link ITickableInstance}, a {@link TileEntityInstance} + * An interface giving {@link BlockEntityInstance}s a hook to have a function called at + * the end of every tick. By implementing {@link TickableInstance}, a {@link BlockEntityInstance} * can update frequently, but not every frame. - *
There are a few cases in which this should be considered over {@link IDynamicInstance}: + *
There are a few cases in which this should be considered over {@link DynamicInstance}: * */ -public interface ITickableInstance extends IInstance { +public interface TickableInstance extends Instance { /** * Called every tick, and after initialization. @@ -38,7 +38,7 @@ public interface ITickableInstance extends IInstance { *
You might want to opt out of this if you want your animations to remain smooth * even when far away from the camera. It is recommended to keep this as is, however. * - * @return true if your instance should be slow ticked. + * @return {@code true} if your instance should be slow ticked. */ default boolean decreaseTickRateWithDistance() { return true; diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index bffbddc46..b365f2458 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -55,7 +55,7 @@ public class Backend { * (Meshlet, MDI, GL31 Draw Instanced are planned), this will name which one is in use. */ public String getBackendDescriptor() { - return engine.getProperName(); + return engine == null ? "" : engine.getProperName(); } public FlwEngine getEngine() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/GameStateRegistry.java b/src/main/java/com/jozufozu/flywheel/backend/GameStateRegistry.java index d7e6af08c..04aa431e6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/GameStateRegistry.java +++ b/src/main/java/com/jozufozu/flywheel/backend/GameStateRegistry.java @@ -3,20 +3,20 @@ package com.jozufozu.flywheel.backend; import java.util.HashMap; import java.util.Map; -import com.jozufozu.flywheel.core.shader.gamestate.IGameStateProvider; +import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider; import net.minecraft.resources.ResourceLocation; public class GameStateRegistry { - private static final Map registeredStateProviders = new HashMap<>(); + private static final Map registeredStateProviders = new HashMap<>(); static void clear() { registeredStateProviders.clear(); } - public static IGameStateProvider getStateProvider(ResourceLocation location) { - IGameStateProvider out = registeredStateProviders.get(location); + public static GameStateProvider getStateProvider(ResourceLocation location) { + GameStateProvider out = registeredStateProviders.get(location); if (out == null) { throw new IllegalArgumentException("State provider '" + location + "' does not exist."); @@ -25,7 +25,7 @@ public class GameStateRegistry { return out; } - public static void register(IGameStateProvider context) { + public static void register(GameStateProvider context) { if (registeredStateProviders.containsKey(context.getID())) { throw new IllegalStateException("Duplicate game state provider: " + context.getID()); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java index f003208fe..51e60eebe 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java @@ -4,7 +4,11 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.lang.reflect.Field; import java.util.Optional; +import java.util.function.BooleanSupplier; + +import com.jozufozu.flywheel.util.Lazy; import net.minecraft.client.Minecraft; @@ -15,6 +19,23 @@ public class OptifineHandler { private static Package optifine; private static OptifineHandler handler; + private static final Lazy isShadowPass = Lazy.of(() -> { + try { + Class ofShaders = Class.forName("net.optifine.shaders.Shaders"); + Field field = ofShaders.getDeclaredField("isShadowPass"); + field.setAccessible(true); + return () -> { + try { + return field.getBoolean(null); + } catch (IllegalAccessException ignored) { + return false; + } + }; + } catch (Exception ignored) { + return () -> false; + } + }); + public final boolean usingShaders; public OptifineHandler(boolean usingShaders) { @@ -40,6 +61,10 @@ public class OptifineHandler { .orElse(false); } + public static boolean isShadowPass() { + return isShadowPass.get().getAsBoolean(); + } + public static void init() { optifine = Package.getPackage(OPTIFINE_ROOT_PACKAGE); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java index c50681c7f..44541854c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java @@ -12,10 +12,17 @@ public class GlVertexArray extends GlObject { setHandle(GlStateManager._glGenVertexArrays()); } + public static void bind(int vao) { + GlStateManager._glBindVertexArray(vao); + BufferUploaderAccessor.flywheel$setLastVAO(vao); + } + public void bind() { - int handle = handle(); - GlStateManager._glBindVertexArray(handle); - BufferUploaderAccessor.flywheel$setLastVAO(handle); + bind(handle()); + } + + public static int getBoundVertexArray() { + return BufferUploaderAccessor.flywheel$getLastVAO(); } public static void unbind() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java index 53a0ab9ac..16f0c450a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java @@ -50,4 +50,12 @@ public enum GlBufferType { case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$setLastVBO(0); } } + + public int getBoundBuffer() { + return switch (this.glEnum) { + case GL15C.GL_ELEMENT_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$getLastEBO(); + case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$getLastVBO(); + default -> -1; + }; + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java index d019832b7..8615e9086 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java @@ -4,7 +4,7 @@ import org.lwjgl.opengl.GLCapabilities; /** * This interface should be implemented by enums such that the - * last defined variant always returns true. + * last defined variant always returns {@code true} */ public interface GlVersioned { /** diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java index a194a265c..6a3e67ba8 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java @@ -4,15 +4,15 @@ import java.util.Arrays; import java.util.stream.Stream; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.api.instance.IInstance; -import com.jozufozu.flywheel.api.instance.ITickableInstance; -import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; +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.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.core.materials.FlatLit; -import com.jozufozu.flywheel.util.box.ImmutableBox; import com.jozufozu.flywheel.light.LightListener; import com.jozufozu.flywheel.light.LightProvider; import com.jozufozu.flywheel.light.ListenerStatus; +import com.jozufozu.flywheel.util.box.ImmutableBox; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -20,9 +20,9 @@ import net.minecraft.world.level.LightLayer; /** * A general interface providing information about any type of thing that could use Flywheel's instanced rendering. - * Right now, that's only {@link TileInstanceManager}, but there could be an entity equivalent in the future. + * Right now, that's only {@link BlockEntityInstanceManager}, but there could be an entity equivalent in the future. */ -public abstract class AbstractInstance implements IInstance, LightListener { +public abstract class AbstractInstance implements Instance, LightListener { protected final MaterialManager materialManager; public final Level world; @@ -48,7 +48,7 @@ public abstract class AbstractInstance implements IInstance, LightListener { * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. * Don't query lighting data here, that's handled separately in {@link #updateLight()}. * - *

If your animations are complex or more CPU driven, see {@link IDynamicInstance} or {@link ITickableInstance}. + *

If your animations are complex or more CPU driven, see {@link DynamicInstance} or {@link TickableInstance}. */ public void update() { } @@ -65,13 +65,13 @@ public abstract class AbstractInstance implements IInstance, LightListener { * When an instance is reset, the instance is deleted and re-created. * *

- * Just before {@link #update()} would be called, shouldReset() is checked. - * If this function returns true, then this instance will be {@link #remove removed}, + * Just before {@link #update()} would be called, {@code shouldReset()} is checked. + * If this function returns {@code true}, then this instance will be {@link #remove removed}, * and another instance will be constructed to replace it. This allows for more sane resource * acquisition compared to trying to update everything within the lifetime of an instance. *

* - * @return true if this instance should be discarded and refreshed. + * @return {@code true} if this instance should be discarded and refreshed. */ public boolean shouldReset() { return false; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java index ef1a6824c..e353a7104 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstancer.java @@ -6,7 +6,6 @@ import java.util.function.Supplier; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; -import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.core.model.Model; public abstract class AbstractInstancer implements Instancer { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/BatchDrawingTracker.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/BatchDrawingTracker.java new file mode 100644 index 000000000..ee1bee295 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/BatchDrawingTracker.java @@ -0,0 +1,83 @@ +package com.jozufozu.flywheel.backend.instancing; + +import java.util.HashSet; +import java.util.Set; + +import com.jozufozu.flywheel.backend.model.BufferBuilderExtension; +import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; +import com.mojang.blaze3d.vertex.BufferBuilder; + +import net.minecraft.client.renderer.RenderType; + +public class BatchDrawingTracker { + + protected final Set activeTypes = new HashSet<>(); + private final BufferBuilder scratch; + + public BatchDrawingTracker() { + scratch = new BufferBuilder(8); + + ((BufferBuilderExtension) scratch).flywheel$freeBuffer(); + } + + /** + * Get a direct vertex consumer for drawing the given number of vertices to the given RenderType. + * @param renderType The RenderType to draw to. + * @param vertexCount The number of vertices that will be drawn. + * @return A direct vertex consumer. + */ + public DirectVertexConsumer getDirectConsumer(RenderType renderType, int vertexCount) { + activeTypes.add(renderType); + return RenderTypeExtension.getDrawBuffer(renderType) + .begin(vertexCount); + } + + /** + * Draws all active DrawBuffers and reset them. + */ + public void endBatch() { + // TODO: when/if this causes trouble with shaders, try to inject our BufferBuilders + // into the RenderBuffers from context. + + for (RenderType renderType : activeTypes) { + _draw(renderType); + } + + activeTypes.clear(); + } + + /** + * Draw and reset the DrawBuffer for the given RenderType. + * @param renderType The RenderType to draw. + */ + public void endBatch(RenderType renderType) { + _draw(renderType); + + activeTypes.remove(renderType); + } + + /** + * Resets all DrawBuffers to 0 vertices. + */ + public void clear() { + for (RenderType type : activeTypes) { + RenderTypeExtension.getDrawBuffer(type) + .reset(); + } + activeTypes.clear(); + } + + private void _draw(RenderType renderType) { + DrawBuffer drawBuffer = RenderTypeExtension.getDrawBuffer(renderType); + + BufferBuilderExtension scratch = (BufferBuilderExtension) this.scratch; + if (drawBuffer.hasVertices()) { + drawBuffer.inject(scratch); + + renderType.end(this.scratch, 0, 0, 0); + + drawBuffer.reset(); + } + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/DrawBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/DrawBuffer.java new file mode 100644 index 000000000..4166c1e59 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/DrawBuffer.java @@ -0,0 +1,77 @@ +package com.jozufozu.flywheel.backend.instancing; + +import java.nio.ByteBuffer; + +import com.jozufozu.flywheel.backend.model.BufferBuilderExtension; +import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; +import com.mojang.blaze3d.platform.MemoryTracker; +import com.mojang.blaze3d.vertex.VertexFormat; + +import net.minecraft.client.renderer.RenderType; + +/** + * A byte buffer that can be used to draw vertices through a {@link DirectVertexConsumer}. + * + * The number of vertices needs to be known ahead of time. + */ +public class DrawBuffer { + + private final RenderType parent; + private ByteBuffer backingBuffer; + private int expectedVertices; + + public DrawBuffer(RenderType parent) { + this.parent = parent; + } + + /** + * Creates a direct vertex consumer that can be used to write vertices into this buffer. + * @param vertexCount The number of vertices to reserve memory for. + * @return A direct vertex consumer. + * @throws IllegalStateException If the buffer is already in use. + */ + public DirectVertexConsumer begin(int vertexCount) { + if (expectedVertices != 0) { + throw new IllegalStateException("Already drawing"); + } + + this.expectedVertices = vertexCount; + + VertexFormat format = parent.format(); + + int byteSize = format.getVertexSize() * vertexCount; + + if (backingBuffer == null) { + backingBuffer = MemoryTracker.create(byteSize); + } + if (byteSize > backingBuffer.capacity()) { + backingBuffer = MemoryTracker.resize(backingBuffer, byteSize); + } + + return new DirectVertexConsumer(backingBuffer, format, vertexCount); + } + + /** + * Injects the backing buffer into the given builder and prepares it for rendering. + * @param bufferBuilder The buffer builder to inject into. + */ + public void inject(BufferBuilderExtension bufferBuilder) { + bufferBuilder.flywheel$injectForRender(backingBuffer, parent.format(), expectedVertices); + } + + /** + * @return {@code true} if the buffer has any vertices. + */ + public boolean hasVertices() { + return expectedVertices > 0; + } + + /** + * Reset the draw buffer to have no vertices. + * + * Does not clear the backing buffer. + */ + public void reset() { + this.expectedVertices = 0; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index 6741c513c..8c79fe8e9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -10,8 +10,8 @@ import java.util.Set; import javax.annotation.Nullable; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.api.instance.ITickableInstance; +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.instancing.instancing.InstancingEngine; import com.jozufozu.flywheel.light.LightUpdater; @@ -30,8 +30,8 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift private final Set queuedUpdates; protected final Map instances; - protected final Object2ObjectOpenHashMap tickableInstances; - protected final Object2ObjectOpenHashMap dynamicInstances; + protected final Object2ObjectOpenHashMap tickableInstances; + protected final Object2ObjectOpenHashMap dynamicInstances; protected int frame; protected int tick; @@ -71,7 +71,7 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift * Ticks the InstanceManager. * *

- * {@link ITickableInstance}s get ticked. + * {@link TickableInstance}s get ticked. *
* Queued updates are processed. *

@@ -85,16 +85,16 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift int cY = (int) cameraY; int cZ = (int) cameraZ; - ArrayList instances = new ArrayList<>(tickableInstances.values()); + ArrayList instances = new ArrayList<>(tickableInstances.values()); int incr = 500; int size = instances.size(); int start = 0; while (start < size) { int end = Math.min(start + incr, size); - List sub = instances.subList(start, end); + List sub = instances.subList(start, end); taskEngine.submit(() -> { - for (ITickableInstance instance : sub) { + for (TickableInstance instance : sub) { tickInstance(cX, cY, cZ, instance); } }); @@ -103,7 +103,7 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift } } - private void tickInstance(int cX, int cY, int cZ, ITickableInstance instance) { + private void tickInstance(int cX, int cY, int cZ, TickableInstance instance) { if (!instance.decreaseTickRateWithDistance()) { instance.tick(); return; @@ -132,16 +132,16 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift int cY = (int) info.getPosition().y; int cZ = (int) info.getPosition().z; - ArrayList instances = new ArrayList<>(dynamicInstances.values()); + ArrayList instances = new ArrayList<>(dynamicInstances.values()); int incr = 500; int size = instances.size(); int start = 0; while (start < size) { int end = Math.min(start + incr, size); - List sub = instances.subList(start, end); + List sub = instances.subList(start, end); taskEngine.submit(() -> { - for (IDynamicInstance dyn : sub) { + for (DynamicInstance dyn : sub) { if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ)) dyn.beginFrame(); } @@ -179,8 +179,8 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift * *

* By default this is the only hook an IInstance has to change its internal state. This is the lowest frequency - * update hook IInstance gets. For more frequent updates, see {@link ITickableInstance} and - * {@link IDynamicInstance}. + * update hook IInstance gets. For more frequent updates, see {@link TickableInstance} and + * {@link DynamicInstance}. *

* * @param obj the object to update. @@ -312,12 +312,12 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift .addListener(renderer); instances.put(obj, renderer); - if (renderer instanceof ITickableInstance r) { + if (renderer instanceof TickableInstance r) { tickableInstances.put(obj, r); r.tick(); } - if (renderer instanceof IDynamicInstance r) { + if (renderer instanceof DynamicInstance r) { dynamicInstances.put(obj, r); r.beginFrame(); } @@ -328,9 +328,9 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift @Override public void onOriginShift() { - ArrayList instancedTiles = new ArrayList<>(instances.keySet()); + ArrayList instanced = new ArrayList<>(instances.keySet()); invalidate(); - instancedTiles.forEach(this::add); + instanced.forEach(this::add); } public void detachLightListeners() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index a6167ab24..8274a2e06 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -1,12 +1,12 @@ package com.jozufozu.flywheel.backend.instancing; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.api.instance.ITickableInstance; +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.instancing.batching.BatchingEngine; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager; import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine; -import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; import com.jozufozu.flywheel.config.FlwEngine; import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.core.shader.WorldProgram; @@ -29,7 +29,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; public class InstanceWorld { protected final Engine engine; protected final InstanceManager entityInstanceManager; - protected final InstanceManager tileEntityInstanceManager; + protected final InstanceManager blockEntityInstanceManager; protected final ParallelTaskEngine taskEngine; @@ -48,16 +48,16 @@ public class InstanceWorld { .build(); entityInstanceManager = new EntityInstanceManager(manager); - tileEntityInstanceManager = new TileInstanceManager(manager); + blockEntityInstanceManager = new BlockEntityInstanceManager(manager); manager.addListener(entityInstanceManager); - manager.addListener(tileEntityInstanceManager); + manager.addListener(blockEntityInstanceManager); this.engine = manager; } case BATCHING -> { this.engine = new BatchingEngine(); entityInstanceManager = new EntityInstanceManager(this.engine); - tileEntityInstanceManager = new TileInstanceManager(this.engine); + blockEntityInstanceManager = new BlockEntityInstanceManager(this.engine); } default -> throw new IllegalArgumentException("Unknown engine type"); } @@ -67,8 +67,8 @@ public class InstanceWorld { return entityInstanceManager; } - public InstanceManager getTileEntityInstanceManager() { - return tileEntityInstanceManager; + public InstanceManager getBlockEntityInstanceManager() { + return blockEntityInstanceManager; } /** @@ -78,7 +78,7 @@ public class InstanceWorld { this.taskEngine.stopWorkers(); engine.delete(); entityInstanceManager.detachLightListeners(); - tileEntityInstanceManager.detachLightListeners(); + blockEntityInstanceManager.detachLightListeners(); } /** @@ -86,22 +86,22 @@ public class InstanceWorld { *

* Check and shift the origin coordinate. *
- * Call {@link IDynamicInstance#beginFrame()} on all instances in this world. + * Call {@link DynamicInstance#beginFrame()} on all instances in this world. *

*/ public void beginFrame(BeginFrameEvent event) { - engine.beginFrame(event.getInfo()); + engine.beginFrame(event.getCamera()); taskEngine.syncPoint(); - tileEntityInstanceManager.beginFrame(taskEngine, event.getInfo()); - entityInstanceManager.beginFrame(taskEngine, event.getInfo()); + blockEntityInstanceManager.beginFrame(taskEngine, event.getCamera()); + entityInstanceManager.beginFrame(taskEngine, event.getCamera()); } /** * Tick the renderers after the game has ticked: *

- * Call {@link ITickableInstance#tick()} on all instances in this world. + * Call {@link TickableInstance#tick()} on all instances in this world. *

*/ public void tick() { @@ -110,7 +110,7 @@ public class InstanceWorld { if (renderViewEntity == null) return; - tileEntityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ()); + blockEntityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ()); entityInstanceManager.tick(taskEngine, renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ()); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index 51755ed9f..bfc580517 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -26,13 +26,13 @@ public class InstancedRenderDispatcher { /** * Call this when you want to manually run {@link AbstractInstance#update()}. - * @param te The tile whose instance you want to update. + * @param blockEntity The block entity whose instance you want to update. */ - public static void enqueueUpdate(BlockEntity te) { - if (Backend.isOn() && te.hasLevel() && te.getLevel() instanceof ClientLevel) { - instanceWorlds.get(te.getLevel()) - .getTileEntityInstanceManager() - .queueUpdate(te); + public static void enqueueUpdate(BlockEntity blockEntity) { + if (Backend.isOn() && blockEntity.hasLevel() && blockEntity.getLevel() instanceof ClientLevel) { + instanceWorlds.get(blockEntity.getLevel()) + .getBlockEntityInstanceManager() + .queueUpdate(blockEntity); } } @@ -48,10 +48,10 @@ public class InstancedRenderDispatcher { } } - public static InstanceManager getTiles(LevelAccessor world) { + public static InstanceManager getBlockEntities(LevelAccessor world) { if (Backend.isOn()) { return instanceWorlds.get(world) - .getTileEntityInstanceManager(); + .getBlockEntityInstanceManager(); } else { throw new NullPointerException("Backend is off, cannot retrieve instance world."); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java index db0c325a4..1946dabdb 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderRegistry.java @@ -1,134 +1,304 @@ package com.jozufozu.flywheel.backend.instancing; -import java.util.Map; +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.Predicate; import javax.annotation.Nullable; -import com.google.common.collect.Maps; -import com.jozufozu.flywheel.api.FlywheelRendered; import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension; +import com.jozufozu.flywheel.backend.instancing.blockentity.SimpleBlockEntityInstancingController; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; -import com.jozufozu.flywheel.backend.instancing.entity.IEntityInstanceFactory; -import com.jozufozu.flywheel.backend.instancing.tile.ITileInstanceFactory; -import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; +import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController; +import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension; +import com.jozufozu.flywheel.backend.instancing.entity.SimpleEntityInstancingController; -import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; +/** + * A utility class for registering and retrieving {@code InstancingController}s. + */ +@SuppressWarnings("unchecked") public class InstancedRenderRegistry { - private static final InstancedRenderRegistry INSTANCE = new InstancedRenderRegistry(); - - public static InstancedRenderRegistry getInstance() { - return INSTANCE; + /** + * Checks if the given block entity type can be instanced. + * @param type The block entity type to check. + * @param The type of the block entity. + * @return {@code true} if the block entity type can be instanced. + */ + public static boolean canInstance(BlockEntityType type) { + return getController(type) != null; } - private final Object2BooleanMap skipRender = new Object2BooleanLinkedOpenHashMap<>(); - private final Map, ITileInstanceFactory> tiles = Maps.newHashMap(); - private final Map, IEntityInstanceFactory> entities = Maps.newHashMap(); - - protected InstancedRenderRegistry() { - skipRender.defaultReturnValue(false); + /** + * Checks if the given entity type can be instanced. + * @param type The entity type to check. + * @param The type of the entity. + * @return {@code true} if the entity type can be instanced. + */ + public static boolean canInstance(EntityType type) { + return getController(type) != null; } - public boolean shouldSkipRender(T type) { - return _skipRender(type.getType()) || ((type instanceof FlywheelRendered) && !((FlywheelRendered) type).shouldRenderNormally()); + /** + * Creates an instance for the given block entity, if possible. + * @param materialManager The material manager to use. + * @param blockEntity The block entity to create an instance of. + * @param The type of the block entity. + * @return An instance of the block entity, or {@code null} if the block entity cannot be instanced. + */ + @Nullable + public static BlockEntityInstance createInstance(MaterialManager materialManager, T blockEntity) { + BlockEntityInstancingController controller = getController(getType(blockEntity)); + if (controller == null) { + return null; + } + return controller.createInstance(materialManager, blockEntity); } - public boolean shouldSkipRender(T type) { - return _skipRender(type.getType()) || ((type instanceof FlywheelRendered) && !((FlywheelRendered) type).shouldRenderNormally()); + /** + * Creates an instance for the given entity, if possible. + * @param materialManager The material manager to use. + * @param entity The entity to create an instance of. + * @param The type of the entity. + * @return An instance of the entity, or {@code null} if the entity cannot be instanced. + */ + @Nullable + public static EntityInstance createInstance(MaterialManager materialManager, T entity) { + EntityInstancingController controller = getController(getType(entity)); + if (controller == null) { + return null; + } + return controller.createInstance(materialManager, entity); } - public boolean canInstance(BlockEntityType type) { - return tiles.containsKey(type); + /** + * Checks if the given block entity is instanced and should not be rendered normally. + * @param blockEntity The block entity to check. + * @param The type of the block entity. + * @return {@code true} if the block entity is instanced and should not be rendered normally. + */ + public static boolean shouldSkipRender(T blockEntity) { + BlockEntityInstancingController controller = getController(getType(blockEntity)); + if (controller == null) { + return false; + } + return controller.shouldSkipRender(blockEntity); } - public boolean canInstance(EntityType type) { - return entities.containsKey(type); + /** + * Checks if the given entity is instanced and should not be rendered normally. + * @param entity The entity to check. + * @param The type of the entity. + * @return {@code true} if the entity is instanced and should not be rendered normally. + */ + public static boolean shouldSkipRender(T entity) { + EntityInstancingController controller = getController(getType(entity)); + if (controller == null) { + return false; + } + return controller.shouldSkipRender(entity); } - public TileConfig tile(BlockEntityType type) { - return new TileConfig<>(type); + /** + * Get an object to configure the instancing controller for the given block entity type. + * @param type The block entity type to configure. + * @param The type of the block entity. + * @return The configuration object. + */ + public static BlockEntityConfig configure(BlockEntityType type) { + return new BlockEntityConfig<>(type); } - public EntityConfig entity(EntityType type) { + /** + * Get an object to configure the instancing controller for the given entity type. + * @param type The entity type to configure. + * @param The type of the entity. + * @return The configuration object. + */ + public static EntityConfig configure(EntityType type) { return new EntityConfig<>(type); } - @SuppressWarnings("unchecked") + /** + * 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. + * @param The type of the block entity. + * @return The instancing controller for the given block entity type, or {@code null} if none exists. + */ @Nullable - public TileEntityInstance create(MaterialManager manager, T tile) { - BlockEntityType type = tile.getType(); - ITileInstanceFactory factory = (ITileInstanceFactory) this.tiles.get(type); - - if (factory == null) return null; - else return factory.create(manager, tile); + public static BlockEntityInstancingController getController(BlockEntityType type) { + return ((BlockEntityTypeExtension) type).flywheel$getInstancingController(); } - - @SuppressWarnings("unchecked") + /** + * Gets the instancing controller for the given entity type, if one exists. + * @param type The entity type to get the instancing controller for. + * @param The type of the entity. + * @return The instancing controller for the given entity type, or {@code null} if none exists. + */ @Nullable - public EntityInstance create(MaterialManager manager, T tile) { - EntityType type = tile.getType(); - IEntityInstanceFactory factory = (IEntityInstanceFactory) this.entities.get(type); - - if (factory == null) return null; - else return factory.create(manager, tile); + public static EntityInstancingController getController(EntityType type) { + return ((EntityTypeExtension) type).flywheel$getInstancingController(); } - private boolean _skipRender(Object o) { - return skipRender.getBoolean(o); + /** + * Sets the instancing controller for the given block entity type. + * @param type The block entity type to set the instancing controller for. + * @param instancingController The instancing controller to set. + * @param The type of the block entity. + */ + public static void setController(BlockEntityType type, BlockEntityInstancingController instancingController) { + ((BlockEntityTypeExtension) type).flywheel$setInstancingController(instancingController); } - public interface Config, FACTORY> { - - CONFIG factory(FACTORY rendererFactory); - - CONFIG setSkipRender(boolean skipRender); + /** + * Sets the instancing controller for the given entity type. + * @param type The entity type to set the instancing controller for. + * @param instancingController The instancing controller to set. + * @param The type of the entity. + */ + public static void setController(EntityType type, EntityInstancingController instancingController) { + ((EntityTypeExtension) type).flywheel$setInstancingController(instancingController); } - public class TileConfig implements Config, ITileInstanceFactory> { + /** + * Gets the type of the given block entity. + * @param blockEntity The block entity to get the type of. + * @param The type of the block entity. + * @return The {@link BlockEntityType} associated with the given block entity. + */ + public static BlockEntityType getType(T blockEntity) { + return (BlockEntityType) blockEntity.getType(); + } - private final BlockEntityType type; + /** + * Gets the type of the given entity. + * @param entity The entity to get the type of. + * @param The type of the entity. + * @return The {@link EntityType} associated with the given entity. + */ + public static EntityType getType(T entity) { + return (EntityType) entity.getType(); + } - public TileConfig(BlockEntityType type) { + /** + * An object to configure the instancing controller for a block entity. + * @param The type of the block entity. + */ + public static class BlockEntityConfig { + protected BlockEntityType type; + protected BiFunction> instanceFactory; + protected Predicate skipRender; + + public BlockEntityConfig(BlockEntityType type) { this.type = type; } - public TileConfig factory(ITileInstanceFactory rendererFactory) { - tiles.put(type, rendererFactory); + /** + * Sets the instance factory for the block entity. + * @param instanceFactory The instance factory. + * @return {@code this} + */ + public BlockEntityConfig factory(BiFunction> instanceFactory) { + this.instanceFactory = instanceFactory; return this; } - public TileConfig setSkipRender(boolean skipRender) { - InstancedRenderRegistry.this.skipRender.put(type, skipRender); + /** + * Sets a predicate to determine whether to skip rendering a block entity. + * @param skipRender The predicate. + * @return {@code this} + */ + public BlockEntityConfig skipRender(Predicate skipRender) { + this.skipRender = skipRender; return this; } + /** + * Sets a predicate to always skip rendering for block entities of this type. + * @return {@code this} + */ + public BlockEntityConfig 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 apply() { + Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!"); + if (skipRender == null) { + skipRender = be -> false; + } + SimpleBlockEntityInstancingController controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender); + setController(type, controller); + return controller; + } } - public class EntityConfig implements Config, IEntityInstanceFactory> { - - private final EntityType type; + /** + * An object to configure the instancing controller for an entity. + * @param The type of the entity. + */ + public static class EntityConfig { + protected EntityType type; + protected BiFunction> instanceFactory; + protected Predicate skipRender; public EntityConfig(EntityType type) { this.type = type; } - public EntityConfig factory(IEntityInstanceFactory rendererFactory) { - entities.put(type, rendererFactory); + /** + * Sets the instance factory for the entity. + * @param instanceFactory The instance factory. + * @return {@code this} + */ + public EntityConfig factory(BiFunction> instanceFactory) { + this.instanceFactory = instanceFactory; return this; } - public EntityConfig setSkipRender(boolean skipRender) { - InstancedRenderRegistry.this.skipRender.put(type, skipRender); - + /** + * Sets a predicate to determine whether to skip rendering an entity. + * @param skipRender The predicate. + * @return {@code this} + */ + public EntityConfig skipRender(Predicate skipRender) { + this.skipRender = skipRender; return this; } + /** + * Sets a predicate to always skip rendering for entities of this type. + * @return {@code this} + */ + public EntityConfig 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 apply() { + Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!"); + if (skipRender == null) { + skipRender = entity -> false; + } + SimpleEntityInstancingController controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender); + setController(type, controller); + return controller; + } } - } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderTypeExtension.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderTypeExtension.java new file mode 100644 index 000000000..d95ea68c1 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderTypeExtension.java @@ -0,0 +1,25 @@ +package com.jozufozu.flywheel.backend.instancing; + +import net.minecraft.client.renderer.RenderType; + +/** + * Duck interface to make RenderType store a DrawBuffer. + * + * @see RenderType + */ +public interface RenderTypeExtension { + + /** + * @return The DrawBuffer associated with this RenderType. + */ + DrawBuffer flywheel$getDrawBuffer(); + + /** + * Helper function to cast a RenderType to a RenderTypeExtension and get its DrawBuffer. + * @param type The RenderType to get the DrawBuffer from. + * @return The DrawBuffer associated with the given RenderType. + */ + static DrawBuffer getDrawBuffer(RenderType type) { + return ((RenderTypeExtension) type).flywheel$getDrawBuffer(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/SuperBufferSource.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/SuperBufferSource.java deleted file mode 100644 index 20984c03b..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/SuperBufferSource.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; - -import com.jozufozu.flywheel.backend.model.BufferBuilderHack; -import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; -import com.mojang.blaze3d.platform.MemoryTracker; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.VertexFormat; - -import net.minecraft.client.renderer.RenderType; - -public class SuperBufferSource { - - protected final Map buffers = new HashMap<>(); - private final BufferBuilder scratch; - - public SuperBufferSource() { - scratch = new BufferBuilder(8); - - ((BufferBuilderHack) scratch).flywheel$freeBuffer(); - } - - public DirectVertexConsumer getBuffer(RenderType renderType, int vertexCount) { - return buffers.computeIfAbsent(renderType, DrawBuffer::new) - .begin(vertexCount); - } - - public void endBatch() { - // TODO: when/if this causes trouble with shaders, try to inject our BufferBuilders - // into the RenderBuffers from context. - - BufferBuilderHack hack = (BufferBuilderHack) scratch; - - for (Map.Entry entry : buffers.entrySet()) { - DrawBuffer builder = entry.getValue(); - - if (builder.expectedVertices > 0) { - RenderType type = entry.getKey(); - - hack.flywheel$hackBegin(builder.backingBuffer, type.format(), builder.expectedVertices); - - type.end(scratch, 0, 0, 0); - - builder.expectedVertices = 0; - } - } - } - - private static class DrawBuffer { - - private final RenderType type; - private ByteBuffer backingBuffer; - private int expectedVertices; - - public DrawBuffer(RenderType type) { - this.type = type; - } - - public DirectVertexConsumer begin(int vertexCount) { - this.expectedVertices = vertexCount; - - VertexFormat format = type.format(); - - int byteSize = format.getVertexSize() * vertexCount; - - if (backingBuffer == null) { - backingBuffer = MemoryTracker.create(byteSize); - } if (byteSize > backingBuffer.capacity()) { - backingBuffer = MemoryTracker.resize(backingBuffer, byteSize); - } - - return new DirectVertexConsumer(backingBuffer, format, vertexCount); - } - - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index 890dce0e1..032a03457 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -7,7 +7,8 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.backend.instancing.SuperBufferSource; +import com.jozufozu.flywheel.backend.OptifineHandler; +import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; import com.mojang.blaze3d.vertex.PoseStack; @@ -34,7 +35,7 @@ public class BatchedMaterialGroup implements MaterialGroup { } } - public void render(PoseStack stack, SuperBufferSource source, TaskEngine pool) { + public void render(PoseStack stack, BatchDrawingTracker source, TaskEngine pool) { int vertexCount = 0; for (BatchedMaterial material : materials.values()) { @@ -44,14 +45,14 @@ public class BatchedMaterialGroup implements MaterialGroup { } } - DirectVertexConsumer consumer = source.getBuffer(state, vertexCount); + DirectVertexConsumer consumer = source.getDirectConsumer(state, vertexCount); // avoids rendering garbage, but doesn't fix the issue of some instances not being buffered consumer.memSetZero(); for (BatchedMaterial material : materials.values()) { for (CPUInstancer instancer : material.models.values()) { - instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay(); + instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.usingShaders(); instancer.submitTasks(stack, pool, consumer); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java index caec4b844..b08044d7b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java @@ -6,18 +6,14 @@ import java.util.Map; import com.jozufozu.flywheel.api.MaterialGroup; import com.jozufozu.flywheel.backend.RenderLayer; -import com.jozufozu.flywheel.backend.instancing.SuperBufferSource; -import com.jozufozu.flywheel.backend.instancing.TaskEngine; +import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker; import com.jozufozu.flywheel.backend.instancing.Engine; +import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.event.RenderLayerEvent; import com.mojang.blaze3d.platform.Lighting; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Matrix4f; import net.minecraft.client.Camera; -import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; @@ -25,7 +21,7 @@ import net.minecraft.core.Vec3i; public class BatchingEngine implements Engine { private final Map> layers; - private final SuperBufferSource superBufferSource = new SuperBufferSource(); + private final BatchDrawingTracker batchTracker = new BatchDrawingTracker(); public BatchingEngine() { this.layers = new EnumMap<>(RenderLayer.class); @@ -47,14 +43,11 @@ public class BatchingEngine implements Engine { @Override public void render(TaskEngine taskEngine, RenderLayerEvent event) { - Map groups = layers.get(event.getLayer()); for (BatchedMaterialGroup group : groups.values()) { - group.render(event.stack, superBufferSource, taskEngine); + group.render(event.stack, batchTracker, taskEngine); } - taskEngine.syncPoint(); - // FIXME: this probably breaks some vanilla stuff but it works much better for flywheel Matrix4f mat = new Matrix4f(); mat.setIdentity(); @@ -64,7 +57,8 @@ public class BatchingEngine implements Engine { Lighting.setupLevel(mat); } - superBufferSource.endBatch(); + taskEngine.syncPoint(); + batchTracker.endBatch(); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java similarity index 67% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java rename to src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java index 59e9b71f1..ed4313063 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java @@ -1,9 +1,9 @@ -package com.jozufozu.flywheel.backend.instancing.tile; +package com.jozufozu.flywheel.backend.instancing.blockentity; import com.jozufozu.flywheel.api.Material; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.api.instance.ITickableInstance; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.materials.model.ModelData; @@ -22,46 +22,46 @@ import net.minecraft.world.level.block.state.BlockState; * *

There are a few additional features that overriding classes can opt in to: *
    - *
  • {@link IDynamicInstance}
  • - *
  • {@link ITickableInstance}
  • + *
  • {@link DynamicInstance}
  • + *
  • {@link TickableInstance}
  • *
* See the interfaces' documentation for more information about each one. * - *
Implementing one or more of these will give a {@link TileEntityInstance} access + *
Implementing one or more of these will give a {@link BlockEntityInstance} access * to more interesting and regular points within a tick or a frame. * * @param The type of {@link BlockEntity} your class is an instance of. */ -public abstract class TileEntityInstance extends AbstractInstance { +public abstract class BlockEntityInstance extends AbstractInstance { - protected final T tile; + protected final T blockEntity; protected final BlockPos pos; protected final BlockPos instancePos; protected final BlockState blockState; - public TileEntityInstance(MaterialManager materialManager, T tile) { - super(materialManager, tile.getLevel()); - this.tile = tile; - this.pos = tile.getBlockPos(); - this.blockState = tile.getBlockState(); + public BlockEntityInstance(MaterialManager materialManager, T blockEntity) { + super(materialManager, blockEntity.getLevel()); + this.blockEntity = blockEntity; + this.pos = blockEntity.getBlockPos(); + this.blockState = blockEntity.getBlockState(); this.instancePos = pos.subtract(materialManager.getOriginCoordinate()); } /** - * Just before {@link #update()} would be called, shouldReset() is checked. - * If this function returns true, then this instance will be {@link #remove removed}, + * Just before {@link #update()} would be called, {@code shouldReset()} is checked. + * If this function returns {@code true}, then this instance will be {@link #remove removed}, * and another instance will be constructed to replace it. This allows for more sane resource * acquisition compared to trying to update everything within the lifetime of an instance. * - * @return true if this instance should be discarded and refreshed. + * @return {@code true} if this instance should be discarded and refreshed. */ public boolean shouldReset() { - return tile.getBlockState() != blockState; + return blockEntity.getBlockState() != blockState; } /** * In order to accommodate for floating point precision errors at high coordinates, - * {@link TileInstanceManager}s are allowed to arbitrarily adjust the origin, and + * {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and * shift the world matrix provided as a shader uniform accordingly. * * @return The {@link BlockPos position} of the {@link BlockEntity} this instance diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstanceManager.java similarity index 58% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java rename to src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstanceManager.java index b0be524da..aebc9ee1e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstanceManager.java @@ -1,46 +1,44 @@ -package com.jozufozu.flywheel.backend.instancing.tile; +package com.jozufozu.flywheel.backend.instancing.blockentity; import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.backend.Backend; 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.TaskEngine; import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -public class TileInstanceManager extends InstanceManager { +public class BlockEntityInstanceManager extends InstanceManager { - public TileInstanceManager(MaterialManager materialManager) { + public BlockEntityInstanceManager(MaterialManager materialManager) { super(materialManager); } @Override protected boolean canInstance(BlockEntity obj) { - return obj != null && InstancedRenderRegistry.getInstance().canInstance(obj.getType()); + return obj != null && InstancedRenderRegistry.canInstance(obj.getType()); } @Override protected AbstractInstance createRaw(BlockEntity obj) { - return InstancedRenderRegistry.getInstance() - .create(materialManager, obj); + return InstancedRenderRegistry.createInstance(materialManager, obj); } @Override - protected boolean canCreateInstance(BlockEntity tile) { - if (tile.isRemoved()) return false; + protected boolean canCreateInstance(BlockEntity blockEntity) { + if (blockEntity.isRemoved()) return false; - Level world = tile.getLevel(); + Level world = blockEntity.getLevel(); if (world == null) return false; - if (world.isEmptyBlock(tile.getBlockPos())) return false; + if (world.isEmptyBlock(blockEntity.getBlockPos())) return false; if (Backend.isFlywheelWorld(world)) { - BlockPos pos = tile.getBlockPos(); + BlockPos pos = blockEntity.getBlockPos(); BlockGetter existingChunk = world.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java new file mode 100644 index 000000000..23bf0b318 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstancingController.java @@ -0,0 +1,26 @@ +package com.jozufozu.flywheel.backend.instancing.blockentity; + +import com.jozufozu.flywheel.api.MaterialManager; + +import net.minecraft.world.level.block.entity.BlockEntity; + +/** + * An instancing controller that will be keyed to a block entity type. + * @param The type of block entity this controller is for. + */ +public interface BlockEntityInstancingController { + /** + * Given a block entity and a material manager, constructs an instance for the block entity. + * @param materialManager The material manager to use. + * @param blockEntity The block entity to construct an instance for. + * @return The instance. + */ + BlockEntityInstance createInstance(MaterialManager materialManager, T blockEntity); + + /** + * Checks if the given block entity should not be rendered normally. + * @param blockEntity The block entity to check. + * @return {@code true} if the block entity should not be rendered normally, {@code false} if it should. + */ + boolean shouldSkipRender(T blockEntity); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java new file mode 100644 index 000000000..3ac1bbb7e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityTypeExtension.java @@ -0,0 +1,12 @@ +package com.jozufozu.flywheel.backend.instancing.blockentity; + +import javax.annotation.Nullable; + +import net.minecraft.world.level.block.entity.BlockEntity; + +public interface BlockEntityTypeExtension { + @Nullable + BlockEntityInstancingController flywheel$getInstancingController(); + + void flywheel$setInstancingController(@Nullable BlockEntityInstancingController instancingController); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/SimpleBlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/SimpleBlockEntityInstancingController.java new file mode 100644 index 000000000..6b2cfe0e6 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/SimpleBlockEntityInstancingController.java @@ -0,0 +1,28 @@ +package com.jozufozu.flywheel.backend.instancing.blockentity; + +import java.util.function.BiFunction; +import java.util.function.Predicate; + +import com.jozufozu.flywheel.api.MaterialManager; + +import net.minecraft.world.level.block.entity.BlockEntity; + +public class SimpleBlockEntityInstancingController implements BlockEntityInstancingController { + protected BiFunction> instanceFactory; + protected Predicate skipRender; + + public SimpleBlockEntityInstancingController(BiFunction> instanceFactory, Predicate skipRender) { + this.instanceFactory = instanceFactory; + this.skipRender = skipRender; + } + + @Override + public BlockEntityInstance createInstance(MaterialManager materialManager, T blockEntity) { + return instanceFactory.apply(materialManager, blockEntity); + } + + @Override + public boolean shouldSkipRender(T blockEntity) { + return skipRender.test(blockEntity); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/package-info.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/package-info.java similarity index 73% rename from src/main/java/com/jozufozu/flywheel/backend/instancing/tile/package-info.java rename to src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/package-info.java index d8532a523..ceb2b6de9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/package-info.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/package-info.java @@ -1,5 +1,5 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -package com.jozufozu.flywheel.backend.instancing.tile; +package com.jozufozu.flywheel.backend.instancing.blockentity; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java index e1f6f3830..02e03435c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java @@ -1,14 +1,14 @@ package com.jozufozu.flywheel.backend.instancing.entity; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.api.instance.ITickableInstance; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; -import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; -import com.jozufozu.flywheel.util.box.GridAlignedBB; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import com.jozufozu.flywheel.light.LightListener; import com.jozufozu.flywheel.light.LightProvider; import com.jozufozu.flywheel.light.MovingListener; +import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.mojang.math.Vector3f; import net.minecraft.core.BlockPos; @@ -24,8 +24,8 @@ import net.minecraft.world.phys.Vec3; * * *

There are a few additional features that overriding classes can opt in to: *
    - *
  • {@link IDynamicInstance}
  • - *
  • {@link ITickableInstance}
  • + *
  • {@link DynamicInstance}
  • + *
  • {@link TickableInstance}
  • *
* See the interfaces' documentation for more information about each one. * @@ -65,7 +65,7 @@ public abstract class EntityInstance extends AbstractInstance /** * In order to accommodate for floating point precision errors at high coordinates, - * {@link TileInstanceManager}s are allowed to arbitrarily adjust the origin, and + * {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and * shift the world matrix provided as a shader uniform accordingly. * * @return The position this instance should be rendered at to appear in the correct location. @@ -78,7 +78,7 @@ public abstract class EntityInstance extends AbstractInstance /** * In order to accommodate for floating point precision errors at high coordinates, - * {@link TileInstanceManager}s are allowed to arbitrarily adjust the origin, and + * {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and * shift the world matrix provided as a shader uniform accordingly. * * @return The position this instance should be rendered at to appear in the correct location. diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java index 494800ae2..60ece43f5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java @@ -5,7 +5,6 @@ import com.jozufozu.flywheel.backend.Backend; 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.TaskEngine; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; @@ -20,13 +19,12 @@ public class EntityInstanceManager extends InstanceManager { @Override protected boolean canInstance(Entity obj) { - return obj != null && InstancedRenderRegistry.getInstance().canInstance(obj.getType()); + return obj != null && InstancedRenderRegistry.canInstance(obj.getType()); } @Override protected AbstractInstance createRaw(Entity obj) { - return InstancedRenderRegistry.getInstance() - .create(materialManager, obj); + return InstancedRenderRegistry.createInstance(materialManager, obj); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java new file mode 100644 index 000000000..740800f6b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstancingController.java @@ -0,0 +1,26 @@ +package com.jozufozu.flywheel.backend.instancing.entity; + +import com.jozufozu.flywheel.api.MaterialManager; + +import net.minecraft.world.entity.Entity; + +/** + * An instancing controller that will be keyed to an entity type. + * @param The entity type. + */ +public interface EntityInstancingController { + /** + * Given an entity and a material manager, constructs an instance for the entity. + * @param materialManager The material manager to use. + * @param entity The entity to construct an instance for. + * @return The instance. + */ + EntityInstance createInstance(MaterialManager materialManager, T entity); + + /** + * Checks if the given entity should not render normally. + * @param entity The entity to check. + * @return {@code true} if the entity should not render normally, {@code false} if it should. + */ + boolean shouldSkipRender(T entity); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java new file mode 100644 index 000000000..b01918acd --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityTypeExtension.java @@ -0,0 +1,12 @@ +package com.jozufozu.flywheel.backend.instancing.entity; + +import javax.annotation.Nullable; + +import net.minecraft.world.entity.Entity; + +public interface EntityTypeExtension { + @Nullable + EntityInstancingController flywheel$getInstancingController(); + + void flywheel$setInstancingController(@Nullable EntityInstancingController instancingController); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/IEntityInstanceFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/IEntityInstanceFactory.java deleted file mode 100644 index 04927760a..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/IEntityInstanceFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.entity; - -import com.jozufozu.flywheel.api.MaterialManager; - -import net.minecraft.world.entity.Entity; - -@FunctionalInterface -public interface IEntityInstanceFactory { - EntityInstance create(MaterialManager manager, E te); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/SimpleEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/SimpleEntityInstancingController.java new file mode 100644 index 000000000..d63eac390 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/SimpleEntityInstancingController.java @@ -0,0 +1,28 @@ +package com.jozufozu.flywheel.backend.instancing.entity; + +import java.util.function.BiFunction; +import java.util.function.Predicate; + +import com.jozufozu.flywheel.api.MaterialManager; + +import net.minecraft.world.entity.Entity; + +public class SimpleEntityInstancingController implements EntityInstancingController { + protected BiFunction> instanceFactory; + protected Predicate skipRender; + + public SimpleEntityInstancingController(BiFunction> instanceFactory, Predicate skipRender) { + this.instanceFactory = instanceFactory; + this.skipRender = skipRender; + } + + @Override + public EntityInstance createInstance(MaterialManager materialManager, T entity) { + return instanceFactory.apply(materialManager, entity); + } + + @Override + public boolean shouldSkipRender(T entity) { + return skipRender.test(entity); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index 6d91b3563..5dc89870c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -77,6 +77,10 @@ public class InstancingEngine

implements Engine { */ @Override public void render(TaskEngine taskEngine, RenderLayerEvent event) { + int ebo = GlBufferType.ELEMENT_ARRAY_BUFFER.getBoundBuffer(); + int vbo = GlBufferType.ARRAY_BUFFER.getBoundBuffer(); + int vao = GlVertexArray.getBoundVertexArray(); + double camX; double camY; double camZ; @@ -97,9 +101,9 @@ public class InstancingEngine

implements Engine { getGroupsToRender(event.getLayer()).forEach(group -> group.render(viewProjection, camX, camY, camZ, event.getLayer())); - GlBufferType.ELEMENT_ARRAY_BUFFER.unbind(); - GlBufferType.ARRAY_BUFFER.unbind(); - GlVertexArray.unbind(); + GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo); + GlBufferType.ARRAY_BUFFER.bind(vbo); + GlVertexArray.bind(vao); } private Stream> getGroupsToRender(@Nullable RenderLayer layer) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/ITileInstanceFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/ITileInstanceFactory.java deleted file mode 100644 index c1bdaa74b..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/ITileInstanceFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing.tile; - -import com.jozufozu.flywheel.api.MaterialManager; - -import net.minecraft.world.level.block.entity.BlockEntity; - -@FunctionalInterface -public interface ITileInstanceFactory { - TileEntityInstance create(MaterialManager manager, T te); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java b/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java new file mode 100644 index 000000000..87d840792 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderExtension.java @@ -0,0 +1,27 @@ +package com.jozufozu.flywheel.backend.model; + +import java.nio.ByteBuffer; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.VertexFormat; + +/** + * Duck interface used on {@link BufferBuilder} to provide lower level access to the backing memory. + * + * @see com.jozufozu.flywheel.mixin.BufferBuilderMixin + */ +public interface BufferBuilderExtension { + + /** + * Frees the internal ByteBuffer, if it exists. + */ + void flywheel$freeBuffer(); + + /** + * Prepares the BufferBuilder for drawing the contents of the given buffer. + * @param buffer The buffer to draw. + * @param format The format of the buffer. + * @param vertexCount The number of vertices in the buffer. + */ + void flywheel$injectForRender(ByteBuffer buffer, VertexFormat format, int vertexCount); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderHack.java b/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderHack.java deleted file mode 100644 index 2fc98cf21..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/model/BufferBuilderHack.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.jozufozu.flywheel.backend.model; - -import java.nio.ByteBuffer; - -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.VertexFormat; - -/** - * Duck interface used on {@link BufferBuilder} to provide lower level access to the backing memory. - */ -public interface BufferBuilderHack { - - void flywheel$freeBuffer(); - - void flywheel$hackBegin(ByteBuffer buffer, VertexFormat format, int vertexCount); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/DirectVertexConsumer.java b/src/main/java/com/jozufozu/flywheel/backend/model/DirectVertexConsumer.java index 8446fbfcc..3461e65e1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/DirectVertexConsumer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/DirectVertexConsumer.java @@ -13,7 +13,7 @@ import com.mojang.blaze3d.vertex.VertexFormatElement; /** * An unsafe vertex consumer allowing for unchecked writes into a ByteBuffer. * - * @see BufferBuilderHack + * @see BufferBuilderExtension */ public class DirectVertexConsumer implements VertexConsumer { public final VertexFormat format; diff --git a/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java index 65ba34a3e..5692b5273 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java @@ -228,7 +228,7 @@ public class SourceFile { } /** - * Scan the source for #use "..." directives. + * Scan the source for {@code #use "..."} directives. * Records the contents of the directive into an {@link Import} object, and marks the directive for elision. * @param elisions */ diff --git a/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java b/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java index 78f611990..ae33c75f3 100644 --- a/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java +++ b/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java @@ -3,9 +3,6 @@ package com.jozufozu.flywheel.config; import java.util.function.Consumer; import java.util.function.Supplier; -import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.OptifineHandler; - import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; diff --git a/src/main/java/com/jozufozu/flywheel/core/LastActiveCamera.java b/src/main/java/com/jozufozu/flywheel/core/LastActiveCamera.java new file mode 100644 index 000000000..60e36f463 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/LastActiveCamera.java @@ -0,0 +1,21 @@ +package com.jozufozu.flywheel.core; + +import net.minecraft.client.Camera; + +/** + * A class tracking which object last had {@link Camera#setup} called on it. + * + * @see com.jozufozu.flywheel.mixin.CameraMixin + */ +public class LastActiveCamera { + + private static Camera camera; + + public static void _setActiveCamera(Camera camera) { + LastActiveCamera.camera = camera; + } + + public static Camera getActiveCamera() { + return camera; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java index 30e427f6b..edfcd2c0c 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java @@ -1,11 +1,11 @@ package com.jozufozu.flywheel.core.crumbling; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager; import net.minecraft.core.BlockPos; -public class CrumblingInstanceManager extends TileInstanceManager { +public class CrumblingInstanceManager extends BlockEntityInstanceManager { public CrumblingInstanceManager(MaterialManager materialManager) { super(materialManager); diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java index 056790864..e9aca9ff3 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -6,8 +6,8 @@ import java.util.SortedSet; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlTextureUnit; -import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine; import com.jozufozu.flywheel.backend.instancing.InstanceManager; +import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine; import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine; import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.event.ReloadRenderersEvent; @@ -36,7 +36,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; /** - * Responsible for rendering the block breaking overlay for instanced tiles. + * Responsible for rendering the block breaking overlay for instanced block entities. */ @OnlyIn(Dist.CLIENT) @Mod.EventBusSubscriber(Dist.CLIENT) @@ -57,7 +57,7 @@ public class CrumblingRenderer { public static void renderBreaking(RenderLayerEvent event) { if (!Backend.canUseInstancing(event.getWorld())) return; - Int2ObjectMap> activeStages = getActiveStageTiles(event.getWorld()); + Int2ObjectMap> activeStages = getActiveStageBlockEntities(event.getWorld()); if (activeStages.isEmpty()) return; @@ -90,9 +90,9 @@ public class CrumblingRenderer { } /** - * Associate each breaking stage with a list of all tile entities at that stage. + * Associate each breaking stage with a list of all block entities at that stage. */ - private static Int2ObjectMap> getActiveStageTiles(ClientLevel world) { + private static Int2ObjectMap> getActiveStageBlockEntities(ClientLevel world) { Int2ObjectMap> breakingEntities = new Int2ObjectArrayMap<>(); @@ -105,11 +105,11 @@ public class CrumblingRenderer { int blockDamage = progresses.last() .getProgress(); - BlockEntity tileEntity = world.getBlockEntity(breakingPos); + BlockEntity blockEntity = world.getBlockEntity(breakingPos); - if (tileEntity != null) { - List tileEntities = breakingEntities.computeIfAbsent(blockDamage, $ -> new ArrayList<>()); - tileEntities.add(tileEntity); + if (blockEntity != null) { + List blockEntities = breakingEntities.computeIfAbsent(blockDamage, $ -> new ArrayList<>()); + blockEntities.add(blockEntity); } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java index 77078ffff..67bdeb798 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -2,9 +2,9 @@ package com.jozufozu.flywheel.core.hardcoded; import java.util.List; +import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.model.Model; -import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe; import com.mojang.blaze3d.platform.MemoryTracker; diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java b/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java index 038a7250a..3829a1a84 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java @@ -14,14 +14,14 @@ public interface FlatLit> { /** * @param blockLight An integer in the range [0, 15] representing the * amount of block light this instance should receive. - * @return this + * @return {@code this} */ D setBlockLight(int blockLight); /** * @param skyLight An integer in the range [0, 15] representing the * amount of sky light this instance should receive. - * @return this + * @return {@code this} */ D setSkyLight(int skyLight); diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java index fdd5127b0..67172a308 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java @@ -3,11 +3,11 @@ package com.jozufozu.flywheel.core.materials.model; import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; -import com.jozufozu.flywheel.core.layout.CommonItems; -import com.jozufozu.flywheel.core.layout.MatrixItems; -import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.Programs; +import com.jozufozu.flywheel.core.layout.BufferLayout; +import com.jozufozu.flywheel.core.layout.CommonItems; +import com.jozufozu.flywheel.core.layout.MatrixItems; import com.jozufozu.flywheel.core.model.ModelTransformer; import net.minecraft.resources.ResourceLocation; diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelWriterUnsafe.java index 354751f4e..6f3682040 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelWriterUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelWriterUnsafe.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.core.materials.model; -import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe; import com.jozufozu.flywheel.util.MatrixWrite; diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java index d2f7e57eb..c74056390 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java @@ -3,10 +3,10 @@ package com.jozufozu.flywheel.core.materials.oriented; import com.jozufozu.flywheel.api.struct.Batched; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; -import com.jozufozu.flywheel.core.layout.CommonItems; -import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.Programs; +import com.jozufozu.flywheel.core.layout.BufferLayout; +import com.jozufozu.flywheel.core.layout.CommonItems; import com.jozufozu.flywheel.core.model.ModelTransformer; import com.mojang.math.Quaternion; diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedWriterUnsafe.java index f7db693a3..f7afd8c2b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedWriterUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedWriterUnsafe.java @@ -2,8 +2,8 @@ package com.jozufozu.flywheel.core.materials.oriented; import org.lwjgl.system.MemoryUtil; -import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe; public class OrientedWriterUnsafe extends BasicWriterUnsafe { diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java index b3e96aa7d..c350361c9 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java @@ -16,7 +16,7 @@ public class WorldModel implements Model { private final String name; /** - * It is expected that renderWorld.getShade(...) returns a constant. + * It is expected that {@code renderWorld.getShade(...)} returns a constant. */ public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, String name) { reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks)); diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/ExtensibleGlProgram.java b/src/main/java/com/jozufozu/flywheel/core/shader/ExtensibleGlProgram.java index 72f642020..05ef8dc73 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/ExtensibleGlProgram.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/ExtensibleGlProgram.java @@ -7,13 +7,13 @@ import javax.annotation.Nonnull; import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.jozufozu.flywheel.core.shader.extension.IExtensionInstance; +import com.jozufozu.flywheel.core.shader.extension.ExtensionInstance; import net.minecraft.resources.ResourceLocation; /** * A shader program that be arbitrarily "extended". This class can take in any number of program extensions, and - * will initialize them and then call their {@link IExtensionInstance#bind() bind} function every subsequent time this + * will initialize them and then call their {@link ExtensionInstance#bind() bind} function every subsequent time this * program is bound. An "extension" is something that interacts with the shader program in a way that is invisible to * the caller using the program. This is used by some programs to implement the different fog modes. Other uses might * include binding extra textures to allow for blocks to have normal maps, for example. As the extensions are @@ -22,7 +22,7 @@ import net.minecraft.resources.ResourceLocation; */ public class ExtensibleGlProgram extends GlProgram { - protected final List extensions = new ArrayList<>(); + protected final List extensions = new ArrayList<>(); public ExtensibleGlProgram(ResourceLocation name, int handle) { super(name, handle); @@ -32,7 +32,7 @@ public class ExtensibleGlProgram extends GlProgram { public void bind() { super.bind(); - extensions.forEach(IExtensionInstance::bind); + extensions.forEach(ExtensionInstance::bind); } @Override @@ -42,7 +42,7 @@ public class ExtensibleGlProgram extends GlProgram { .append(name) .append('['); - for (IExtensionInstance extension : extensions) { + for (ExtensionInstance extension : extensions) { builder.append(extension) .append('+'); } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/extension/IExtensionInstance.java b/src/main/java/com/jozufozu/flywheel/core/shader/extension/ExtensionInstance.java similarity index 87% rename from src/main/java/com/jozufozu/flywheel/core/shader/extension/IExtensionInstance.java rename to src/main/java/com/jozufozu/flywheel/core/shader/extension/ExtensionInstance.java index d6c2e0f04..6499820c9 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/extension/IExtensionInstance.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/extension/ExtensionInstance.java @@ -2,7 +2,7 @@ package com.jozufozu.flywheel.core.shader.extension; import net.minecraft.resources.ResourceLocation; -public interface IExtensionInstance { +public interface ExtensionInstance { /** * Bind the extra program state. It is recommended to grab the state information from global variables. diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java b/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java index ac3dcc36e..70d1bff4b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java @@ -5,7 +5,7 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import net.minecraft.resources.ResourceLocation; -public class UnitExtensionInstance implements IExtensionInstance { +public class UnitExtensionInstance implements ExtensionInstance { public static final ResourceLocation NAME = Flywheel.rl("unit"); diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java b/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java index b76c370eb..dd371debd 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java @@ -8,7 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.resources.ResourceLocation; -public class WorldFog implements IExtensionInstance { +public class WorldFog implements ExtensionInstance { public static final ResourceLocation NAME = Flywheel.rl("fog"); diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/IGameStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/GameStateProvider.java similarity index 60% rename from src/main/java/com/jozufozu/flywheel/core/shader/gamestate/IGameStateProvider.java rename to src/main/java/com/jozufozu/flywheel/core/shader/gamestate/GameStateProvider.java index 78fb00d07..152ee113d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/IGameStateProvider.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/GameStateProvider.java @@ -5,9 +5,9 @@ import com.mojang.serialization.Codec; import net.minecraft.resources.ResourceLocation; -public interface IGameStateProvider { +public interface GameStateProvider { - Codec CODEC = ResourceLocation.CODEC.xmap(GameStateRegistry::getStateProvider, IGameStateProvider::getID); + Codec CODEC = ResourceLocation.CODEC.xmap(GameStateRegistry::getStateProvider, GameStateProvider::getID); ResourceLocation getID(); diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/spec/BooleanStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/spec/BooleanStateProvider.java new file mode 100644 index 000000000..1cf0b1da2 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/shader/spec/BooleanStateProvider.java @@ -0,0 +1,13 @@ +package com.jozufozu.flywheel.core.shader.spec; + +import com.jozufozu.flywheel.core.shader.gamestate.GameStateProvider; + +public interface BooleanStateProvider extends GameStateProvider { + + boolean isTrue(); + + @Override + default Boolean getValue() { + return isTrue(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java b/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java index f9e105f98..f79169806 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java @@ -17,11 +17,11 @@ import net.minecraft.resources.ResourceLocation; * An object describing a shader program that can be loaded by flywheel. * *

- * These are defined through json. All ProgramSpecs in assets/modid/flywheel/programs are parsed and + * These are defined through json. All ProgramSpecs in {@code assets/modid/flywheel/programs} are parsed and * processed. One ProgramSpec typically specifies one "material" that can be used in game to render things. *

*

- * All shader source files in assets/modid/flywheel/shaders are completely loaded and parsed into + * All shader source files in {@code assets/modid/flywheel/shaders} are completely loaded and parsed into * {@link SourceFile SourceFiles}, but not compiled until one of them is * referenced by a ProgramSpec. *

diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java index bfd246988..a0687b992 100644 --- a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java @@ -43,7 +43,7 @@ import net.minecraft.world.ticks.LevelTickAccess; public class VirtualRenderWorld extends Level implements FlywheelWorld { public final Map blocksAdded = new HashMap<>(); - public final Map tesAdded = new HashMap<>(); + public final Map besAdded = new HashMap<>(); public final Set spannedSections = new HashSet<>(); private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos(); @@ -85,9 +85,9 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { lighter.runUpdates(Integer.MAX_VALUE, false, false); } - public void setTileEntities(Collection tileEntities) { - tesAdded.clear(); - tileEntities.forEach(te -> tesAdded.put(te.getBlockPos(), te)); + public void setBlockEntities(Collection blockEntities) { + besAdded.clear(); + blockEntities.forEach(be -> besAdded.put(be.getBlockPos(), be)); } public void clear() { @@ -153,7 +153,7 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { @Override @Nullable public BlockEntity getBlockEntity(BlockPos pos) { - return tesAdded.get(pos); + return besAdded.get(pos); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java b/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java index 2db6271ee..db4d6fd1f 100644 --- a/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java +++ b/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java @@ -8,28 +8,28 @@ import net.minecraftforge.eventbus.api.Event; public class BeginFrameEvent extends Event { private final ClientLevel world; - private final Camera info; - private final Frustum clippingHelper; + private final Camera camera; + private final Frustum frustum; - public BeginFrameEvent(ClientLevel world, Camera info, Frustum clippingHelper) { + public BeginFrameEvent(ClientLevel world, Camera camera, Frustum frustum) { this.world = world; - this.info = info; - this.clippingHelper = clippingHelper; + this.camera = camera; + this.frustum = frustum; } public ClientLevel getWorld() { return world; } - public Camera getInfo() { - return info; + public Camera getCamera() { + return camera; } - public Frustum getClippingHelper() { - return clippingHelper; + public Frustum getFrustum() { + return frustum; } public Vec3 getCameraPos() { - return info.getPosition(); + return camera.getPosition(); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java new file mode 100644 index 000000000..ba5b86e18 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java @@ -0,0 +1,29 @@ +package com.jozufozu.flywheel.mixin; + +import javax.annotation.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.backend.instancing.blockentity.BlockEntityTypeExtension; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +@Mixin(BlockEntityType.class) +public class BlockEntityTypeMixin implements BlockEntityTypeExtension { + @Unique + private BlockEntityInstancingController flywheel$instancingController; + + @Override + @Nullable + public BlockEntityInstancingController flywheel$getInstancingController() { + return flywheel$instancingController; + } + + @Override + public void flywheel$setInstancingController(@Nullable BlockEntityInstancingController instancingController) { + this.flywheel$instancingController = instancingController; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java index a105affa3..6b13b9a92 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/BufferBuilderMixin.java @@ -9,15 +9,13 @@ import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import com.jozufozu.flywheel.backend.instancing.SuperBufferSource; -import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; -import com.jozufozu.flywheel.backend.model.BufferBuilderHack; +import com.jozufozu.flywheel.backend.model.BufferBuilderExtension; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormatElement; @Mixin(BufferBuilder.class) -public abstract class BufferBuilderMixin implements BufferBuilderHack { +public abstract class BufferBuilderMixin implements BufferBuilderExtension { @Shadow private ByteBuffer buffer; @@ -52,7 +50,7 @@ public abstract class BufferBuilderMixin implements BufferBuilderHack { } @Override - public void flywheel$hackBegin(@Nonnull ByteBuffer buffer, @Nonnull VertexFormat format, int vertexCount) { + public void flywheel$injectForRender(@Nonnull ByteBuffer buffer, @Nonnull VertexFormat format, int vertexCount) { this.building = true; this.mode = VertexFormat.Mode.QUADS; diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java index 64b81bd2b..f7d609805 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java @@ -21,4 +21,19 @@ public interface BufferUploaderAccessor { static void flywheel$setLastEBO(int id) { throw new AssertionError(); } + + @Accessor("lastIndexBufferObject") + static int flywheel$getLastEBO() { + throw new AssertionError(); + } + + @Accessor("lastVertexBufferObject") + static int flywheel$getLastVBO() { + throw new AssertionError(); + } + + @Accessor("lastVertexArrayObject") + static int flywheel$getLastVAO() { + throw new AssertionError(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/CameraMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/CameraMixin.java new file mode 100644 index 000000000..52e6043ef --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/CameraMixin.java @@ -0,0 +1,21 @@ +package com.jozufozu.flywheel.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.jozufozu.flywheel.core.LastActiveCamera; + +import net.minecraft.client.Camera; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.BlockGetter; + +@Mixin(Camera.class) +public class CameraMixin { + + @Inject(method = "setup", at = @At("TAIL")) + private void setup(BlockGetter level, Entity entity, boolean is3rdPerson, boolean isMirrored, float pt, CallbackInfo ci) { + LastActiveCamera._setActiveCamera((Camera)(Object) this); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java index 0e64a35ed..ed1a41e6e 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/CancelEntityRenderMixin.java @@ -24,11 +24,9 @@ public class CancelEntityRenderMixin { private Iterable filterEntities(ClientLevel world) { Iterable entities = world.entitiesForRendering(); if (Backend.isOn()) { - ArrayList filtered = Lists.newArrayList(entities); - InstancedRenderRegistry r = InstancedRenderRegistry.getInstance(); - filtered.removeIf(r::shouldSkipRender); + filtered.removeIf(InstancedRenderRegistry::shouldSkipRender); return filtered; } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java index 861fa7c06..a4accbe24 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/ChunkRebuildHooksMixin.java @@ -22,14 +22,11 @@ public class ChunkRebuildHooksMixin { @Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true) private void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set set, E be, CallbackInfo ci) { - if (Backend.canUseInstancing(be.getLevel())) { + if (InstancedRenderRegistry.canInstance(be.getType())) + InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be); - InstancedRenderRegistry registry = InstancedRenderRegistry.getInstance(); - if (registry.canInstance(be.getType())) - InstancedRenderDispatcher.getTiles(be.getLevel()).queueAdd(be); - - if (registry.shouldSkipRender(be)) + if (InstancedRenderRegistry.shouldSkipRender(be)) ci.cancel(); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java new file mode 100644 index 000000000..fdd14c9d2 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java @@ -0,0 +1,29 @@ +package com.jozufozu.flywheel.mixin; + +import javax.annotation.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.backend.instancing.entity.EntityTypeExtension; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; + +@Mixin(EntityType.class) +public class EntityTypeMixin implements EntityTypeExtension { + @Unique + private EntityInstancingController flywheel$instancingController; + + @Override + @Nullable + public EntityInstancingController flywheel$getInstancingController() { + return flywheel$instancingController; + } + + @Override + public void flywheel$setInstancingController(@Nullable EntityInstancingController instancingController) { + this.flywheel$instancingController = instancingController; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java new file mode 100644 index 000000000..c0edf6bf0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java @@ -0,0 +1,25 @@ +package com.jozufozu.flywheel.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.jozufozu.flywheel.backend.OptifineHandler; +import com.jozufozu.flywheel.core.LastActiveCamera; +import com.jozufozu.flywheel.event.BeginFrameEvent; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraftforge.common.MinecraftForge; + +@Mixin(Frustum.class) +public class FrustumMixin { + + @Inject(method = "prepare", at = @At("TAIL")) + private void onPrepare(double x, double y, double z, CallbackInfo ci) { + if (OptifineHandler.isShadowPass()) { + MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(Minecraft.getInstance().level, LastActiveCamera.getActiveCamera(), (Frustum) (Object) this)); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java index 53137d485..b28fbfa84 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/InstanceAddMixin.java @@ -26,9 +26,9 @@ public class InstanceAddMixin { @Inject(method = "setBlockEntity", at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")) - private void tileAdded(BlockEntity be, CallbackInfo ci) { + private void blockEntityAdded(BlockEntity be, CallbackInfo ci) { if (level.isClientSide && Backend.isOn()) { - InstancedRenderDispatcher.getTiles(this.level) + InstancedRenderDispatcher.getBlockEntities(this.level) .add(be); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java index 9a6862ddf..0ee0fd088 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/InstanceRemoveMixin.java @@ -25,18 +25,18 @@ public class InstanceRemoveMixin { @Inject(at = @At("TAIL"), method = "setRemoved") private void removeInstance(CallbackInfo ci) { if (level instanceof ClientLevel && Backend.isOn()) { - InstancedRenderDispatcher.getTiles(this.level) + InstancedRenderDispatcher.getBlockEntities(this.level) .remove((BlockEntity) (Object) this); } } // /** // * Don't do this. -// * It can cause infinite loops if an instance class tries to access another tile entity in its constructor. +// * It can cause infinite loops if an instance class tries to access another block entity in its constructor. // */ // @Inject(at = @At("TAIL"), method = "clearRemoved") // private void addInstance(CallbackInfo ci) { -// if (level.isClientSide) InstancedRenderDispatcher.getTiles(this.level) +// if (level.isClientSide) InstancedRenderDispatcher.getBlockEntities(this.level) // .add((BlockEntity) (Object) this); // } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/RenderHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java similarity index 94% rename from src/main/java/com/jozufozu/flywheel/mixin/RenderHooksMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java index 5452c100e..3dbe19701 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/RenderHooksMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java @@ -33,7 +33,7 @@ import net.minecraftforge.common.MinecraftForge; @OnlyIn(Dist.CLIENT) @Mixin(LevelRenderer.class) -public class RenderHooksMixin { +public class LevelRendererMixin { @Shadow private ClientLevel level; @@ -52,7 +52,7 @@ public class RenderHooksMixin { * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects. * This should probably be a forge event. */ - @Inject(at = @At("TAIL"), method = "renderChunkLayer") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ShaderInstance;clear()V"), method = "renderChunkLayer") private void renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ, Matrix4f p_172999_, CallbackInfo ci) { RenderBuffers renderBuffers = this.renderBuffers; @@ -87,7 +87,7 @@ public class RenderHooksMixin { @Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V") private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) { if (Backend.isOn()) { - InstancedRenderDispatcher.getTiles(level) + InstancedRenderDispatcher.getBlockEntities(level) .update(level.getBlockEntity(pos)); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java new file mode 100644 index 000000000..c3a3d7b5d --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java @@ -0,0 +1,24 @@ +package com.jozufozu.flywheel.mixin; + +import javax.annotation.Nonnull; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import com.jozufozu.flywheel.backend.instancing.DrawBuffer; +import com.jozufozu.flywheel.backend.instancing.RenderTypeExtension; + +import net.minecraft.client.renderer.RenderType; + +@Mixin(RenderType.class) +public class RenderTypeMixin implements RenderTypeExtension { + + @Unique + private final DrawBuffer flywheel$drawBuffer = new DrawBuffer((RenderType) (Object) this); + + @Override + @Nonnull + public DrawBuffer flywheel$getDrawBuffer() { + return flywheel$drawBuffer; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index c66e41b63..0da987881 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -1,11 +1,11 @@ package com.jozufozu.flywheel.vanilla; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.core.hardcoded.ModelPart; +import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -14,14 +14,14 @@ import net.minecraft.client.renderer.blockentity.BellRenderer; import net.minecraft.util.Mth; import net.minecraft.world.level.block.entity.BellBlockEntity; -public class BellInstance extends TileEntityInstance implements IDynamicInstance { +public class BellInstance extends BlockEntityInstance implements DynamicInstance { private final OrientedData bell; private float lastRingTime = Float.NaN; - public BellInstance(MaterialManager materialManager, BellBlockEntity tile) { - super(materialManager, tile); + public BellInstance(MaterialManager materialManager, BellBlockEntity blockEntity) { + super(materialManager, blockEntity); bell = createBellInstance() .setPivot(0.5f, 0.75f, 0.5f) @@ -30,15 +30,15 @@ public class BellInstance extends TileEntityInstance implements @Override public void beginFrame() { - float ringTime = (float)tile.ticks + AnimationTickHolder.getPartialTicks(); + float ringTime = (float)blockEntity.ticks + AnimationTickHolder.getPartialTicks(); if (ringTime == lastRingTime) return; lastRingTime = ringTime; - if (tile.shaking) { + if (blockEntity.shaking) { float angle = Mth.sin(ringTime / (float) Math.PI) / (4.0F + ringTime / 3.0F); - Vector3f ringAxis = tile.clickDirection.getCounterClockWise().step(); + Vector3f ringAxis = blockEntity.clickDirection.getCounterClockWise().step(); bell.setRotation(ringAxis.rotation(angle)); } else { @@ -59,7 +59,7 @@ public class BellInstance extends TileEntityInstance implements private OrientedData createBellInstance() { return materialManager.defaultCutout() .material(Materials.ORIENTED) - .model(tile.getType(), BellInstance::createBellModel) + .model(blockEntity.getType(), BellInstance::createBellModel) .createInstance(); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index ab1acdebf..df834d326 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -5,12 +5,12 @@ import java.util.Calendar; import javax.annotation.Nonnull; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.materials.oriented.OrientedData; -import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -28,7 +28,7 @@ import net.minecraft.world.level.block.entity.ChestBlockEntity; import net.minecraft.world.level.block.entity.LidBlockEntity; import net.minecraft.world.level.block.state.properties.ChestType; -public class ChestInstance extends TileEntityInstance implements IDynamicInstance { +public class ChestInstance extends BlockEntityInstance implements DynamicInstance { private final OrientedData body; private final ModelData lid; @@ -41,13 +41,13 @@ public class ChestInstance extends TileE private float lastProgress = Float.NaN; - public ChestInstance(MaterialManager materialManager, T tile) { - super(materialManager, tile); + public ChestInstance(MaterialManager materialManager, T blockEntity) { + super(materialManager, blockEntity); Block block = blockState.getBlock(); chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE; - renderMaterial = Sheets.chooseMaterial(tile, chestType, isChristmas()); + renderMaterial = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()); body = baseInstance() .setPosition(getInstancePosition()); @@ -63,7 +63,7 @@ public class ChestInstance extends TileE DoubleBlockCombiner.NeighborCombineResult wrapper = chestBlock.combine(blockState, world, getWorldPosition(), true); - this.lidProgress = wrapper.apply(ChestBlock.opennessCombiner(tile)); + this.lidProgress = wrapper.apply(ChestBlock.opennessCombiner(blockEntity)); } else { diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index 4fe3116df..c4d06994a 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -1,13 +1,13 @@ package com.jozufozu.flywheel.vanilla; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.api.instance.ITickableInstance; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.model.Model; -import com.jozufozu.flywheel.core.hardcoded.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.transform.MatrixTransformStack; import com.mojang.math.Vector3f; @@ -21,7 +21,7 @@ import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -public class MinecartInstance extends EntityInstance implements IDynamicInstance, ITickableInstance { +public class MinecartInstance extends EntityInstance implements DynamicInstance, TickableInstance { private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index a64e5b0ec..167b2367a 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -1,11 +1,11 @@ package com.jozufozu.flywheel.vanilla; import com.jozufozu.flywheel.api.MaterialManager; -import com.jozufozu.flywheel.api.instance.IDynamicInstance; -import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; +import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.hardcoded.ModelPart; +import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.transform.MatrixTransformStack; import com.mojang.math.Quaternion; @@ -19,7 +19,7 @@ import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.block.ShulkerBoxBlock; import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; -public class ShulkerBoxInstance extends TileEntityInstance implements IDynamicInstance { +public class ShulkerBoxInstance extends BlockEntityInstance implements DynamicInstance { private final TextureAtlasSprite texture; @@ -29,10 +29,10 @@ public class ShulkerBoxInstance extends TileEntityInstance