Search in sources :

Example 1 with ChunkRendererRegion

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;
}
Also used : ChunkRendererRegion(net.minecraft.client.render.chunk.ChunkRendererRegion) MatrixStack(net.minecraft.client.util.math.MatrixStack) BufferBuilder(net.minecraft.client.render.BufferBuilder) RenderLayer(net.minecraft.client.render.RenderLayer) ChunkOcclusionDataBuilder(net.minecraft.client.render.chunk.ChunkOcclusionDataBuilder) BlockState(net.minecraft.block.BlockState) Random(java.util.Random) BlockRenderManager(net.minecraft.client.render.block.BlockRenderManager) EventRenderBlock(org.bleachhack.event.events.EventRenderBlock) EventRenderFluid(org.bleachhack.event.events.EventRenderFluid) BlockPos(net.minecraft.util.math.BlockPos) BlockEntity(net.minecraft.block.entity.BlockEntity) HashSet(java.util.HashSet) FluidState(net.minecraft.fluid.FluidState)

Example 2 with ChunkRendererRegion

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);
    }
}
Also used : ChunkRendererRegion(net.minecraft.client.render.chunk.ChunkRendererRegion) AccessChunkRendererRegion(net.fabricmc.indigo.renderer.accessor.AccessChunkRendererRegion) TerrainRenderContext(net.fabricmc.indigo.renderer.render.TerrainRenderContext) AccessChunkRendererRegion(net.fabricmc.indigo.renderer.accessor.AccessChunkRendererRegion) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 3 with ChunkRendererRegion

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();
}
Also used : ChunkRendererRegion(net.minecraft.client.render.chunk.ChunkRendererRegion) ChunkRebuildHelper(grondag.canvas.chunk.ChunkRebuildHelper) ChunkRenderData(net.minecraft.client.render.chunk.ChunkRenderData) FluidBufferBuilder(grondag.canvas.buffer.packing.FluidBufferBuilder) ChunkRenderDataExt(grondag.canvas.chunk.ChunkRenderDataExt) World(net.minecraft.world.World) TerrainRenderContext(grondag.canvas.apiimpl.rendercontext.TerrainRenderContext) ChunkOcclusionGraphBuilder(net.minecraft.client.render.chunk.ChunkOcclusionGraphBuilder) BlockRenderManager(net.minecraft.client.render.block.BlockRenderManager) BlockPos(net.minecraft.util.math.BlockPos) BlockEntity(net.minecraft.block.entity.BlockEntity) BlockState(net.minecraft.block.BlockState) VertexCollectorList(grondag.canvas.buffer.packing.VertexCollectorList) UploadableChunk(grondag.canvas.chunk.UploadableChunk) FastRenderRegion(grondag.canvas.chunk.FastRenderRegion) BlockRenderLayer(net.minecraft.block.BlockRenderLayer) ChunkRendererRegionExt(grondag.canvas.chunk.ChunkRendererRegionExt) FluidState(net.minecraft.fluid.FluidState) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 4 with ChunkRendererRegion

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);
    }
}
Also used : ChunkRendererRegion(net.minecraft.client.render.chunk.ChunkRendererRegion) TerrainRenderContext(grondag.canvas.apiimpl.rendercontext.TerrainRenderContext) ChunkRendererRegionExt(grondag.canvas.chunk.ChunkRendererRegionExt) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 5 with ChunkRendererRegion

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;
}
Also used : ChunkRendererRegion(net.minecraft.client.render.chunk.ChunkRendererRegion) BufferBuilder(net.minecraft.client.render.BufferBuilder) RenderLayer(net.minecraft.client.render.RenderLayer) ChunkOcclusionDataBuilder(net.minecraft.client.render.chunk.ChunkOcclusionDataBuilder) BlockState(net.minecraft.block.BlockState) ChunkMeshBuilder(me.jellysquid.mods.sodium.client.render.mesh.ChunkMeshBuilder) Vector3f(net.minecraft.client.util.math.Vector3f) BlockRenderManager(net.minecraft.client.render.block.BlockRenderManager) ExtendedChunkData(me.jellysquid.mods.sodium.client.render.pipeline.ExtendedChunkData) Block(net.minecraft.block.Block) BlockPos(net.minecraft.util.math.BlockPos) BlockEntity(net.minecraft.block.entity.BlockEntity) FluidState(net.minecraft.fluid.FluidState) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Aggregations

ChunkRendererRegion (net.minecraft.client.render.chunk.ChunkRendererRegion)6 BlockState (net.minecraft.block.BlockState)4 BlockEntity (net.minecraft.block.entity.BlockEntity)4 BlockRenderManager (net.minecraft.client.render.block.BlockRenderManager)4 FluidState (net.minecraft.fluid.FluidState)4 BlockPos (net.minecraft.util.math.BlockPos)4 BufferBuilder (net.minecraft.client.render.BufferBuilder)3 RenderLayer (net.minecraft.client.render.RenderLayer)3 ChunkOcclusionDataBuilder (net.minecraft.client.render.chunk.ChunkOcclusionDataBuilder)3 Inject (org.spongepowered.asm.mixin.injection.Inject)3 TerrainRenderContext (grondag.canvas.apiimpl.rendercontext.TerrainRenderContext)2 ChunkRendererRegionExt (grondag.canvas.chunk.ChunkRendererRegionExt)2 HashSet (java.util.HashSet)2 Random (java.util.Random)2 MatrixStack (net.minecraft.client.util.math.MatrixStack)2 RenderBlockEvent (com.tangykiwi.kiwiclient.event.RenderBlockEvent)1 RenderFluidEvent (com.tangykiwi.kiwiclient.event.RenderFluidEvent)1 FluidBufferBuilder (grondag.canvas.buffer.packing.FluidBufferBuilder)1 VertexCollectorList (grondag.canvas.buffer.packing.VertexCollectorList)1 ChunkRebuildHelper (grondag.canvas.chunk.ChunkRebuildHelper)1