mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 06:24:12 +01:00
kinda separate system capability stuff, should probably clean this up more.
fix lighting glitches on world load.
This commit is contained in:
parent
d824304f12
commit
a5f3d799d1
@ -1,6 +1,7 @@
|
||||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
@ -56,11 +57,12 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
|
||||
transform(entity, partialTicks, matrixStacks);
|
||||
Contraption contraption = entity.getContraption();
|
||||
if (contraption != null) {
|
||||
if (!FastRenderDispatcher.available()) {
|
||||
ContraptionRenderer.render(entity.world, contraption, ms, msLocal, buffers);
|
||||
} else {
|
||||
if (Backend.canUseVBOs()) {
|
||||
ContraptionRenderer.renderDynamic(entity.world, contraption, ms, msLocal, buffers);
|
||||
}
|
||||
else {
|
||||
ContraptionRenderer.render(entity.world, contraption, ms, msLocal, buffers);
|
||||
}
|
||||
}
|
||||
ms.pop();
|
||||
|
||||
|
@ -5,6 +5,7 @@ import java.util.Random;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.*;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@ -75,7 +76,7 @@ public class ContraptionRenderer {
|
||||
|
||||
protected static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
if (FastRenderDispatcher.available()) {
|
||||
if (Backend.canUseVBOs()) {
|
||||
ContraptionRenderDispatcher.renderTileEntities(world, c, ms, msLocal, buffer);
|
||||
} else {
|
||||
TileEntityRenderHelper.renderTileEntities(world, c.maybeInstancedTileEntities, ms, msLocal, buffer);
|
||||
|
@ -34,10 +34,6 @@ import java.util.Map;
|
||||
public class ContraptionRenderDispatcher {
|
||||
public static final HashMap<Integer, RenderedContraption> renderers = new HashMap<>();
|
||||
|
||||
public static void markForRendering(Contraption c, MatrixStack model) {
|
||||
getRenderer(c.entity.world, c).setRenderSettings(model.peek().getModel());
|
||||
}
|
||||
|
||||
public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) {
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
renderer.getLighter().lightVolume.notifyLightUpdate(world, type, pos);
|
||||
@ -73,7 +69,8 @@ public class ContraptionRenderDispatcher {
|
||||
private static <C extends AbstractContraptionEntity> void updateTransform(C c, AbstractContraptionEntityRenderer<C> entityRenderer) {
|
||||
MatrixStack stack = entityRenderer.makeTransformMatrix(c, AnimationTickHolder.getPartialTicks());
|
||||
|
||||
markForRendering(c.getContraption(), stack);
|
||||
Contraption c1 = c.getContraption();
|
||||
getRenderer(c1.entity.world, c1).setRenderSettings(stack.peek().getModel());
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
@ -104,16 +101,20 @@ public class ContraptionRenderDispatcher {
|
||||
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
||||
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
|
||||
|
||||
if (Backend.canUseVBOs()) {
|
||||
ContraptionProgram structureShader = Backend.getProgram(AllProgramSpecs.CONTRAPTION_STRUCTURE);
|
||||
structureShader.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode());
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
renderer.doRenderLayer(layer, structureShader);
|
||||
}
|
||||
}
|
||||
|
||||
if (Backend.canUseInstancing()) {
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
renderer.kinetics.render(layer, viewProjection, camX, camY, camZ, renderer::setup);
|
||||
renderer.teardown();
|
||||
}
|
||||
}
|
||||
|
||||
layer.endDrawing();
|
||||
GL11.glDisable(GL13.GL_TEXTURE_3D);
|
||||
|
@ -6,6 +6,7 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
||||
@ -52,9 +53,11 @@ public class RenderedContraption {
|
||||
this.renderWorld = setupRenderWorld(world, contraption);
|
||||
|
||||
buildLayers();
|
||||
if (Backend.canUseInstancing()) {
|
||||
buildInstancedTiles();
|
||||
buildActors();
|
||||
}
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return contraption.entity.getEntityId();
|
||||
|
@ -84,8 +84,9 @@ public class ConfigureConfigPacket extends SimplePacketBase {
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void experimentalRendering(String value) {
|
||||
boolean last = AllConfigs.CLIENT.experimentalRendering.get();
|
||||
if (!"".equals(value)) {
|
||||
AllConfigs.CLIENT.experimentalRendering.set(Boolean.parseBoolean(value));
|
||||
}
|
||||
FastRenderDispatcher.refresh();
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ public class CClient extends ConfigBase {
|
||||
public ConfigBool rainbowDebug =
|
||||
b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open.");
|
||||
|
||||
public ConfigRender experimentalRendering =
|
||||
new ConfigRender("experimentalRendering", true, "Use modern OpenGL features to drastically increase performance.");
|
||||
public ConfigBool experimentalRendering =
|
||||
b(true, "experimentalRendering", "Use modern OpenGL features to drastically increase performance.");
|
||||
|
||||
public ConfigInt overlayOffsetX = i(20, Integer.MIN_VALUE, Integer.MAX_VALUE, "overlayOffsetX", "Offset the overlay from goggle- and hover- information by this many pixels on the X axis; Use /create overlay");
|
||||
public ConfigInt overlayOffsetY = i(0, Integer.MIN_VALUE, Integer.MAX_VALUE, "overlayOffsetY", "Offset the overlay from goggle- and hover- information by this many pixels on the Y axis; Use /create overlay");
|
||||
@ -25,27 +25,4 @@ public class CClient extends ConfigBase {
|
||||
public String getName() {
|
||||
return "client";
|
||||
}
|
||||
|
||||
public class ConfigRender extends ConfigBool {
|
||||
|
||||
public ConfigRender(String name, boolean def, String... comment) {
|
||||
super(name, def, comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured value and checks if the rendering is actually supported.
|
||||
* @return True if fast rendering is enabled and the current system/configuration is capable.
|
||||
*/
|
||||
@Override
|
||||
public Boolean get() {
|
||||
return super.get() && Backend.canUse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Boolean value) {
|
||||
super.set(value);
|
||||
Backend.enabled = get();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.light.ILightListener;
|
||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||
import net.minecraft.util.math.SectionPos;
|
||||
import net.minecraft.world.ILightReader;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.chunk.AbstractChunkProvider;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@ -12,6 +15,8 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Mixin(ClientChunkProvider.class)
|
||||
public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
||||
@ -24,6 +29,23 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
||||
*/
|
||||
@Inject(at = @At("HEAD"), method = "markLightChanged")
|
||||
private void onLightUpdate(LightType type, SectionPos pos, CallbackInfo ci) {
|
||||
FastRenderDispatcher.notifyLightUpdate(((ClientChunkProvider) (Object) this), type, pos);
|
||||
ClientChunkProvider thi = ((ClientChunkProvider) (Object) this);
|
||||
|
||||
Chunk chunk = thi.getChunk(pos.getSectionX(), pos.getSectionZ(), false);
|
||||
|
||||
int sectionY = pos.getSectionY();
|
||||
|
||||
if (chunk != null) {
|
||||
chunk.getTileEntityMap()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> SectionPos.toChunk(entry.getKey().getY()) == sectionY)
|
||||
.map(Map.Entry::getValue)
|
||||
.filter(tile -> tile instanceof ILightListener)
|
||||
.map(tile -> (ILightListener) tile)
|
||||
.forEach(ILightListener::onChunkLightUpdate);
|
||||
}
|
||||
|
||||
ContraptionRenderDispatcher.notifyLightUpdate((ILightReader) thi.getWorld(), type, pos);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.OptifineHandler;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@ -21,7 +26,21 @@ public class RenderInLayerMixin {
|
||||
* This should probably be a forge event.
|
||||
*/
|
||||
@Inject(at = @At(value = "TAIL"), method = "renderLayer")
|
||||
private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
|
||||
FastRenderDispatcher.renderLayer(type, stack, (float) cameraX, (float) cameraY, (float) cameraZ);
|
||||
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
||||
if (!Backend.available()) return;
|
||||
|
||||
float cameraX = (float) camX;
|
||||
float cameraY = (float) camY;
|
||||
float cameraZ = (float) camZ;
|
||||
|
||||
Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ);
|
||||
viewProjection.multiplyBackward(stack.peek().getModel());
|
||||
viewProjection.multiplyBackward(FastRenderDispatcher.getProjectionMatrix());
|
||||
|
||||
FastRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ);
|
||||
|
||||
ContraptionRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ);
|
||||
|
||||
GL20.glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
||||
import net.minecraftforge.resource.VanillaResourceType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.opengl.ARBVertexProgram;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
@ -42,10 +41,9 @@ public class Backend {
|
||||
private static final Map<ResourceLocation, ProgramSpec<?>> registry = new HashMap<>();
|
||||
private static final Map<ProgramSpec<?>, GlProgram> programs = new HashMap<>();
|
||||
|
||||
public static boolean enabled;
|
||||
private static boolean enabled;
|
||||
|
||||
public static GLCapabilities capabilities;
|
||||
private static SystemCapability capability;
|
||||
private static MapBuffer mapBuffer;
|
||||
|
||||
public Backend() {
|
||||
@ -102,16 +100,24 @@ public class Backend {
|
||||
return Arrays.stream(constants).filter(it -> it.supported(caps)).findFirst().orElse(last);
|
||||
}
|
||||
|
||||
public static boolean canUse() {
|
||||
return isCapable() && !OptifineHandler.usingShaders();
|
||||
public static boolean canUseInstancing() {
|
||||
return enabled && gl33();
|
||||
}
|
||||
|
||||
public static SystemCapability getCapability() {
|
||||
return capability;
|
||||
public static boolean canUseVBOs() {
|
||||
return enabled && gl20();
|
||||
}
|
||||
|
||||
public static boolean isCapable() {
|
||||
return capability.isCapable();
|
||||
public static boolean available() {
|
||||
return enabled && gl20();
|
||||
}
|
||||
|
||||
public static boolean gl33() {
|
||||
return capabilities.OpenGL33;
|
||||
}
|
||||
|
||||
public static boolean gl20() {
|
||||
return capabilities.OpenGL20;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
@ -132,9 +138,10 @@ public class Backend {
|
||||
capabilities = GL.createCapabilities();
|
||||
mapBuffer = getLatest(MapBuffer.class);
|
||||
|
||||
OptifineHandler.refresh();
|
||||
refresh();
|
||||
|
||||
if (isCapable()) {
|
||||
if (gl20()) {
|
||||
|
||||
programs.values().forEach(GlProgram::delete);
|
||||
programs.clear();
|
||||
@ -146,13 +153,7 @@ public class Backend {
|
||||
}
|
||||
|
||||
public static void refresh() {
|
||||
if (capabilities.OpenGL33) {
|
||||
capability = SystemCapability.CAPABLE;
|
||||
} else {
|
||||
capability = SystemCapability.INCAPABLE;
|
||||
}
|
||||
|
||||
enabled = AllConfigs.CLIENT.experimentalRendering.get();
|
||||
enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders();
|
||||
}
|
||||
|
||||
private static <P extends GlProgram, S extends ProgramSpec<P>> void loadProgram(IResourceManager manager, S programSpec) {
|
||||
|
@ -30,6 +30,7 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.system.CallbackI;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
@ -40,7 +41,7 @@ import java.util.function.Consumer;
|
||||
public class FastRenderDispatcher {
|
||||
|
||||
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
||||
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
||||
public static WorldAttached<ConcurrentHashMap<TileEntity, Integer>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::new);
|
||||
|
||||
private static Matrix4f projectionMatrixThisFrame = null;
|
||||
|
||||
@ -55,18 +56,36 @@ public class FastRenderDispatcher {
|
||||
public static void tick() {
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
|
||||
runQueue(addedLastTick.get(world), CreateClient.kineticRenderer::onLightUpdate);
|
||||
// Clean up twice a second. This doesn't have to happen every tick,
|
||||
// but this does need to be run to ensure we don't miss anything.
|
||||
int ticks = AnimationTickHolder.getTicks();
|
||||
|
||||
ConcurrentHashMap<TileEntity, Integer> map = addedLastTick.get(world);
|
||||
map
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(it -> ticks - it.getValue() > 10)
|
||||
.map(Map.Entry::getKey)
|
||||
.forEach(te -> {
|
||||
map.remove(te);
|
||||
|
||||
CreateClient.kineticRenderer.onLightUpdate(te);
|
||||
});
|
||||
|
||||
|
||||
if (ticks % 10 == 0) {
|
||||
CreateClient.kineticRenderer.clean();
|
||||
}
|
||||
|
||||
runQueue(queuedUpdates.get(world), CreateClient.kineticRenderer::update);
|
||||
}
|
||||
|
||||
public static boolean available() {
|
||||
return Backend.enabled;
|
||||
return Backend.canUseInstancing();
|
||||
}
|
||||
|
||||
public static boolean available(World world) {
|
||||
return Backend.enabled && !(world instanceof SchematicWorld);
|
||||
return Backend.canUseInstancing() && !(world instanceof SchematicWorld);
|
||||
}
|
||||
|
||||
public static int getDebugMode() {
|
||||
@ -77,6 +96,7 @@ public class FastRenderDispatcher {
|
||||
RenderWork.enqueue(() -> {
|
||||
CreateClient.kineticRenderer.invalidate();
|
||||
OptifineHandler.refresh();
|
||||
Backend.refresh();
|
||||
Minecraft.getInstance().worldRenderer.loadRenderers();
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
if (world != null) world.loadedTileEntityList.forEach(CreateClient.kineticRenderer::add);
|
||||
@ -97,12 +117,8 @@ public class FastRenderDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderLayer(RenderType layer, MatrixStack stack, float cameraX, float cameraY, float cameraZ) {
|
||||
if (!available()) return;
|
||||
|
||||
Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ);
|
||||
viewProjection.multiplyBackward(stack.peek().getModel());
|
||||
viewProjection.multiplyBackward(getProjectionMatrix());
|
||||
public static void renderLayer(RenderType layer, Matrix4f viewProjection, float cameraX, float cameraY, float cameraZ) {
|
||||
if (!Backend.canUseInstancing()) return;
|
||||
|
||||
layer.startDrawing();
|
||||
|
||||
@ -113,31 +129,9 @@ public class FastRenderDispatcher {
|
||||
RenderSystem.disableCull();
|
||||
//RenderSystem.disableDepthTest();
|
||||
|
||||
ContraptionRenderDispatcher.renderLayer(layer, viewProjection, cameraX, cameraY, cameraZ);
|
||||
if (!OptifineHandler.usingShaders())
|
||||
GL20.glUseProgram(0);
|
||||
layer.endDrawing();
|
||||
}
|
||||
|
||||
public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) {
|
||||
ContraptionRenderDispatcher.notifyLightUpdate((ILightReader) world.getWorld(), type, pos);
|
||||
|
||||
Chunk chunk = world.getChunk(pos.getSectionX(), pos.getSectionZ(), false);
|
||||
|
||||
int sectionY = pos.getSectionY();
|
||||
|
||||
if (chunk != null) {
|
||||
chunk.getTileEntityMap()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> SectionPos.toChunk(entry.getKey().getY()) == sectionY)
|
||||
.map(Map.Entry::getValue)
|
||||
.filter(tile -> tile instanceof ILightListener)
|
||||
.map(tile -> (ILightListener) tile)
|
||||
.forEach(ILightListener::onChunkLightUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
// copied from GameRenderer.renderWorld
|
||||
public static Matrix4f getProjectionMatrix() {
|
||||
if (projectionMatrixThisFrame != null) return projectionMatrixThisFrame;
|
||||
|
@ -1,19 +0,0 @@
|
||||
package com.simibubi.create.foundation.render.backend;
|
||||
|
||||
public enum SystemCapability {
|
||||
/**
|
||||
* The current system does not support enough
|
||||
* OpenGL features to enable fast rendering.
|
||||
*/
|
||||
INCAPABLE,
|
||||
|
||||
/**
|
||||
* The current system supports OpenGL 3.3.
|
||||
*/
|
||||
CAPABLE,
|
||||
;
|
||||
|
||||
public boolean isCapable() {
|
||||
return this == CAPABLE;
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) {
|
||||
if (!Backend.enabled) return null;
|
||||
if (!Backend.canUseInstancing()) return null;
|
||||
|
||||
TileEntityInstance<?> instance = instances.get(tile);
|
||||
|
||||
@ -47,7 +47,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
||||
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
|
||||
|
||||
if (renderer != null) {
|
||||
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).add(tile);
|
||||
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).put(tile, AnimationTickHolder.getTicks());
|
||||
instances.put(tile, renderer);
|
||||
}
|
||||
|
||||
@ -93,12 +93,8 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
// Clean up twice a second. This doesn't have to happen every tick,
|
||||
// but this does need to be run to ensure we don't miss anything.
|
||||
if (AnimationTickHolder.getTicks() % 10 == 0) {
|
||||
instances.keySet().stream().filter(TileEntity::isRemoved).forEach(instances::remove);
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
for (RenderMaterial<?, ?> material : materials.values()) {
|
||||
|
Loading…
Reference in New Issue
Block a user