use of net.minecraft.client.render.chunk.ChunkRendererRegion in project BleachHack by BleachDrinker420.
the class MixinChunkRebuildTask method newRender.
private Set<BlockEntity> newRender(float cameraX, float cameraY, float cameraZ, ChunkData data, BlockBufferBuilderStorage buffers) {
BlockPos blockPos = field_20839.getOrigin().toImmutable();
BlockPos blockPos2 = blockPos.add(15, 15, 15);
ChunkOcclusionDataBuilder chunkOcclusionDataBuilder = new ChunkOcclusionDataBuilder();
Set<BlockEntity> set = new HashSet<>();
ChunkRendererRegion chunkRendererRegion = this.region;
this.region = null;
MatrixStack matrixStack = new MatrixStack();
if (chunkRendererRegion != null) {
BlockModelRenderer.enableBrightnessCache();
Random random = new Random();
BlockRenderManager blockRenderManager = MinecraftClient.getInstance().getBlockRenderManager();
for (BlockPos blockPos3 : BlockPos.iterate(blockPos, blockPos2)) {
BlockState blockState = chunkRendererRegion.getBlockState(blockPos3);
if (blockState.isOpaqueFullCube(chunkRendererRegion, blockPos3)) {
chunkOcclusionDataBuilder.markClosed(blockPos3);
}
if (blockState.hasBlockEntity()) {
BlockEntity blockEntityx = chunkRendererRegion.getBlockEntity(blockPos3, WorldChunk.CreationType.CHECK);
if (blockEntityx != null) {
this.addBlockEntity(data, set, blockEntityx);
}
}
FluidState fluid = chunkRendererRegion.getFluidState(blockPos3);
if (!fluid.isEmpty()) {
RenderLayer renderLayer = RenderLayers.getFluidLayer(fluid);
BufferBuilder bufferBuilder = buffers.get(renderLayer);
if (data.initializedLayers.add(renderLayer)) {
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL);
}
EventRenderFluid event = new EventRenderFluid(fluid, blockPos3, bufferBuilder);
BleachHack.eventBus.post(event);
if (event.isCancelled())
continue;
if (blockRenderManager.renderFluid(blockPos3, chunkRendererRegion, bufferBuilder, fluid)) {
data.empty = false;
data.nonEmptyLayers.add(renderLayer);
}
}
if (blockState.getRenderType() != BlockRenderType.INVISIBLE) {
RenderLayer renderLayer = RenderLayers.getBlockLayer(blockState);
BufferBuilder bufferBuilder = buffers.get(renderLayer);
if (data.initializedLayers.add(renderLayer)) {
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL);
}
EventRenderBlock.Tesselate event = new EventRenderBlock.Tesselate(blockState, blockPos3, matrixStack, bufferBuilder);
BleachHack.eventBus.post(event);
if (event.isCancelled())
continue;
matrixStack.push();
matrixStack.translate(blockPos3.getX() & 15, blockPos3.getY() & 15, blockPos3.getZ() & 15);
if (blockRenderManager.renderBlock(blockState, blockPos3, chunkRendererRegion, matrixStack, bufferBuilder, true, random)) {
data.empty = false;
data.nonEmptyLayers.add(renderLayer);
}
bufferBuilder.unfixColor();
matrixStack.pop();
}
}
if (data.nonEmptyLayers.contains(RenderLayer.getTranslucent())) {
BufferBuilder bufferBuilder2 = buffers.get(RenderLayer.getTranslucent());
bufferBuilder2.setCameraPosition(cameraX - (float) blockPos.getX(), cameraY - (float) blockPos.getY(), cameraZ - (float) blockPos.getZ());
data.bufferState = bufferBuilder2.popState();
}
Stream<RenderLayer> var10000 = data.initializedLayers.stream();
Objects.requireNonNull(buffers);
var10000.map(buffers::get).forEach(BufferBuilder::end);
BlockModelRenderer.disableBrightnessCache();
}
data.occlusionGraph = chunkOcclusionDataBuilder.build();
return set;
}
use of net.minecraft.client.render.chunk.ChunkRendererRegion in project fabric by FabricMC.
the class MixinChunkRenderTask method chunkDataHook.
/**
* The block view reference is voided when {@link ChunkRenderTask#getAndInvalidateWorldView()} is called during
* chunk rebuild, but we need it and it is harder to make reliable, non-invasive changes there.
* So we capture the block view before the reference is voided and send it to the renderer. <p>
*
* We also store a reference to the renderer in the view to avoid doing thread-local lookups for each block.
*/
@Inject(at = @At("HEAD"), method = "takeRegion")
private void chunkDataHook(CallbackInfoReturnable<ChunkRendererRegion> info) {
final ChunkRendererRegion blockView = region;
if (blockView != null) {
final TerrainRenderContext renderer = TerrainRenderContext.POOL.get();
renderer.setBlockView(blockView);
((AccessChunkRendererRegion) blockView).fabric_setRenderer(renderer);
}
}
use of net.minecraft.client.render.chunk.ChunkRendererRegion in project canvas by vram-guild.
the class MixinChunkRenderer method onRebuildChunk.
@Inject(method = "rebuildChunk", at = @At("HEAD"), cancellable = true, require = 1)
private void onRebuildChunk(final float x, final float y, final float z, final ChunkRenderTask chunkRenderTask, final CallbackInfo ci) {
final TerrainRenderContext renderContext = TerrainRenderContext.POOL.get();
final ChunkRebuildHelper help = renderContext.chunkRebuildHelper;
help.clear();
final ChunkRenderData chunkRenderData = ChunkRenderDataStore.claim();
final ChunkRenderDataExt chunkDataExt = (ChunkRenderDataExt) chunkRenderData;
final BlockPos.Mutable origin = this.origin;
final World world = this.world;
if (world != null) {
chunkRenderTask.getLock().lock();
try {
if (chunkRenderTask.getStage() != ChunkRenderTask.Stage.COMPILING) {
return;
}
chunkRenderTask.setRenderData(chunkRenderData);
} finally {
chunkRenderTask.getLock().unlock();
}
// PERF: avoid allocation
final ChunkOcclusionGraphBuilder visibilityData = new ChunkOcclusionGraphBuilder();
// PERF: avoid allocation
final HashSet<BlockEntity> blockEntities = Sets.newHashSet();
final ChunkRendererRegion vanillaRegion = chunkRenderTask.takeRegion();
if (vanillaRegion != null) {
final FastRenderRegion renderRegion = ((ChunkRendererRegionExt) vanillaRegion).canvas_fastRegion();
++chunkUpdateCount;
help.prepareCollectors(origin.getX(), origin.getY(), origin.getZ());
renderContext.setChunkTask(chunkRenderTask);
/**
* Capture the block layer result flags so our renderer can update them when more
* than one layer is rendered for a single model. This is also where we signal the
* renderer to prepare for a new chunk using the data we've accumulated up to this point.
*/
renderContext.prepare((ChunkRenderer) (Object) this, origin);
// NB: We don't use this and it probably isn't needed but leaving just in case - cost is low
BlockModelRenderer.enableBrightnessCache();
final BlockRenderManager blockRenderManager = MinecraftClient.getInstance().getBlockRenderManager();
final BlockPos.Mutable searchPos = help.searchPos;
final int xMin = origin.getX();
final int yMin = origin.getY();
final int zMin = origin.getZ();
final int xMax = xMin + 16;
final int yMax = yMin + 16;
final int zMax = zMin + 16;
for (int xPos = xMin; xPos < xMax; xPos++) {
for (int yPos = yMin; yPos < yMax; yPos++) {
for (int zPos = zMin; zPos < zMax; zPos++) {
final BlockState blockState = renderRegion.getBlockState(xPos, yPos, zPos);
searchPos.set(xPos, yPos, zPos);
if (blockState.isFullOpaque(renderRegion, searchPos)) {
visibilityData.markClosed(searchPos);
}
if (blockState.getBlock().hasBlockEntity()) {
final BlockEntity blockEntity = renderRegion.getBlockEntity(searchPos, WorldChunk.CreationType.CHECK);
if (blockEntity != null) {
final BlockEntityRenderer<BlockEntity> blockEntityRenderer = BlockEntityRenderDispatcher.INSTANCE.get(blockEntity);
if (blockEntityRenderer != null) {
// Fixes MC-112730 - no reason to render both globally and in chunk
if (blockEntityRenderer.method_3563(blockEntity)) {
// global renderer - like beacons
blockEntities.add(blockEntity);
} else {
// chunk-local renderer
chunkRenderData.addBlockEntity(blockEntity);
}
}
}
}
BlockRenderLayer renderLayer;
// UGLY: we are relying on knowledge that fluid state is directly derived from block state, which
// may not be true in future versions and may break. However, is significantly faster to re-use block
// state here vs. retrieving it again.
final FluidState fluidState = blockState.getFluidState();
if (!fluidState.isEmpty()) {
renderLayer = fluidState.getRenderLayer();
// TODO: apply appropriate shader props for fluids
final FluidBufferBuilder fluidBuilder = help.fluidBuilder.prepare(help.getCollector(renderLayer).get(Canvas.MATERIAL_STANDARD, ShaderProps.waterProps()), searchPos, renderLayer);
blockRenderManager.tesselateFluid(searchPos, renderRegion, fluidBuilder, fluidState);
}
if (blockState.getRenderType() == BlockRenderType.MODEL) {
renderContext.tesselateBlock(blockState, searchPos);
}
}
}
}
if (!help.solidCollector.isEmpty()) {
chunkRenderData.markBufferInitialized(BlockRenderLayer.SOLID);
chunkDataExt.canvas_setNonEmpty(BlockRenderLayer.SOLID);
final UploadableChunk.Solid abandoned = uploadSolid.getAndSet(help.solidCollector.packUploadSolid());
if (abandoned != null) {
abandoned.cancel();
}
}
if (!help.translucentCollector.isEmpty()) {
final VertexCollectorList vcl = help.translucentCollector;
chunkRenderData.markBufferInitialized(BlockRenderLayer.TRANSLUCENT);
chunkDataExt.canvas_setNonEmpty(BlockRenderLayer.TRANSLUCENT);
vcl.setViewCoordinates(x, y, z);
chunkDataExt.canvas_collectorState(vcl.getCollectorState(null));
final UploadableChunk.Translucent abandoned = uploadTranslucent.getAndSet(vcl.packUploadTranslucent());
if (abandoned != null) {
abandoned.cancel();
}
}
/**
* Release all references. Probably not necessary but would be $#%! to debug if it is.
*/
renderContext.release();
BlockModelRenderer.disableBrightnessCache();
}
chunkRenderData.setOcclusionGraph(visibilityData.build());
lock.lock();
try {
help.tileEntitiesToAdd.addAll(blockEntities);
help.tileEntitiesToRemove.addAll(this.blockEntities);
help.tileEntitiesToAdd.removeAll(this.blockEntities);
help.tileEntitiesToRemove.removeAll(blockEntities);
this.blockEntities.clear();
this.blockEntities.addAll(blockEntities);
renderer.updateBlockEntities(help.tileEntitiesToRemove, help.tileEntitiesToAdd);
} finally {
lock.unlock();
}
}
ci.cancel();
}
use of net.minecraft.client.render.chunk.ChunkRendererRegion in project canvas by vram-guild.
the class MixinChunkRenderTask method onTakeRegion.
/**
* The block view reference is voided when
* {@link ChunkRenderTask#takeRegion()} is called during chunk
* rebuild, but we need it and it is harder to make reliable, non-invasive
* changes there. So we capture the block view before the reference is voided
* and send it to the renderer.
* <p>
*
* We also store a reference to the renderer in the view to avoid doing
* thread-local lookups for each block.
*/
@Inject(at = @At("HEAD"), method = "takeRegion")
private void onTakeRegion(CallbackInfoReturnable<ChunkRendererRegion> info) {
final ChunkRendererRegion blockView = region;
if (blockView != null) {
final TerrainRenderContext renderer = TerrainRenderContext.POOL.get();
final ChunkRendererRegionExt regionExt = (ChunkRendererRegionExt) region;
renderer.setBlockView(regionExt.canvas_fastRegion());
regionExt.canvas_renderer(renderer);
}
}
use of net.minecraft.client.render.chunk.ChunkRendererRegion in project sodium-fabric by CaffeineMC.
the class MixinRebuildTask method render.
/**
* @author JellySquid
*/
@Overwrite
private Set<BlockEntity> render(float cameraX, float cameraY, float cameraZ, ChunkBuilder.ChunkData data, BlockBufferBuilderStorage buffers) {
ExtendedChunkData edata = (ExtendedChunkData) data;
BlockPos from = this.parent.getOrigin().toImmutable();
BlockPos to = from.add(15, 15, 15);
ChunkOcclusionDataBuilder occlusion = new ChunkOcclusionDataBuilder();
Set<BlockEntity> set = Sets.newHashSet();
ChunkRendererRegion world = this.region;
Vector3f translation = new Vector3f();
if (world != null) {
BlockRenderManager blockRenderManager = MinecraftClient.getInstance().getBlockRenderManager();
int minX = from.getX();
int minY = from.getY();
int minZ = from.getZ();
int maxX = to.getX();
int maxY = to.getY();
int maxZ = to.getZ();
BlockPos.Mutable pos = new BlockPos.Mutable();
for (int z = minZ; z <= maxZ; z++) {
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
pos.set(x, y, z);
BlockState blockState = world.getBlockState(pos);
FluidState fluidState = blockState.getFluidState();
Block block = blockState.getBlock();
if (blockState.isFullOpaque(world, pos)) {
occlusion.markClosed(pos);
}
if (block.hasBlockEntity()) {
BlockEntity entity = world.getBlockEntity(pos, WorldChunk.CreationType.CHECK);
if (entity != null) {
this.addBlockEntity(data, set, entity);
}
}
if (!fluidState.isEmpty()) {
RenderLayer layer = RenderLayers.getFluidLayer(fluidState);
BufferBuilder builder = buffers.get(layer);
if (!builder.isBuilding()) {
builder.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL);
edata.getInitializedLayers().add(layer);
}
blockRenderManager.renderFluid(pos, world, builder, fluidState);
}
if (blockState.getRenderType() != BlockRenderType.INVISIBLE) {
RenderLayer layer = RenderLayers.getBlockLayer(blockState);
BufferBuilder builder = buffers.get(layer);
if (!builder.isBuilding()) {
builder.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL);
edata.getInitializedLayers().add(layer);
}
translation.set(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15);
this.pipeline.renderBlock(blockState, pos, world, translation, builder, true);
}
}
}
}
for (RenderLayer layer : edata.getInitializedLayers()) {
BufferBuilder builder = buffers.get(layer);
if (layer == RenderLayer.getTranslucent()) {
builder.sortQuads(cameraX - (float) from.getX(), cameraY - (float) from.getY(), cameraZ - (float) from.getZ());
edata.setTranslucentBufferState(builder.popState());
}
builder.end();
if (((ChunkMeshBuilder) builder).isEmpty()) {
continue;
}
edata.getNonEmptyLayers().add(layer);
}
if (edata.getNonEmptyLayers().size() > 0) {
edata.markNonEmpty();
}
}
edata.setOcclusionData(occlusion.build());
this.region = null;
this.pipeline = null;
return set;
}
Aggregations