Contraption renderer checks for flywheel worlds

- Should fix an issue with smaller units
This commit is contained in:
JozsefA 2021-04-28 22:08:45 -07:00
parent ab6b18e42d
commit 81b0cf77e1

View file

@ -44,7 +44,6 @@ import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraft.world.LightType; import net.minecraft.world.LightType;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template; import net.minecraft.world.gen.feature.template.Template;
@ -52,57 +51,27 @@ import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData; import net.minecraftforge.client.model.data.EmptyModelData;
public class ContraptionRenderDispatcher { public class ContraptionRenderDispatcher {
public static final Int2ObjectMap<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>();
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>(); public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
protected static PlacementSimulationWorld renderWorld; protected static PlacementSimulationWorld renderWorld;
public static void notifyLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) { public static void tick() {
for (RenderedContraption renderer : renderers.values()) { if (Minecraft.getInstance().isGamePaused()) return;
renderer.getLighter().lightVolume.notifyLightPacket(world, chunkX, chunkZ);
}
}
public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, for (RenderedContraption contraption : renderers.values()) {
IRenderTypeBuffer buffer) { contraption.getLighter().tick(contraption);
PlacementSimulationWorld renderWorld = null;
if (Backend.canUseVBOs()) {
RenderedContraption renderer = getRenderer(world, c);
renderWorld = renderer.renderWorld; contraption.kinetics.tick();
} }
TileEntityRenderHelper.renderTileEntities(world, renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer); }
} public static void beginFrame(ActiveRenderInfo info, double camX, double camY, double camZ) {
for (RenderedContraption renderer : renderers.values()) {
renderer.beginFrame(info, camX, camY, camZ);
}
}
public static void tick() { public static void renderLayer(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
if (Minecraft.getInstance().isGamePaused()) return;
for (RenderedContraption contraption : renderers.values()) {
contraption.getLighter().tick(contraption);
contraption.kinetics.tick();
}
}
private static RenderedContraption getRenderer(World world, Contraption c) {
int entityId = c.entity.getEntityId();
RenderedContraption contraption = renderers.get(entityId);
if (contraption == null) {
contraption = new RenderedContraption(world, c);
renderers.put(entityId, contraption);
}
return contraption;
}
public static void beginFrame(ActiveRenderInfo info, double camX, double camY, double camZ) {
for (RenderedContraption renderer : renderers.values()) {
renderer.beginFrame(info, camX, camY, camZ);
}
}
public static void renderLayer(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
removeDeadContraptions(); removeDeadContraptions();
if (renderers.isEmpty()) return; if (renderers.isEmpty()) return;
@ -121,79 +90,110 @@ public class ContraptionRenderDispatcher {
if (Backend.canUseInstancing()) { if (Backend.canUseInstancing()) {
for (RenderedContraption renderer : renderers.values()) { for (RenderedContraption renderer : renderers.values()) {
renderer.kinetics.render(layer, viewProjection, camX, camY, camZ, renderer::setup); renderer.kinetics.render(layer, viewProjection, camX, camY, camZ, renderer::setup);
renderer.teardown(); renderer.teardown();
} }
} }
layer.endDrawing(); layer.endDrawing();
GL11.glDisable(GL13.GL_TEXTURE_3D); GL11.glDisable(GL13.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE0); GL13.glActiveTexture(GL40.GL_TEXTURE0);
} }
public static void removeDeadContraptions() { private static RenderedContraption getRenderer(World world, Contraption c) {
renderers.values().removeIf(renderer -> { int entityId = c.entity.getEntityId();
if (renderer.isDead()) { RenderedContraption contraption = renderers.get(entityId);
renderer.invalidate();
return true;
}
return false;
});
}
public static void invalidateAll() { if (contraption == null) {
for (RenderedContraption renderer : renderers.values()) { contraption = new RenderedContraption(world, c);
renderer.invalidate(); renderers.put(entityId, contraption);
} }
renderers.clear(); return contraption;
} }
public static void render(AbstractContraptionEntity entity, MatrixStack ms, IRenderTypeBuffer buffers, public static void render(AbstractContraptionEntity entity, MatrixStack ms, IRenderTypeBuffer buffers,
MatrixStack msLocal, Contraption contraption) { MatrixStack msLocal, Contraption contraption) {
if (Backend.canUseVBOs()) { if (Backend.canUseVBOs() && Backend.isFlywheelWorld(entity.world)) {
ContraptionRenderDispatcher.renderDynamic(entity.world, contraption, ms, msLocal, buffers); ContraptionRenderDispatcher.renderDynamic(entity.world, contraption, ms, msLocal, buffers);
} else { } else {
ContraptionRenderDispatcher.renderDynamic(entity.world, contraption, ms, msLocal, buffers); ContraptionRenderDispatcher.renderDynamic(entity.world, contraption, ms, msLocal, buffers);
ContraptionRenderDispatcher.renderStructure(entity.world, contraption, ms, msLocal, buffers); ContraptionRenderDispatcher.renderStructure(entity.world, contraption, ms, msLocal, buffers);
} }
} }
public static void renderDynamic(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, public static void renderStructure(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) { IRenderTypeBuffer buffer) {
renderTileEntities(world, c, ms, msLocal, buffer); SuperByteBufferCache bufferCache = CreateClient.bufferCache;
if (buffer instanceof IRenderTypeBuffer.Impl) List<RenderType> blockLayers = RenderType.getBlockLayers();
((IRenderTypeBuffer.Impl) buffer).draw();
renderActors(world, c, ms, msLocal, buffer);
}
public static void renderStructure(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, buffer.getBuffer(RenderType.getSolid());
IRenderTypeBuffer buffer) { for (int i = 0; i < blockLayers.size(); i++) {
SuperByteBufferCache bufferCache = CreateClient.bufferCache; RenderType layer = blockLayers.get(i);
List<RenderType> blockLayers = RenderType.getBlockLayers(); Pair<Contraption, Integer> key = Pair.of(c, i);
SuperByteBuffer contraptionBuffer = bufferCache.get(CONTRAPTION, key, () -> buildStructureBuffer(c, layer));
if (contraptionBuffer.isEmpty())
continue;
Matrix4f model = msLocal.peek()
.getModel();
contraptionBuffer.light(model)
.renderInto(ms, buffer.getBuffer(layer));
}
}
buffer.getBuffer(RenderType.getSolid()); public static void renderDynamic(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
for (int i = 0; i < blockLayers.size(); i++) { IRenderTypeBuffer buffer) {
RenderType layer = blockLayers.get(i); renderTileEntities(world, c, ms, msLocal, buffer);
Pair<Contraption, Integer> key = Pair.of(c, i); if (buffer instanceof IRenderTypeBuffer.Impl)
SuperByteBuffer contraptionBuffer = bufferCache.get(CONTRAPTION, key, () -> buildStructureBuffer(c, layer)); ((IRenderTypeBuffer.Impl) buffer).draw();
if (contraptionBuffer.isEmpty()) renderActors(world, c, ms, msLocal, buffer);
continue; }
Matrix4f model = msLocal.peek()
.getModel();
contraptionBuffer.light(model)
.renderInto(ms, buffer.getBuffer(layer));
}
}
private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) { public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
BufferBuilder builder = buildStructure(c, layer); IRenderTypeBuffer buffer) {
return new SuperByteBuffer(builder); PlacementSimulationWorld renderWorld = null;
} if (Backend.canUseVBOs() && Backend.isFlywheelWorld(world)) {
RenderedContraption renderer = getRenderer(world, c);
public static BufferBuilder buildStructure(Contraption c, RenderType layer) { renderWorld = renderer.renderWorld;
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world) }
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world); TileEntityRenderHelper.renderTileEntities(world, renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer);
}
protected static void renderActors(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) {
MatrixStack[] matrixStacks = new MatrixStack[]{ms, msLocal};
for (Pair<Template.BlockInfo, MovementContext> actor : c.getActors()) {
MovementContext context = actor.getRight();
if (context == null)
continue;
if (context.world == null)
context.world = world;
Template.BlockInfo blockInfo = actor.getLeft();
for (MatrixStack m : matrixStacks) {
m.push();
MatrixStacker.of(m)
.translate(blockInfo.pos);
}
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
if (movementBehaviour != null)
movementBehaviour.renderInContraption(context, ms, msLocal, buffer);
for (MatrixStack m : matrixStacks)
m.pop();
}
}
private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) {
BufferBuilder builder = buildStructure(c, layer);
return new SuperByteBuffer(builder);
}
public static BufferBuilder buildStructure(Contraption c, RenderType layer) {
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
ForgeHooksClient.setRenderLayer(layer); ForgeHooksClient.setRenderLayer(layer);
MatrixStack ms = new MatrixStack(); MatrixStack ms = new MatrixStack();
@ -232,31 +232,6 @@ public class ContraptionRenderDispatcher {
return builder; return builder;
} }
protected static void renderActors(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) {
MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal };
for (Pair<Template.BlockInfo, MovementContext> actor : c.getActors()) {
MovementContext context = actor.getRight();
if (context == null)
continue;
if (context.world == null)
context.world = world;
Template.BlockInfo blockInfo = actor.getLeft();
for (MatrixStack m : matrixStacks) {
m.push();
MatrixStacker.of(m)
.translate(blockInfo.pos);
}
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
if (movementBehaviour != null)
movementBehaviour.renderInContraption(context, ms, msLocal, buffer);
for (MatrixStack m : matrixStacks)
m.pop();
}
}
public static int getLight(World world, float lx, float ly, float lz) { public static int getLight(World world, float lx, float ly, float lz) {
BlockPos.Mutable pos = new BlockPos.Mutable(); BlockPos.Mutable pos = new BlockPos.Mutable();
float sky = 0, block = 0; float sky = 0, block = 0;
@ -292,14 +267,32 @@ public class ContraptionRenderDispatcher {
return packedLight; return packedLight;
} }
public static int getLightOnContraption(MovementContext context) { public static int getLightOnContraption(MovementContext context) {
int entityId = context.contraption.entity.getEntityId(); int entityId = context.contraption.entity.getEntityId();
RenderedContraption renderedContraption = renderers.get(entityId); RenderedContraption renderedContraption = renderers.get(entityId);
if (renderedContraption != null) { if (renderedContraption != null) {
return renderedContraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos); return renderedContraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos);
} else { } else {
return -1; return -1;
} }
} }
public static void invalidateAll() {
for (RenderedContraption renderer : renderers.values()) {
renderer.invalidate();
}
renderers.clear();
}
public static void removeDeadContraptions() {
renderers.values().removeIf(renderer -> {
if (renderer.isDead()) {
renderer.invalidate();
return true;
}
return false;
});
}
} }