Search in sources :

Example 1 with FastRenderRegion

use of grondag.canvas.chunk.FastRenderRegion 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 2 with FastRenderRegion

use of grondag.canvas.chunk.FastRenderRegion in project canvas by vram-guild.

the class LightSmoother method computeSmoothedBrightness.

public static void computeSmoothedBrightness(BlockPos chunkOrigin, BlockRenderView blockViewIn, Long2IntOpenHashMap output) {
    final Helper help = helpers.get();
    final BlockPos.Mutable smoothPos = help.smoothPos;
    final int[] sky = help.a;
    final int[] block = help.b;
    final int minX = chunkOrigin.getX() - MARGIN;
    final int minY = chunkOrigin.getY() - MARGIN;
    final int minZ = chunkOrigin.getZ() - MARGIN;
    final FastRenderRegion view = (FastRenderRegion) blockViewIn;
    for (int x = 0; x < POS_DIAMETER; x++) {
        for (int y = 0; y < POS_DIAMETER; y++) {
            for (int z = 0; z < POS_DIAMETER; z++) {
                final int bx = x + minX;
                final int by = y + minY;
                final int bz = z + minZ;
                smoothPos.set(bx, by, bz);
                final BlockState state = view.getBlockState(bx, by, bz);
                // PERF: consider packed pos
                // don't use cache here because we are populating the cache
                final int packedLight = view.directBrightness(smoothPos);
                // PERF: use cache
                final boolean opaque = state.isFullOpaque(view, smoothPos);
                // //                    subtractedCache.put(packedPos, (short) subtracted);
                final int i = index(x, y, z);
                if (opaque) {
                    block[i] = OPAQUE;
                    sky[i] = OPAQUE;
                } else if (packedLight == 0) {
                    block[i] = 0;
                    sky[i] = 0;
                } else {
                    block[i] = (packedLight & 0xFF);
                    sky[i] = ((packedLight >>> 16) & 0xFF);
                }
            }
        }
    }
    final int[] work = help.c;
    smooth(BLUR_RADIUS + 1, block, work);
    smooth(BLUR_RADIUS, work, block);
    // smooth(1, block, work);
    // float[] swap = block;
    // block = work;
    // work = swap;
    smooth(BLUR_RADIUS + 1, sky, work);
    smooth(BLUR_RADIUS, work, sky);
    // smooth(1, sky, work);
    // swap = sky;
    // sky = work;
    // work = swap;
    final int limit = 16 + MARGIN + 1;
    for (int x = MARGIN - 2; x < limit; x++) {
        for (int y = MARGIN - 2; y < limit; y++) {
            for (int z = MARGIN - 2; z < limit; z++) {
                final long packedPos = PackedBlockPos.pack(x + minX, y + minY, z + minZ);
                final int i = index(x, y, z);
                final int b = MathHelper.clamp(((block[i]) * 104 + 51) / 100, 0, 240);
                final int k = MathHelper.clamp(((sky[i]) * 104 + 51) / 100, 0, 240);
                output.put(packedPos, ((b + 2) & 0b11111100) | (((k + 2) & 0b11111100) << 16));
            }
        }
    }
}
Also used : MathHelper(net.minecraft.util.math.MathHelper) BlockState(net.minecraft.block.BlockState) PackedBlockPos(grondag.fermion.position.PackedBlockPos) BlockPos(net.minecraft.util.math.BlockPos) FastRenderRegion(grondag.canvas.chunk.FastRenderRegion)

Aggregations

FastRenderRegion (grondag.canvas.chunk.FastRenderRegion)2 BlockState (net.minecraft.block.BlockState)2 BlockPos (net.minecraft.util.math.BlockPos)2 TerrainRenderContext (grondag.canvas.apiimpl.rendercontext.TerrainRenderContext)1 FluidBufferBuilder (grondag.canvas.buffer.packing.FluidBufferBuilder)1 VertexCollectorList (grondag.canvas.buffer.packing.VertexCollectorList)1 ChunkRebuildHelper (grondag.canvas.chunk.ChunkRebuildHelper)1 ChunkRenderDataExt (grondag.canvas.chunk.ChunkRenderDataExt)1 ChunkRendererRegionExt (grondag.canvas.chunk.ChunkRendererRegionExt)1 UploadableChunk (grondag.canvas.chunk.UploadableChunk)1 PackedBlockPos (grondag.fermion.position.PackedBlockPos)1 BlockRenderLayer (net.minecraft.block.BlockRenderLayer)1 BlockEntity (net.minecraft.block.entity.BlockEntity)1 BlockRenderManager (net.minecraft.client.render.block.BlockRenderManager)1 ChunkOcclusionGraphBuilder (net.minecraft.client.render.chunk.ChunkOcclusionGraphBuilder)1 ChunkRenderData (net.minecraft.client.render.chunk.ChunkRenderData)1 ChunkRendererRegion (net.minecraft.client.render.chunk.ChunkRendererRegion)1 FluidState (net.minecraft.fluid.FluidState)1 MathHelper (net.minecraft.util.math.MathHelper)1 World (net.minecraft.world.World)1