132 lines
6.3 KiB
Java
132 lines
6.3 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* it.unimi.dsi.fastutil.objects.ObjectArrayList
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.client.renderer.chunk;
|
|
|
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
|
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
|
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
|
import com.mojang.blaze3d.vertex.MeshData;
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
|
import com.mojang.blaze3d.vertex.VertexSorting;
|
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.EnumMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
|
import net.minecraft.client.renderer.SectionBufferBuilderPack;
|
|
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
|
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
|
import net.minecraft.client.renderer.block.model.BlockModelPart;
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
|
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
|
import net.minecraft.client.renderer.chunk.RenderSectionRegion;
|
|
import net.minecraft.client.renderer.chunk.VisGraph;
|
|
import net.minecraft.client.renderer.chunk.VisibilitySet;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.SectionPos;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.level.block.RenderShape;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.material.FluidState;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public class SectionCompiler {
|
|
private final BlockRenderDispatcher blockRenderer;
|
|
private final BlockEntityRenderDispatcher blockEntityRenderer;
|
|
|
|
public SectionCompiler(BlockRenderDispatcher blockRenderer, BlockEntityRenderDispatcher blockEntityRenderer) {
|
|
this.blockRenderer = blockRenderer;
|
|
this.blockEntityRenderer = blockEntityRenderer;
|
|
}
|
|
|
|
public Results compile(SectionPos sectionPos, RenderSectionRegion region, VertexSorting vertexSorting, SectionBufferBuilderPack builders) {
|
|
Results results = new Results();
|
|
BlockPos minPos = sectionPos.origin();
|
|
BlockPos maxPos = minPos.offset(15, 15, 15);
|
|
VisGraph visGraph = new VisGraph();
|
|
PoseStack poseStack = new PoseStack();
|
|
ModelBlockRenderer.enableCaching();
|
|
EnumMap<ChunkSectionLayer, BufferBuilder> startedLayers = new EnumMap<ChunkSectionLayer, BufferBuilder>(ChunkSectionLayer.class);
|
|
RandomSource random = RandomSource.create();
|
|
ObjectArrayList parts = new ObjectArrayList();
|
|
for (BlockPos blockPos : BlockPos.betweenClosed(minPos, maxPos)) {
|
|
BufferBuilder builder;
|
|
ChunkSectionLayer layer;
|
|
FluidState fluidState;
|
|
BlockEntity blockEntity;
|
|
BlockState blockState = region.getBlockState(blockPos);
|
|
if (blockState.isSolidRender()) {
|
|
visGraph.setOpaque(blockPos);
|
|
}
|
|
if (blockState.hasBlockEntity() && (blockEntity = region.getBlockEntity(blockPos)) != null) {
|
|
this.handleBlockEntity(results, blockEntity);
|
|
}
|
|
if (!(fluidState = blockState.getFluidState()).isEmpty()) {
|
|
layer = ItemBlockRenderTypes.getRenderLayer(fluidState);
|
|
builder = this.getOrBeginLayer(startedLayers, builders, layer);
|
|
this.blockRenderer.renderLiquid(blockPos, region, builder, blockState, fluidState);
|
|
}
|
|
if (blockState.getRenderShape() != RenderShape.MODEL) continue;
|
|
layer = ItemBlockRenderTypes.getChunkRenderType(blockState);
|
|
builder = this.getOrBeginLayer(startedLayers, builders, layer);
|
|
random.setSeed(blockState.getSeed(blockPos));
|
|
this.blockRenderer.getBlockModel(blockState).collectParts(random, (List<BlockModelPart>)parts);
|
|
poseStack.pushPose();
|
|
poseStack.translate(SectionPos.sectionRelative(blockPos.getX()), SectionPos.sectionRelative(blockPos.getY()), SectionPos.sectionRelative(blockPos.getZ()));
|
|
this.blockRenderer.renderBatched(blockState, blockPos, region, poseStack, builder, true, (List<BlockModelPart>)parts);
|
|
poseStack.popPose();
|
|
parts.clear();
|
|
}
|
|
for (Map.Entry entry : startedLayers.entrySet()) {
|
|
ChunkSectionLayer layer = (ChunkSectionLayer)((Object)entry.getKey());
|
|
MeshData mesh = ((BufferBuilder)entry.getValue()).build();
|
|
if (mesh == null) continue;
|
|
if (layer == ChunkSectionLayer.TRANSLUCENT) {
|
|
results.transparencyState = mesh.sortQuads(builders.buffer(layer), vertexSorting);
|
|
}
|
|
results.renderedLayers.put(layer, mesh);
|
|
}
|
|
ModelBlockRenderer.clearCache();
|
|
results.visibilitySet = visGraph.resolve();
|
|
return results;
|
|
}
|
|
|
|
private BufferBuilder getOrBeginLayer(Map<ChunkSectionLayer, BufferBuilder> startedLayers, SectionBufferBuilderPack buffers, ChunkSectionLayer renderType) {
|
|
BufferBuilder builder = startedLayers.get((Object)renderType);
|
|
if (builder == null) {
|
|
ByteBufferBuilder buffer = buffers.buffer(renderType);
|
|
builder = new BufferBuilder(buffer, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
|
startedLayers.put(renderType, builder);
|
|
}
|
|
return builder;
|
|
}
|
|
|
|
private <E extends BlockEntity> void handleBlockEntity(Results results, E blockEntity) {
|
|
BlockEntityRenderer renderer = this.blockEntityRenderer.getRenderer(blockEntity);
|
|
if (renderer != null && !renderer.shouldRenderOffScreen()) {
|
|
results.blockEntities.add(blockEntity);
|
|
}
|
|
}
|
|
|
|
public static final class Results {
|
|
public final List<BlockEntity> blockEntities = new ArrayList<BlockEntity>();
|
|
public final Map<ChunkSectionLayer, MeshData> renderedLayers = new EnumMap<ChunkSectionLayer, MeshData>(ChunkSectionLayer.class);
|
|
public VisibilitySet visibilitySet = new VisibilitySet();
|
|
public @Nullable MeshData.SortState transparencyState;
|
|
|
|
public void release() {
|
|
this.renderedLayers.values().forEach(MeshData::close);
|
|
}
|
|
}
|
|
}
|
|
|