From cda169766e100f8c03e7a495910185fdbd6cf5e2 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Thu, 19 Dec 2024 00:01:37 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E9=80=9D=E7=9D=80=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=BF=80=E5=85=89=E6=B8=B2=E6=9F=93=E7=AE=A1=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dependencies.gradle | 5 + gradle/scripts/repositories.gradle | 3 + .../anvilcraft/api/LaserStateAccess.java | 18 ++ .../block/entity/BaseLaserBlockEntity.java | 25 +- .../block/entity/RubyLaserBlockEntity.java | 6 +- .../block/entity/RubyPrismBlockEntity.java | 4 +- .../client/event/RenderEventListener.java | 7 + .../anvilcraft/client/init/ModShaders.java | 1 + .../client/renderer/RenderState.java | 18 +- .../client/renderer/laser/LaserCompiler.java | 18 +- .../client/renderer/laser/LaserRenderer.java | 235 ++++++++++++++++++ .../client/renderer/laser/LaserState.java | 10 +- .../anvilcraft/mixin/LevelRendererMixin.java | 88 +------ .../mixin/MinecraftClientMixin.java | 20 ++ .../anvilcraft/mixin/RenderSystemMixin.java | 24 ++ .../compat/SodiumDefaultMaterialsMixin.java | 2 +- .../anvilcraft/util/ThreadFactoryImpl.java | 36 +++ src/main/resources/anvilcraft.mixins.json | 4 +- 18 files changed, 415 insertions(+), 109 deletions(-) create mode 100644 src/main/java/dev/dubhe/anvilcraft/api/LaserStateAccess.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/mixin/MinecraftClientMixin.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/util/ThreadFactoryImpl.java diff --git a/dependencies.gradle b/dependencies.gradle index b2a16869e..c4722d11d 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -29,6 +29,11 @@ dependencies { implementation(libs.jade) implementation(libs.theoneprobe) implementation(libs.kubejs) + + compileOnly("org.sinytra.forgified-fabric-api:fabric-api-base:0.4.42+d1308ded19") + compileOnly("org.sinytra.forgified-fabric-api:fabric-renderer-api-v1:3.4.0+acb05a3919") + compileOnly("org.sinytra.forgified-fabric-api:fabric-block-view-api-v2:1.0.10+9afaaf8c19") + compileOnly("org.sinytra.forgified-fabric-api:fabric-rendering-data-attachment-v1:0.3.48+73761d2e19") } // compileOnly("maven.modrinth:sodium:mc1.21.1-0.6.0-beta.4-neoforge") diff --git a/gradle/scripts/repositories.gradle b/gradle/scripts/repositories.gradle index 46f4b838b..4f8c7c419 100644 --- a/gradle/scripts/repositories.gradle +++ b/gradle/scripts/repositories.gradle @@ -31,4 +31,7 @@ repositories { maven { // TOP url "https://maven.k-4u.nl" } + maven { + url "https://maven.su5ed.dev/releases" + } } diff --git a/src/main/java/dev/dubhe/anvilcraft/api/LaserStateAccess.java b/src/main/java/dev/dubhe/anvilcraft/api/LaserStateAccess.java new file mode 100644 index 000000000..4356790da --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/api/LaserStateAccess.java @@ -0,0 +1,18 @@ +package dev.dubhe.anvilcraft.api; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; + +public interface LaserStateAccess { + BlockPos getIrradiateBlockPos(); + + int getLaserLevel(); + + Direction getFacing(); + + BlockPos getBlockPos(); + + float getLaserOffset(); + + boolean removed(); +} diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java index 564c8439a..8f280da83 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java @@ -1,6 +1,8 @@ package dev.dubhe.anvilcraft.block.entity; import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.api.LaserStateAccess; +import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; import dev.dubhe.anvilcraft.init.ModBlockTags; import dev.dubhe.anvilcraft.init.ModDamageTypes; import dev.dubhe.anvilcraft.network.LaserEmitPacket; @@ -35,7 +37,7 @@ import java.util.HashSet; import java.util.List; -public abstract class BaseLaserBlockEntity extends BlockEntity { +public abstract class BaseLaserBlockEntity extends BlockEntity implements LaserStateAccess { public static final int[] COOLDOWNS = { Integer.MAX_VALUE, 24 * 20, @@ -194,8 +196,8 @@ public void emitLaser(Direction direction) { IItemHandler cap = getLevel() .getCapability( Capabilities.ItemHandler.BLOCK, - getBlockPos().relative(getDirection().getOpposite()), - getDirection() + getBlockPos().relative(getFacing().getOpposite()), + getFacing() ); drops.forEach(itemStack -> { if (cap != null) { @@ -267,7 +269,7 @@ public void onCancelingIrradiation(BaseLaserBlockEntity baseLaserBlockEntity) { irradiateBlockEntity.onCancelingIrradiation(this); } - public abstract Direction getDirection(); + public abstract Direction getFacing(); @Override public void setRemoved() { @@ -276,9 +278,10 @@ public void setRemoved() { if (irradiateBlockPos == null) return; if (!(level.getBlockEntity(irradiateBlockPos) instanceof BaseLaserBlockEntity irradiateBlockEntity)) return; irradiateBlockEntity.onCancelingIrradiation(this); + LaserRenderer.getInstance().requireRecompile(this); } - public float laserOffset() { + public float getLaserOffset() { return 0; } @@ -299,6 +302,17 @@ public AABB getRenderBoundingBox() { Double.POSITIVE_INFINITY); } + @Override + public boolean removed() { + return isRemoved(); + } + + @Override + public void clearRemoved() { + super.clearRemoved(); + LaserRenderer.getInstance().requireRecompile(this); + } + public void updateLaserLevel(int value){ if (laserLevel != value){ markChanged(); @@ -309,5 +323,6 @@ public void updateLaserLevel(int value){ public void clientUpdate(BlockPos irradiateBlockPos, int laserLevel) { this.irradiateBlockPos = irradiateBlockPos; this.laserLevel = laserLevel; + LaserRenderer.getInstance().requireRecompile(this); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyLaserBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyLaserBlockEntity.java index 01e56f685..235fa309c 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyLaserBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyLaserBlockEntity.java @@ -58,7 +58,7 @@ public void tick(@NotNull Level level) { 2); } if (isSwitchedOn()) { - emitLaser(getDirection()); + emitLaser(getFacing()); } else { if (irradiateBlockPos != null && level.getBlockEntity(irradiateBlockPos) instanceof BaseLaserBlockEntity irradiateBlockEntity @@ -96,12 +96,12 @@ public int getInputPower() { } @Override - public float laserOffset() { + public float getLaserOffset() { return 0.489f; } @Override - public Direction getDirection() { + public Direction getFacing() { return this.getBlockState().getValue(RubyLaserBlock.FACING); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyPrismBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyPrismBlockEntity.java index c142cc1bc..57fe65da7 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyPrismBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/RubyPrismBlockEntity.java @@ -29,7 +29,7 @@ private RubyPrismBlockEntity(BlockEntityType type, BlockPos pos, BlockState b public void tick(@NotNull Level level) { resetState(); if (enabled || enabledLastTick) { - emitLaser(getDirection()); + emitLaser(getFacing()); } enabledLastTick = enabled; if (laserLevel == 0) { @@ -57,7 +57,7 @@ public void onIrradiated(BaseLaserBlockEntity baseLaserBlockEntity) { } @Override - public Direction getDirection() { + public Direction getFacing() { return getBlockState().getValue(RubyPrismBlock.FACING); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java b/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java index 70eab313b..f25c04757 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java @@ -6,6 +6,7 @@ import dev.dubhe.anvilcraft.api.tooltip.HudTooltipManager; import dev.dubhe.anvilcraft.client.ModInspectionClient; import dev.dubhe.anvilcraft.client.renderer.PowerGridRenderer; +import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; import dev.dubhe.anvilcraft.item.IEngineerGoggles; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; @@ -29,6 +30,12 @@ @EventBusSubscriber(value = Dist.CLIENT) public class RenderEventListener { + @SubscribeEvent + public static void onRenderLaser(RenderLevelStageEvent event) { + if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_LEVEL)return; + LaserRenderer.getInstance().render(event.getModelViewMatrix(), event.getProjectionMatrix()); + } + @SubscribeEvent public static void onRenderInspection(RenderLevelStageEvent event) { if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_BLOCK_ENTITIES) return; diff --git a/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java b/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java index 0adc94091..4c5546380 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java @@ -24,6 +24,7 @@ public class ModShaders { private static PostChain bloomChain; static final Minecraft MINECRAFT = Minecraft.getInstance(); + @Getter static ShaderInstance renderTypeLaserShader; static ShaderInstance renderTypeColoredOverlayShader; @Getter diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java index 773d86488..5292ab118 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java @@ -8,26 +8,12 @@ import org.slf4j.Logger; public class RenderState { - - private static boolean CONTAINS_INCOMPATIBLE_MODS; private static boolean IRIS_PRESENT; @Getter private static boolean bloomRenderStage; - private static final String[] INCOMPATIBLE_MODS = { - "sodium", - "embeddium", - "iris" - }; private static final Logger logger = LogUtils.getLogger(); static { - CONTAINS_INCOMPATIBLE_MODS = false; - for (String incompatibleMod : INCOMPATIBLE_MODS) { - if (ModList.get().isLoaded(incompatibleMod)){ - logger.warn("Incompatible mod {} detected, fallback laser rendering into BlockEntityRenderer.", incompatibleMod); - CONTAINS_INCOMPATIBLE_MODS = true; - } - } IRIS_PRESENT = ModList.get().isLoaded("iris"); } @@ -44,7 +30,7 @@ public static void levelStage(){ } public static boolean isEnhancedRenderingAvailable() { - return !(CONTAINS_INCOMPATIBLE_MODS || Minecraft.useShaderTransparency()); + return !Minecraft.useShaderTransparency(); } public static boolean isBloomEffectEnabled(){ @@ -52,6 +38,6 @@ public static boolean isBloomEffectEnabled(){ } public static boolean hasIncompatibleMods() { - return CONTAINS_INCOMPATIBLE_MODS; + return false; } } diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java index 9f623b5fc..1c78aaa42 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java @@ -4,9 +4,11 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import dev.dubhe.anvilcraft.client.init.ModRenderTypes; import dev.dubhe.anvilcraft.client.renderer.RenderState; +import dev.dubhe.anvilcraft.util.Callback; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import java.util.function.Consumer; import java.util.function.Function; public class LaserCompiler { @@ -25,6 +27,18 @@ public class LaserCompiler { public static void compile( LaserState state, Function bufferBuilderFunction + ) { + compile( + state, + bufferBuilderFunction, + it -> {} + ); + } + + public static void compile( + LaserState state, + Function bufferBuilderFunction, + Consumer renderTypeCompiled ) { if (state.laserLevel() <= 0) return; VertexConsumer solidLayer = bufferBuilderFunction.apply(RenderType.solid()); @@ -42,7 +56,8 @@ public static void compile( state.laserAtlasSprite(), state.concreteAtlasSprite() ); - RenderType haloRenderType = RenderState.isEnhancedRenderingAvailable() ? ModRenderTypes.LASER : RenderType.translucent(); + renderTypeCompiled.accept(RenderType.solid()); + RenderType haloRenderType = ModRenderTypes.LASER; VertexConsumer builder = bufferBuilderFunction.apply(haloRenderType); float haloWidth = width + HALF_PIXEL; renderBox( @@ -58,6 +73,7 @@ public static void compile( state.laserAtlasSprite(), state.concreteAtlasSprite() ); + renderTypeCompiled.accept(haloRenderType); } private static void renderBox( diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java new file mode 100644 index 000000000..bda37e02f --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -0,0 +1,235 @@ +package dev.dubhe.anvilcraft.client.renderer.laser; + +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.shaders.Uniform; +import com.mojang.blaze3d.systems.RenderSystem; +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.Tesselator; +import com.mojang.blaze3d.vertex.VertexBuffer; +import com.mojang.blaze3d.vertex.VertexFormat; +import dev.dubhe.anvilcraft.api.LaserStateAccess; +import dev.dubhe.anvilcraft.client.init.ModRenderTargets; +import dev.dubhe.anvilcraft.client.init.ModRenderTypes; +import dev.dubhe.anvilcraft.client.renderer.RenderState; +import dev.dubhe.anvilcraft.util.ThreadFactoryImpl; +import lombok.Getter; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.core.BlockPos; +import net.minecraft.world.phys.Vec3; +import org.joml.Matrix4f; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class LaserRenderer { + public static final RenderType[] SUPPORTED_RENDERTYPES = new RenderType[]{ + ModRenderTypes.LASER, + RenderType.solid(), + }; + private final Queue pendingUploads = new ConcurrentLinkedDeque<>(); + private final Queue compileQueue = new ConcurrentLinkedDeque<>(); + @Getter + private static LaserRenderer instance; + private final Map byteBuffers = Arrays.stream(SUPPORTED_RENDERTYPES) + .collect(Collectors.toMap( + Function.identity(), + it -> new ByteBufferBuilder(786432) + )); + private final Map buffers = Arrays.stream(SUPPORTED_RENDERTYPES) + .collect(Collectors.toMap( + Function.identity(), + it -> new VertexBuffer(VertexBuffer.Usage.STATIC) + )); + private final ClientLevel level; + private Set laserBlockEntities = new HashSet<>(); + private final Minecraft minecraft = Minecraft.getInstance(); + private static final ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactoryImpl()); + private RebuildTask lastRebuildTask = null; + private boolean isEmpty = true; + private boolean valid = true; + + public LaserRenderer(ClientLevel level) { + this.level = level; + } + + public static void updateLevel(ClientLevel level) { + if (instance != null) { + instance.releaseBuffers(); + } + instance = new LaserRenderer(level); + } + + public void uploadBuffers() { + while (!compileQueue.isEmpty()){ + compileQueue.poll().run(); + } + while (!pendingUploads.isEmpty()) { + pendingUploads.poll().run(); + } + } + + public void releaseBuffers() { + byteBuffers.values().forEach(ByteBufferBuilder::close); + buffers.values().forEach(VertexBuffer::close); + valid = false; + } + + public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { + if (lastRebuildTask != null) { + lastRebuildTask.cancel(); + } + if (baseLaserBlockEntity.removed()) { + laserBlockEntities.remove(baseLaserBlockEntity); + return; + } + laserBlockEntities.add(baseLaserBlockEntity); + compileQueue.add(new RebuildTask()); + } + + public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { + if (ModRenderTargets.getBloomTarget() != null && RenderState.isBloomEffectEnabled()) { + ModRenderTargets.getBloomTarget().setClearColor(0, 0, 0, 0); + ModRenderTargets.getBloomTarget().clear(Minecraft.ON_OSX); + ModRenderTargets.getBloomTarget().copyDepthFrom(this.minecraft.getMainRenderTarget()); + } + if (isEmpty) return; + System.out.println("RENDER!!!"); + Window window = Minecraft.getInstance().getWindow(); + Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); + for (Map.Entry entry : buffers.entrySet()) { + if (entry.getKey() == ModRenderTypes.LASER) { + RenderState.levelStage(); + renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); + RenderState.bloomStage(); + renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); + continue; + } + renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); + } + } + + private void renderLayer( + RenderType renderType, + VertexBuffer vertexBuffer, + Matrix4f frustumMatrix, + Matrix4f projectionMatrix, + Vec3 cameraPosition, + Window window + ) { + if (vertexBuffer.getFormat() == null) { + System.out.println("WTF"); + return; + } + renderType.setupRenderState(); + ShaderInstance shader = RenderSystem.getShader(); + shader.setDefaultUniforms(VertexFormat.Mode.QUADS, frustumMatrix, projectionMatrix, window); + shader.apply(); + Uniform uniform = shader.CHUNK_OFFSET; + if (uniform != null) { + uniform.set( + (float) -cameraPosition.x, + (float) -cameraPosition.y, + (float) -cameraPosition.z + ); + uniform.upload(); + } + vertexBuffer.bind(); + vertexBuffer.draw(); + VertexBuffer.unbind(); + if (uniform != null) { + uniform.set(0.0F, 0.0F, 0.0F); + } + renderType.clearRenderState(); + } + + public void clear() { + byteBuffers.values().forEach(ByteBufferBuilder::clear); + } + + private class RebuildTask implements Runnable { + private boolean cancelled = false; + + @Override + public void run() { + lastRebuildTask = this; + Map bufferBuilderMap = new HashMap<>(); + for (RenderType supportedRendertype : SUPPORTED_RENDERTYPES) { + bufferBuilderMap.put(supportedRendertype, new BufferBuilder( + byteBuffers.get(supportedRendertype), + VertexFormat.Mode.QUADS, + DefaultVertexFormat.BLOCK) + ); + } + PoseStack poseStack = new PoseStack(); + LaserRenderer.this.isEmpty = true; + for (LaserStateAccess laserBlockEntity : new ArrayList<>(laserBlockEntities)) { + if (cancelled) return; + poseStack.pushPose(); + BlockPos pos = laserBlockEntity.getBlockPos(); + poseStack.translate( + pos.getX(), + pos.getY(), + pos.getZ() + ); + LaserState laserState = LaserState.create(laserBlockEntity, poseStack); + if (laserState == null) continue; + LaserCompiler.compile( + laserState, + it -> { + if (bufferBuilderMap.containsKey(it)) { + return bufferBuilderMap.get(it); + } + throw new IllegalArgumentException("Unknown RenderType: " + it); + }, + it -> { + + } + ); + } + bufferBuilderMap.forEach((renderType, bufferBuilder) -> { + if (bufferBuilder != null) { + MeshData meshData = bufferBuilder.build(); + if (meshData != null) { + LaserRenderer.this.isEmpty = false; + VertexBuffer vb = buffers.get(renderType); + if (vb.isInvalid()) { + meshData.close(); + } else { + pendingUploads.add(() -> { + if (LaserRenderer.this.valid) { + if (vb.isInvalid()) return; + vb.bind(); + vb.upload(meshData); + VertexBuffer.unbind(); + } + }); + } + } + } + }); + + lastRebuildTask = null; + } + + void cancel() { + cancelled = true; + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserState.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserState.java index 1abf2baee..43cad0278 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserState.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserState.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.api.LaserStateAccess; import dev.dubhe.anvilcraft.block.entity.BaseLaserBlockEntity; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureAtlas; @@ -12,7 +13,7 @@ import java.util.function.Function; public record LaserState( - BaseLaserBlockEntity blockEntity, + LaserStateAccess blockEntity, BlockPos pos, float length, float offset, @@ -21,8 +22,7 @@ public record LaserState( TextureAtlasSprite laserAtlasSprite, TextureAtlasSprite concreteAtlasSprite ) { - public static LaserState create(BaseLaserBlockEntity blockEntity, PoseStack poseStack) { - if (blockEntity.getLevel() == null) return null; + public static LaserState create(LaserStateAccess blockEntity, PoseStack poseStack) { if (blockEntity.getIrradiateBlockPos() == null) return null; Function spriteGetter = Minecraft.getInstance() .getTextureAtlas(TextureAtlas.LOCATION_BLOCKS); @@ -32,12 +32,12 @@ public static LaserState create(BaseLaserBlockEntity blockEntity, PoseStack pose .getIrradiateBlockPos() .getCenter() .distanceTo(blockEntity.getBlockPos().getCenter()) - 0.5); - poseStack.mulPose(blockEntity.getDirection().getRotation()); + poseStack.mulPose(blockEntity.getFacing().getRotation()); LaserState laserState = new LaserState( blockEntity, blockEntity.getBlockPos(), length, - blockEntity.laserOffset(), + blockEntity.getLaserOffset(), blockEntity.getLaserLevel(), poseStack.last(), spriteGetter diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 8ed1a406e..45722540d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -12,10 +12,10 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import dev.dubhe.anvilcraft.client.init.ModRenderTargets; -import dev.dubhe.anvilcraft.client.init.ModRenderTypes; import dev.dubhe.anvilcraft.client.init.ModShaders; import dev.dubhe.anvilcraft.client.renderer.PowerGridRenderer; import dev.dubhe.anvilcraft.client.renderer.RenderState; +import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; import dev.dubhe.anvilcraft.util.RenderHelper; import net.minecraft.client.Camera; import net.minecraft.client.DeltaTracker; @@ -27,13 +27,11 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; -import net.minecraft.world.phys.Vec3; import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -47,50 +45,6 @@ public abstract class LevelRendererMixin { @Final private Minecraft minecraft; - @Inject( - method = "renderLevel", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V", - ordinal = 5, - shift = At.Shift.AFTER - ) - ) - void renderLayer( - DeltaTracker deltaTracker, - boolean renderBlockOutline, - Camera camera, - GameRenderer gameRenderer, - LightTexture lightTexture, - Matrix4f frustumMatrix, - Matrix4f projectionMatrix, - CallbackInfo ci - ) { - anvilcraft$renderLaser(deltaTracker, renderBlockOutline, camera, gameRenderer, lightTexture, frustumMatrix, projectionMatrix); - } - - @Inject( - method = "renderLevel", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V", - ordinal = 3, - shift = At.Shift.AFTER - ) - ) - void renderLayer1( - DeltaTracker deltaTracker, - boolean renderBlockOutline, - Camera camera, - GameRenderer gameRenderer, - LightTexture lightTexture, - Matrix4f frustumMatrix, - Matrix4f projectionMatrix, - CallbackInfo ci - ) { - anvilcraft$renderLaser(deltaTracker, renderBlockOutline, camera, gameRenderer, lightTexture, frustumMatrix, projectionMatrix); - } - @Inject( method = "renderLevel", at = @At( @@ -120,6 +74,18 @@ void renderEnhancedTransmitterLines( } } + @Inject( + method = "renderLevel", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/LevelRenderer;compileSections(Lnet/minecraft/client/Camera;)V" + ) + ) + void uploadBuffers(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f frustumMatrix, Matrix4f projectionMatrix, CallbackInfo ci){ + LaserRenderer.getInstance().uploadBuffers(); + } + + @Inject( method = "renderLevel", at = @At( @@ -182,33 +148,5 @@ void bloomPostProcess( minecraft.getMainRenderTarget().bindWrite(false); } - @Unique - private void anvilcraft$renderLaser( - DeltaTracker deltaTracker, - boolean renderBlockOutline, - Camera camera, - GameRenderer gameRenderer, - LightTexture lightTexture, - Matrix4f frustumMatrix, - Matrix4f projectionMatrix - ) { - if (!RenderState.isEnhancedRenderingAvailable()) return; - Vec3 vec3 = camera.getPosition(); - double d0 = vec3.x(); - double d1 = vec3.y(); - double d2 = vec3.z(); - if (ModRenderTargets.getBloomTarget() != null && RenderState.isBloomEffectEnabled()) { - ModRenderTargets.getBloomTarget().setClearColor(0, 0, 0, 0); - ModRenderTargets.getBloomTarget().clear(Minecraft.ON_OSX); - ModRenderTargets.getBloomTarget().copyDepthFrom(this.minecraft.getMainRenderTarget()); - } - - RenderState.levelStage(); - this.renderSectionLayer(ModRenderTypes.LASER, d0, d1, d2, frustumMatrix, projectionMatrix); - if (!RenderState.isBloomEffectEnabled()) return; - RenderState.bloomStage(); - this.renderSectionLayer(ModRenderTypes.LASER, d0, d1, d2, frustumMatrix, projectionMatrix); - } - } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/MinecraftClientMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/MinecraftClientMixin.java new file mode 100644 index 000000000..d785ac28e --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/MinecraftClientMixin.java @@ -0,0 +1,20 @@ +package dev.dubhe.anvilcraft.mixin; + +import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +public class MinecraftClientMixin { + @Inject( + method = "updateLevelInEngines", + at = @At("HEAD") + ) + void updateLevel(ClientLevel level, CallbackInfo ci){ + LaserRenderer.updateLevel(level); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java new file mode 100644 index 000000000..96275c283 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java @@ -0,0 +1,24 @@ +package dev.dubhe.anvilcraft.mixin; + +import com.mojang.blaze3d.systems.RenderSystem; +import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(RenderSystem.class) +public class RenderSystemMixin { + @Inject( + method = "flipFrame", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/blaze3d/vertex/Tesselator;clear()V" + ) + ) + private static void clearBuffers(long windowId, CallbackInfo ci){ + if (LaserRenderer.getInstance() != null) { + LaserRenderer.getInstance().clear(); + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumDefaultMaterialsMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumDefaultMaterialsMixin.java index 5369cb48b..44568ba18 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumDefaultMaterialsMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumDefaultMaterialsMixin.java @@ -18,7 +18,7 @@ public class SodiumDefaultMaterialsMixin { cancellable = true ) private static void anvilcraft$forRenderLayer(RenderType layer, CallbackInfoReturnable cir){ - if (layer == ModRenderTypes.LASER){ + if (layer == ModRenderTypes.LASER) { cir.setReturnValue(ModSodiumMaterials.LASER); cir.cancel(); } diff --git a/src/main/java/dev/dubhe/anvilcraft/util/ThreadFactoryImpl.java b/src/main/java/dev/dubhe/anvilcraft/util/ThreadFactoryImpl.java new file mode 100644 index 000000000..d8ddc8f64 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/util/ThreadFactoryImpl.java @@ -0,0 +1,36 @@ +package dev.dubhe.anvilcraft.util; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.atomic.AtomicInteger; + +public class ThreadFactoryImpl implements java.util.concurrent.ThreadFactory { + private static final AtomicInteger poolNumber = new AtomicInteger(1); + private final ThreadGroup group; + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final String namePrefix; + + @SuppressWarnings("removal") + public ThreadFactoryImpl() { + SecurityManager s = System.getSecurityManager(); + group = (s != null) + ? s.getThreadGroup() + : Thread.currentThread().getThreadGroup(); + namePrefix = "AnvilCraftWorker-" + poolNumber.getAndIncrement() + "-thread-"; + } + + @Override + public Thread newThread(@NotNull Runnable r) { + Thread t = new Thread( + group, + r, + namePrefix + threadNumber.getAndIncrement(), + 0 + ); + t.setDaemon(true); + if (t.getPriority() != Thread.NORM_PRIORITY) { + t.setPriority(Thread.NORM_PRIORITY); + } + return t; + } +} diff --git a/src/main/resources/anvilcraft.mixins.json b/src/main/resources/anvilcraft.mixins.json index 33eb92b73..fc4ffb8ad 100644 --- a/src/main/resources/anvilcraft.mixins.json +++ b/src/main/resources/anvilcraft.mixins.json @@ -36,14 +36,16 @@ "GameRendererMixin", "ItemInHandRendererMixin", "LevelRendererMixin", + "MinecraftClientMixin", "MouseHandlerMixin", + "RenderSystemMixin", "RenderTypeMixin", "SectionCompilerMixin", "SoundEngineMixin", "compat.EmbChunkBuilderMeshingTaskMixin", - "compat.SodiumChunkBuilderMeshingTaskMixin", "compat.EmbeddiumDefaultMaterialsMixin", "compat.EmbeddiumDefaultTerrainRenderPassesMixin", + "compat.SodiumChunkBuilderMeshingTaskMixin", "compat.SodiumDefaultMaterialsMixin", "compat.SodiumDefaultTerrainRenderPassesMixin" ], From a5acdc6e8e60157bd851befc6fc80418d1fab255 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Thu, 19 Dec 2024 01:16:41 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E9=80=9D=E7=9D=80=E5=AE=9E=E7=8E=B0vertex?= =?UTF-8?q?=20sort?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/event/RenderEventListener.java | 6 --- .../client/renderer/laser/LaserCompiler.java | 14 ------- .../client/renderer/laser/LaserRenderer.java | 32 ++++++++++++++-- .../anvilcraft/mixin/LevelRendererMixin.java | 1 + .../mixin/SectionCompilerMixin.java | 38 +++++++++---------- 5 files changed, 48 insertions(+), 43 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java b/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java index f25c04757..74d9f2b0d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java @@ -30,12 +30,6 @@ @EventBusSubscriber(value = Dist.CLIENT) public class RenderEventListener { - @SubscribeEvent - public static void onRenderLaser(RenderLevelStageEvent event) { - if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_LEVEL)return; - LaserRenderer.getInstance().render(event.getModelViewMatrix(), event.getProjectionMatrix()); - } - @SubscribeEvent public static void onRenderInspection(RenderLevelStageEvent event) { if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_BLOCK_ENTITIES) return; diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java index 1c78aaa42..b46581cc2 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java @@ -27,18 +27,6 @@ public class LaserCompiler { public static void compile( LaserState state, Function bufferBuilderFunction - ) { - compile( - state, - bufferBuilderFunction, - it -> {} - ); - } - - public static void compile( - LaserState state, - Function bufferBuilderFunction, - Consumer renderTypeCompiled ) { if (state.laserLevel() <= 0) return; VertexConsumer solidLayer = bufferBuilderFunction.apply(RenderType.solid()); @@ -56,7 +44,6 @@ public static void compile( state.laserAtlasSprite(), state.concreteAtlasSprite() ); - renderTypeCompiled.accept(RenderType.solid()); RenderType haloRenderType = ModRenderTypes.LASER; VertexConsumer builder = bufferBuilderFunction.apply(haloRenderType); float haloWidth = width + HALF_PIXEL; @@ -73,7 +60,6 @@ public static void compile( state.laserAtlasSprite(), state.concreteAtlasSprite() ); - renderTypeCompiled.accept(haloRenderType); } private static void renderBox( diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index bda37e02f..7432b5f24 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -11,6 +11,7 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexBuffer; import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.blaze3d.vertex.VertexSorting; import dev.dubhe.anvilcraft.api.LaserStateAccess; import dev.dubhe.anvilcraft.client.init.ModRenderTargets; import dev.dubhe.anvilcraft.client.init.ModRenderTypes; @@ -57,6 +58,7 @@ public class LaserRenderer { Function.identity(), it -> new VertexBuffer(VertexBuffer.Usage.STATIC) )); + private final Map sortStates = new HashMap<>(); private final ClientLevel level; private Set laserBlockEntities = new HashSet<>(); private final Minecraft minecraft = Minecraft.getInstance(); @@ -77,7 +79,7 @@ public static void updateLevel(ClientLevel level) { } public void uploadBuffers() { - while (!compileQueue.isEmpty()){ + while (!compileQueue.isEmpty()) { compileQueue.poll().run(); } while (!pendingUploads.isEmpty()) { @@ -100,10 +102,12 @@ public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { return; } laserBlockEntities.add(baseLaserBlockEntity); + laserBlockEntities.removeIf(LaserStateAccess::removed); compileQueue.add(new RebuildTask()); } public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { + RenderSystem.enableBlend(); if (ModRenderTargets.getBloomTarget() != null && RenderState.isBloomEffectEnabled()) { ModRenderTargets.getBloomTarget().setClearColor(0, 0, 0, 0); ModRenderTargets.getBloomTarget().clear(Minecraft.ON_OSX); @@ -114,6 +118,16 @@ public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); for (Map.Entry entry : buffers.entrySet()) { + MeshData.SortState sortState = sortStates.get(entry.getKey()); + if (sortState != null) { + ByteBufferBuilder.Result result = sortState.buildSortedIndexBuffer(byteBuffers.get(entry.getKey()), createVertexSorting()); + if (result != null) { + VertexBuffer vb = entry.getValue(); + vb.bind(); + vb.uploadIndexBuffer(result); + VertexBuffer.unbind(); + } + } if (entry.getKey() == ModRenderTypes.LASER) { RenderState.levelStage(); renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); @@ -159,6 +173,11 @@ private void renderLayer( renderType.clearRenderState(); } + private VertexSorting createVertexSorting() { + Vec3 cameraPos = minecraft.gameRenderer.getMainCamera().getPosition(); + return VertexSorting.byDistance(cameraPos.toVector3f()); + } + public void clear() { byteBuffers.values().forEach(ByteBufferBuilder::clear); } @@ -197,9 +216,6 @@ public void run() { return bufferBuilderMap.get(it); } throw new IllegalArgumentException("Unknown RenderType: " + it); - }, - it -> { - } ); } @@ -209,6 +225,14 @@ public void run() { if (meshData != null) { LaserRenderer.this.isEmpty = false; VertexBuffer vb = buffers.get(renderType); + sortStates.put( + renderType, + meshData.sortQuads( + byteBuffers.get(renderType), + createVertexSorting() + ) + ); + if (vb.isInvalid()) { meshData.close(); } else { diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 45722540d..897db16a4 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -104,6 +104,7 @@ void bloomPostProcess( Matrix4f projectionMatrix, CallbackInfo ci ) { + LaserRenderer.getInstance().render(frustumMatrix, projectionMatrix); if (!RenderState.isEnhancedRenderingAvailable()) return; if (!RenderState.isBloomEffectEnabled()) return; diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/SectionCompilerMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/SectionCompilerMixin.java index 8431168f8..59d3aec90 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/SectionCompilerMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/SectionCompilerMixin.java @@ -113,25 +113,25 @@ void compile( ) { if (!RenderState.isEnhancedRenderingAvailable()) return; if (!(blockEntity instanceof BaseLaserBlockEntity baseLaserBlockEntity)) return; - poseStack.pushPose(); - BlockPos pos = blockEntity.getBlockPos(); - poseStack.translate( - (float) SectionPos.sectionRelative(pos.getX()), - (float) SectionPos.sectionRelative(pos.getY()), - (float) SectionPos.sectionRelative(pos.getZ()) - ); - LaserState laserState = LaserState.create(baseLaserBlockEntity, poseStack); - if (laserState != null) { - LaserCompiler.compile( - laserState, - renderType -> this.getOrBeginLayer( - map, - sectionBufferBuilderPack, - renderType - ) - ); - } - poseStack.popPose(); +// poseStack.pushPose(); +// BlockPos pos = blockEntity.getBlockPos(); +// poseStack.translate( +// (float) SectionPos.sectionRelative(pos.getX()), +// (float) SectionPos.sectionRelative(pos.getY()), +// (float) SectionPos.sectionRelative(pos.getZ()) +// ); +// LaserState laserState = LaserState.create(baseLaserBlockEntity, poseStack); +// if (laserState != null) { +// LaserCompiler.compile( +// laserState, +// renderType -> this.getOrBeginLayer( +// map, +// sectionBufferBuilderPack, +// renderType +// ) +// ); +// } +// poseStack.popPose(); } @WrapOperation( From 715f4c6422bcee4a54272eae7f397c135e5d58fe Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Fri, 20 Dec 2024 18:43:42 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E9=80=9D=E7=9D=80=E5=86=99=E4=BA=86?= =?UTF-8?q?=E6=BF=80=E5=85=89=E7=AE=A1=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/init/ModRenderTypes.java | 2 +- .../anvilcraft/client/init/ModShaders.java | 2 +- .../client/renderer/laser/LaserCompiler.java | 84 +++++--- .../client/renderer/laser/LaserRenderer.java | 201 ++++++++++-------- .../anvilcraft/mixin/LevelRendererMixin.java | 2 +- .../resources/META-INF/accesstransformer.cfg | 17 +- .../shaders/core/rendertype_laser.fsh | 1 + .../shaders/core/rendertype_laser.vsh | 3 + 8 files changed, 191 insertions(+), 121 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/client/init/ModRenderTypes.java b/src/main/java/dev/dubhe/anvilcraft/client/init/ModRenderTypes.java index ab750d9c3..979eaec20 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/init/ModRenderTypes.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/init/ModRenderTypes.java @@ -115,7 +115,7 @@ public void clearRenderState() { public static final RenderType LASER = RenderType.create( "anvilcraft:laser", - DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL, + DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 1536, true, diff --git a/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java b/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java index 4c5546380..c0e407e74 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/init/ModShaders.java @@ -42,7 +42,7 @@ public static void register(RegisterShadersEvent event) { event.registerShader(new ShaderInstance( event.getResourceProvider(), AnvilCraft.of("rendertype_laser"), - DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL + DefaultVertexFormat.BLOCK ), it -> renderTypeLaserShader = it ); diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java index b46581cc2..20b0078fb 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserCompiler.java @@ -7,6 +7,7 @@ import dev.dubhe.anvilcraft.util.Callback; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.neoforged.fml.common.Mod; import java.util.function.Consumer; import java.util.function.Function; @@ -24,41 +25,66 @@ public class LaserCompiler { LASER_WIDTH = array; } + public static void compileStage( + LaserState state, + VertexConsumer vertexConsumer, + RenderType renderType, + float width + ) { + if (renderType == RenderType.SOLID) { + renderBox( + vertexConsumer, + state.pose(), + -width, + -state.offset() - 0.001f, + -width, + width, + state.length() + 0.501f, + width, + 1f, + state.laserAtlasSprite(), + state.concreteAtlasSprite() + ); + } else if (renderType == ModRenderTypes.LASER) { + float haloWidth = width + HALF_PIXEL; + renderBox( + vertexConsumer, + state.pose(), + -haloWidth, + -state.offset(), + -haloWidth, + haloWidth, + state.length() + 0.5f + HALF_PIXEL, + haloWidth, + 0.6f, + state.laserAtlasSprite(), + state.concreteAtlasSprite() + ); + } + } + + public static float laserWidth(LaserState state) { + return LASER_WIDTH[Math.clamp(state.blockEntity().getLaserLevel(), 1, 64)] + 0.001f; + } + + public static void compile( LaserState state, Function bufferBuilderFunction ) { if (state.laserLevel() <= 0) return; - VertexConsumer solidLayer = bufferBuilderFunction.apply(RenderType.solid()); - float width = LASER_WIDTH[Math.clamp(state.blockEntity().getLaserLevel(), 1, 64)] + 0.001f; - renderBox( - solidLayer, - state.pose(), - -width, - -state.offset() - 0.001f, - -width, - width, - state.length() + 0.501f, - width, - 1f, - state.laserAtlasSprite(), - state.concreteAtlasSprite() + float width = laserWidth(state); + compileStage( + state, + bufferBuilderFunction.apply(RenderType.solid()), + RenderType.SOLID, + width ); - RenderType haloRenderType = ModRenderTypes.LASER; - VertexConsumer builder = bufferBuilderFunction.apply(haloRenderType); - float haloWidth = width + HALF_PIXEL; - renderBox( - builder, - state.pose(), - -haloWidth, - -state.offset(), - -haloWidth, - haloWidth, - state.length() + 0.5f + HALF_PIXEL, - haloWidth, - 0.6f, - state.laserAtlasSprite(), - state.concreteAtlasSprite() + compileStage( + state, + bufferBuilderFunction.apply(ModRenderTypes.LASER), + ModRenderTypes.LASER, + width ); } diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index 7432b5f24..481084ae3 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -4,9 +4,7 @@ import com.mojang.blaze3d.shaders.Uniform; import com.mojang.blaze3d.systems.RenderSystem; 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.Tesselator; import com.mojang.blaze3d.vertex.VertexBuffer; @@ -16,7 +14,7 @@ import dev.dubhe.anvilcraft.client.init.ModRenderTargets; import dev.dubhe.anvilcraft.client.init.ModRenderTypes; import dev.dubhe.anvilcraft.client.renderer.RenderState; -import dev.dubhe.anvilcraft.util.ThreadFactoryImpl; +import lombok.EqualsAndHashCode; import lombok.Getter; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -25,6 +23,9 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; import org.joml.Matrix4f; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL15C; +import org.lwjgl.system.MemoryUtil; import java.util.ArrayList; import java.util.Arrays; @@ -34,8 +35,6 @@ import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.function.Function; import java.util.stream.Collectors; @@ -44,25 +43,24 @@ public class LaserRenderer { ModRenderTypes.LASER, RenderType.solid(), }; + private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); + private final Queue pendingUploads = new ConcurrentLinkedDeque<>(); private final Queue compileQueue = new ConcurrentLinkedDeque<>(); @Getter private static LaserRenderer instance; - private final Map byteBuffers = Arrays.stream(SUPPORTED_RENDERTYPES) - .collect(Collectors.toMap( - Function.identity(), - it -> new ByteBufferBuilder(786432) - )); private final Map buffers = Arrays.stream(SUPPORTED_RENDERTYPES) .collect(Collectors.toMap( Function.identity(), it -> new VertexBuffer(VertexBuffer.Usage.STATIC) )); - private final Map sortStates = new HashMap<>(); + + private Map compileResultMap = new HashMap<>(); + + @SuppressWarnings("unused") private final ClientLevel level; - private Set laserBlockEntities = new HashSet<>(); + private final Set laserBlockEntities = new HashSet<>(); private final Minecraft minecraft = Minecraft.getInstance(); - private static final ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactoryImpl()); private RebuildTask lastRebuildTask = null; private boolean isEmpty = true; private boolean valid = true; @@ -78,18 +76,18 @@ public static void updateLevel(ClientLevel level) { instance = new LaserRenderer(level); } - public void uploadBuffers() { - while (!compileQueue.isEmpty()) { + public void runTasks() { + while (!compileQueue.isEmpty() && valid) { compileQueue.poll().run(); } - while (!pendingUploads.isEmpty()) { + while (!pendingUploads.isEmpty() && valid) { pendingUploads.poll().run(); } } public void releaseBuffers() { - byteBuffers.values().forEach(ByteBufferBuilder::close); buffers.values().forEach(VertexBuffer::close); + compileResultMap.values().forEach(CompileResult::free); valid = false; } @@ -118,16 +116,6 @@ public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); for (Map.Entry entry : buffers.entrySet()) { - MeshData.SortState sortState = sortStates.get(entry.getKey()); - if (sortState != null) { - ByteBufferBuilder.Result result = sortState.buildSortedIndexBuffer(byteBuffers.get(entry.getKey()), createVertexSorting()); - if (result != null) { - VertexBuffer vb = entry.getValue(); - vb.bind(); - vb.uploadIndexBuffer(result); - VertexBuffer.unbind(); - } - } if (entry.getKey() == ModRenderTypes.LASER) { RenderState.levelStage(); renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); @@ -147,10 +135,7 @@ private void renderLayer( Vec3 cameraPosition, Window window ) { - if (vertexBuffer.getFormat() == null) { - System.out.println("WTF"); - return; - } + CompileResult compileResult = compileResultMap.get(renderType); renderType.setupRenderState(); ShaderInstance shader = RenderSystem.getShader(); shader.setDefaultUniforms(VertexFormat.Mode.QUADS, frustumMatrix, projectionMatrix, window); @@ -165,7 +150,7 @@ private void renderLayer( uniform.upload(); } vertexBuffer.bind(); - vertexBuffer.draw(); + RenderSystem.drawElements(GL15.GL_TRIANGLES, compileResult.indexCount, vertexBuffer.sequentialIndices.type().asGLType); VertexBuffer.unbind(); if (uniform != null) { uniform.set(0.0F, 0.0F, 0.0F); @@ -179,7 +164,6 @@ private VertexSorting createVertexSorting() { } public void clear() { - byteBuffers.values().forEach(ByteBufferBuilder::clear); } private class RebuildTask implements Runnable { @@ -188,67 +172,59 @@ private class RebuildTask implements Runnable { @Override public void run() { lastRebuildTask = this; - Map bufferBuilderMap = new HashMap<>(); - for (RenderType supportedRendertype : SUPPORTED_RENDERTYPES) { - bufferBuilderMap.put(supportedRendertype, new BufferBuilder( - byteBuffers.get(supportedRendertype), - VertexFormat.Mode.QUADS, - DefaultVertexFormat.BLOCK) - ); - } + Map compileResultMap = new HashMap<>(); PoseStack poseStack = new PoseStack(); LaserRenderer.this.isEmpty = true; - for (LaserStateAccess laserBlockEntity : new ArrayList<>(laserBlockEntities)) { + for (RenderType renderType : SUPPORTED_RENDERTYPES) { if (cancelled) return; - poseStack.pushPose(); - BlockPos pos = laserBlockEntity.getBlockPos(); - poseStack.translate( - pos.getX(), - pos.getY(), - pos.getZ() - ); - LaserState laserState = LaserState.create(laserBlockEntity, poseStack); - if (laserState == null) continue; - LaserCompiler.compile( - laserState, - it -> { - if (bufferBuilderMap.containsKey(it)) { - return bufferBuilderMap.get(it); - } - throw new IllegalArgumentException("Unknown RenderType: " + it); - } + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder bufferBuilder = tesselator.begin(renderType.mode, renderType.format); + long ptr = tesselator.buffer.pointer; + int offsetBeforeCompile = tesselator.buffer.writeOffset; + for (LaserStateAccess laserBlockEntity : new ArrayList<>(laserBlockEntities)) { + if (cancelled) return; + poseStack.pushPose(); + BlockPos pos = laserBlockEntity.getBlockPos(); + poseStack.translate( + pos.getX(), + pos.getY(), + pos.getZ() + ); + LaserState laserState = LaserState.create(laserBlockEntity, poseStack); + if (laserState == null) continue; + float width = LaserCompiler.laserWidth(laserState); + LaserCompiler.compileStage( + laserState, + bufferBuilder, + renderType, + width + ); + poseStack.popPose(); + } + if (bufferBuilder.vertices > 0){ + LaserRenderer.this.isEmpty = false; + } + System.out.println(renderType.name + " bufferBuilder.vertices = " + bufferBuilder.vertices); + int compiledVertices = bufferBuilder.vertices * bufferBuilder.format.getVertexSize(); + long allocated = ALLOCATOR.malloc(compiledVertices); + MemoryUtil.memCopy(ptr + offsetBeforeCompile, allocated, compiledVertices); + CompileResult compileResult = new CompileResult( + renderType, + bufferBuilder.vertices, + bufferBuilder.format.getVertexSize(), + allocated, + renderType.mode.indexCount(bufferBuilder.vertices) ); + compileResultMap.put(renderType, compileResult); } - bufferBuilderMap.forEach((renderType, bufferBuilder) -> { - if (bufferBuilder != null) { - MeshData meshData = bufferBuilder.build(); - if (meshData != null) { - LaserRenderer.this.isEmpty = false; - VertexBuffer vb = buffers.get(renderType); - sortStates.put( - renderType, - meshData.sortQuads( - byteBuffers.get(renderType), - createVertexSorting() - ) - ); - - if (vb.isInvalid()) { - meshData.close(); - } else { - pendingUploads.add(() -> { - if (LaserRenderer.this.valid) { - if (vb.isInvalid()) return; - vb.bind(); - vb.upload(meshData); - VertexBuffer.unbind(); - } - }); - } - } - } + LaserRenderer.this.compileResultMap.values().forEach(CompileResult::free); + LaserRenderer.this.compileResultMap = compileResultMap; + compileResultMap.forEach((renderType, compileResult) -> { + pendingUploads.add(() -> { + VertexBuffer vb = buffers.get(renderType); + compileResult.upload(vb); + }); }); - lastRebuildTask = null; } @@ -256,4 +232,53 @@ void cancel() { cancelled = true; } } + + @EqualsAndHashCode + static final class CompileResult { + final RenderType renderType; + final int vertexCount; + final int vertexSize; + final long vertexBufferPtr; + final int indexCount; + boolean freed = false; + + CompileResult( + RenderType renderType, + int vertexCount, + int vertexSize, + long vertexBufferPtr, + int indexCount + ) { + this.renderType = renderType; + this.vertexCount = vertexCount; + this.vertexSize = vertexSize; + this.vertexBufferPtr = vertexBufferPtr; + this.indexCount = indexCount; + } + + void upload(VertexBuffer vertexBuffer) { + if (freed) return; + VertexFormat.Mode mode = renderType.mode; + vertexBuffer.bind(); + if (vertexBuffer.format != null) { + vertexBuffer.format.clearBufferState(); + } + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBuffer.vertexBufferId); + renderType.format.setupBufferState(); + vertexBuffer.format = renderType.format; + GL15C.nglBufferData(GL15.GL_ARRAY_BUFFER, (long) vertexCount * vertexSize, vertexBufferPtr, GL15.GL_STATIC_DRAW); + RenderSystem.AutoStorageIndexBuffer indexBuffer = RenderSystem.getSequentialBuffer(mode); + if (indexBuffer != vertexBuffer.sequentialIndices || !indexBuffer.hasStorage(indexCount)) { + indexBuffer.bind(indexCount); + } + vertexBuffer.sequentialIndices = indexBuffer; + VertexBuffer.unbind(); + } + + void free() { + if (freed) return; + ALLOCATOR.free(vertexBufferPtr); + freed = true; + } + } } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 897db16a4..36212f733 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -82,7 +82,7 @@ void renderEnhancedTransmitterLines( ) ) void uploadBuffers(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f frustumMatrix, Matrix4f projectionMatrix, CallbackInfo ci){ - LaserRenderer.getInstance().uploadBuffers(); + LaserRenderer.getInstance().runTasks(); } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index e5d704cdf..c5bc92c92 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -61,4 +61,19 @@ public net.minecraft.client.Minecraft missTime public net.minecraft.client.Minecraft handleKeybinds()V public net.minecraft.world.entity.Entity inBlockState -public net.minecraft.world.entity.Entity collideWithShapes(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/List;)Lnet/minecraft/world/phys/Vec3; # collideWithShapes \ No newline at end of file +public net.minecraft.world.entity.Entity collideWithShapes(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/List;)Lnet/minecraft/world/phys/Vec3; # collideWithShapes + +public com.mojang.blaze3d.vertex.Tesselator buffer +public com.mojang.blaze3d.vertex.ByteBufferBuilder pointer +public com.mojang.blaze3d.vertex.ByteBufferBuilder capacity +public com.mojang.blaze3d.vertex.ByteBufferBuilder writeOffset +public com.mojang.blaze3d.vertex.BufferBuilder format +public com.mojang.blaze3d.vertex.BufferBuilder vertices + +public com.mojang.blaze3d.vertex.VertexBuffer vertexBufferId +public com.mojang.blaze3d.vertex.VertexBuffer indexBufferId +public com.mojang.blaze3d.vertex.VertexBuffer arrayObjectId +public com.mojang.blaze3d.vertex.VertexBuffer format +public com.mojang.blaze3d.vertex.VertexBuffer usage +public com.mojang.blaze3d.vertex.VertexBuffer sequentialIndices + diff --git a/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.fsh b/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.fsh index 851068d05..e5a9cb21d 100644 --- a/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.fsh +++ b/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.fsh @@ -12,6 +12,7 @@ uniform vec4 FogColor; in float vertexDistance; in vec4 vertexColor; in vec2 texCoord0; +in vec2 lightCoord; out vec4 fragColor; diff --git a/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.vsh b/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.vsh index 0fee16182..6082fced0 100644 --- a/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.vsh +++ b/src/main/resources/assets/anvilcraft/shaders/core/rendertype_laser.vsh @@ -5,6 +5,7 @@ in vec3 Position; in vec4 Color; in vec2 UV0; +in vec2 UV2; in vec3 Normal; uniform sampler2D Sampler2; @@ -17,6 +18,7 @@ uniform int FogShape; out float vertexDistance; out vec4 vertexColor; out vec2 texCoord0; +out vec2 lightCoord; void main() { vec3 pos = Position + ChunkOffset; @@ -24,4 +26,5 @@ void main() { vertexDistance = fog_distance(pos, FogShape); vertexColor = Color; texCoord0 = UV0; + lightCoord = UV2; } From 9e5cd6b8717c4517ce2b98d6ac7afc20ebeb0e60 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Fri, 20 Dec 2024 19:27:52 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=BF=80=E5=85=89=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?=E5=A4=A7=E9=83=A8=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/entity/BaseLaserBlockEntity.java | 2 +- .../client/renderer/PowerGridRenderer.java | 5 +++ .../client/renderer/laser/LaserRenderer.java | 45 ++++++++++--------- .../anvilcraft/mixin/LevelRendererMixin.java | 3 +- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java index 8f280da83..c75618d13 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseLaserBlockEntity.java @@ -304,7 +304,7 @@ public AABB getRenderBoundingBox() { @Override public boolean removed() { - return isRemoved(); + return remove; } @Override diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/PowerGridRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/PowerGridRenderer.java index 931e4b05b..6614e6eff 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/PowerGridRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/PowerGridRenderer.java @@ -65,6 +65,11 @@ public static void renderEnhancedTransmitterLine( if (!RenderState.isEnhancedRenderingAvailable() || !RenderState.isBloomEffectEnabled()) return; if (!AnvilCraft.config.renderPowerTransmitterLines) return; if (Minecraft.getInstance().level == null) return; + if (ModRenderTargets.getBloomTarget() != null) { + ModRenderTargets.getBloomTarget().setClearColor(0, 0, 0, 0); + ModRenderTargets.getBloomTarget().clear(Minecraft.ON_OSX); + ModRenderTargets.getBloomTarget().copyDepthFrom(Minecraft.getInstance().getMainRenderTarget()); + } String level = Minecraft.getInstance().level.dimension().location().toString(); VertexConsumer consumer1 = bufferSource.getBuffer(ModRenderTypes.LINE_BLOOM); diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index 481084ae3..405a3fb53 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexBuffer; @@ -40,8 +41,8 @@ public class LaserRenderer { public static final RenderType[] SUPPORTED_RENDERTYPES = new RenderType[]{ - ModRenderTypes.LASER, RenderType.solid(), + ModRenderTypes.LASER }; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); @@ -97,6 +98,7 @@ public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { } if (baseLaserBlockEntity.removed()) { laserBlockEntities.remove(baseLaserBlockEntity); + compileQueue.add(new RebuildTask()); return; } laserBlockEntities.add(baseLaserBlockEntity); @@ -106,24 +108,19 @@ public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { RenderSystem.enableBlend(); - if (ModRenderTargets.getBloomTarget() != null && RenderState.isBloomEffectEnabled()) { - ModRenderTargets.getBloomTarget().setClearColor(0, 0, 0, 0); - ModRenderTargets.getBloomTarget().clear(Minecraft.ON_OSX); - ModRenderTargets.getBloomTarget().copyDepthFrom(this.minecraft.getMainRenderTarget()); - } if (isEmpty) return; - System.out.println("RENDER!!!"); Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); - for (Map.Entry entry : buffers.entrySet()) { - if (entry.getKey() == ModRenderTypes.LASER) { + for (RenderType renderType : SUPPORTED_RENDERTYPES) { + VertexBuffer vb = buffers.get(renderType); + if (renderType == ModRenderTypes.LASER) { RenderState.levelStage(); - renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); + renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); RenderState.bloomStage(); - renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); + renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); continue; } - renderLayer(entry.getKey(), entry.getValue(), frustumMatrix, projectionMatrix, cameraPosition, window); + renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); } } @@ -191,23 +188,27 @@ public void run() { pos.getZ() ); LaserState laserState = LaserState.create(laserBlockEntity, poseStack); - if (laserState == null) continue; - float width = LaserCompiler.laserWidth(laserState); - LaserCompiler.compileStage( - laserState, - bufferBuilder, - renderType, - width - ); + if (laserState != null) { + float width = LaserCompiler.laserWidth(laserState); + LaserCompiler.compileStage( + laserState, + bufferBuilder, + renderType, + width + ); + } poseStack.popPose(); } - if (bufferBuilder.vertices > 0){ + if (bufferBuilder.vertices > 0) { LaserRenderer.this.isEmpty = false; } - System.out.println(renderType.name + " bufferBuilder.vertices = " + bufferBuilder.vertices); int compiledVertices = bufferBuilder.vertices * bufferBuilder.format.getVertexSize(); long allocated = ALLOCATOR.malloc(compiledVertices); MemoryUtil.memCopy(ptr + offsetBeforeCompile, allocated, compiledVertices); + MeshData mesh = bufferBuilder.build(); + if (mesh != null) { + mesh.close(); + } CompileResult compileResult = new CompileResult( renderType, bufferBuilder.vertices, diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 36212f733..0a1d9134c 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -104,10 +104,9 @@ void bloomPostProcess( Matrix4f projectionMatrix, CallbackInfo ci ) { - LaserRenderer.getInstance().render(frustumMatrix, projectionMatrix); if (!RenderState.isEnhancedRenderingAvailable()) return; + LaserRenderer.getInstance().render(frustumMatrix, projectionMatrix); if (!RenderState.isBloomEffectEnabled()) return; - RenderTarget mcInput = ModShaders.getBloomChain().getTempTarget("mcinput"); mcInput.setClearColor(0, 0, 0, 0); mcInput.clear(Minecraft.ON_OSX); From c537442e43993265cebcf6c0e0efe07b3f96d5a4 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Fri, 20 Dec 2024 20:28:17 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=BF=80=E5=85=89=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?=E6=9B=B4=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../anvilcraft/block/BaseLaserBlock.java | 12 +++++++ .../anvilcraft/block/RubyLaserBlock.java | 2 +- .../anvilcraft/block/RubyPrismBlock.java | 2 +- .../client/event/RenderEventListener.java | 1 + .../client/renderer/RenderState.java | 3 +- ...rRenderer.java => LaserBlockRenderer.java} | 4 +-- .../client/renderer/laser/LaserRenderer.java | 34 ++++++++++++++----- .../anvilcraft/init/ModBlockEntities.java | 6 ++-- .../integration/iris/IrisState.java | 2 +- .../anvilcraft/mixin/LevelChunkMixin.java | 29 ++++++++++++++++ .../anvilcraft/mixin/LevelRendererMixin.java | 15 ++++---- .../anvilcraft/mixin/RenderSystemMixin.java | 24 ------------- src/main/resources/anvilcraft.mixins.json | 4 +-- 13 files changed, 87 insertions(+), 51 deletions(-) create mode 100644 src/main/java/dev/dubhe/anvilcraft/block/BaseLaserBlock.java rename src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/{LaserRenderer.java => LaserBlockRenderer.java} (93%) create mode 100644 src/main/java/dev/dubhe/anvilcraft/mixin/LevelChunkMixin.java delete mode 100644 src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java diff --git a/src/main/java/dev/dubhe/anvilcraft/block/BaseLaserBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/BaseLaserBlock.java new file mode 100644 index 000000000..3c6fb275e --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/block/BaseLaserBlock.java @@ -0,0 +1,12 @@ +package dev.dubhe.anvilcraft.block; + +import net.minecraft.world.level.block.BaseEntityBlock; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public abstract class BaseLaserBlock extends BaseEntityBlock { + protected BaseLaserBlock(Properties properties) { + super(properties); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/block/RubyLaserBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/RubyLaserBlock.java index 59e9d0380..3e862bdd0 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/RubyLaserBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/RubyLaserBlock.java @@ -37,7 +37,7 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class RubyLaserBlock extends BaseEntityBlock implements IHammerRemovable, HammerRotateBehavior { +public class RubyLaserBlock extends BaseLaserBlock implements IHammerRemovable, HammerRotateBehavior { public static final VoxelShape UP_MODEL = Shapes.or(Block.box(4, 3, 4, 12, 13, 12), Block.box(5, 13, 5, 11, 16, 11), Block.box(3, 0, 3, 13, 3, 13)); public static final VoxelShape DOWN_MODEL = diff --git a/src/main/java/dev/dubhe/anvilcraft/block/RubyPrismBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/RubyPrismBlock.java index a2cba38f0..87ddee8a1 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/RubyPrismBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/RubyPrismBlock.java @@ -33,7 +33,7 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class RubyPrismBlock extends BaseEntityBlock implements IHammerRemovable, HammerRotateBehavior { +public class RubyPrismBlock extends BaseLaserBlock implements IHammerRemovable, HammerRotateBehavior { public static final VoxelShape UP_MODEL = Shapes.or(Block.box(0, 0, 0, 16, 4, 16), Block.box(2, 4, 2, 14, 14, 14), Block.box(4, 14, 4, 12, 16, 12)); public static final VoxelShape DOWN_MODEL = diff --git a/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java b/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java index a231f953d..a16388fd0 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/event/RenderEventListener.java @@ -6,6 +6,7 @@ import dev.dubhe.anvilcraft.api.tooltip.HudTooltipManager; import dev.dubhe.anvilcraft.client.ModInspectionClient; import dev.dubhe.anvilcraft.client.renderer.PowerGridRenderer; +import dev.dubhe.anvilcraft.client.renderer.RenderState; import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; import dev.dubhe.anvilcraft.item.IEngineerGoggles; import net.minecraft.client.DeltaTracker; diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java index 5292ab118..b3587b2be 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/RenderState.java @@ -2,6 +2,7 @@ import com.mojang.logging.LogUtils; import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.integration.iris.IrisState; import lombok.Getter; import net.minecraft.client.Minecraft; import net.neoforged.fml.ModList; @@ -30,7 +31,7 @@ public static void levelStage(){ } public static boolean isEnhancedRenderingAvailable() { - return !Minecraft.useShaderTransparency(); + return !Minecraft.useShaderTransparency() && !IrisState.isShaderEnabled(); } public static boolean isBloomEffectEnabled(){ diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/LaserBlockRenderer.java similarity index 93% rename from src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/LaserRenderer.java rename to src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/LaserBlockRenderer.java index 6591145cf..36760c9de 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/blockentity/LaserBlockRenderer.java @@ -19,10 +19,10 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class LaserRenderer implements BlockEntityRenderer { +public class LaserBlockRenderer implements BlockEntityRenderer { @SuppressWarnings("unused") - public LaserRenderer(BlockEntityRendererProvider.Context context) { + public LaserBlockRenderer(BlockEntityRendererProvider.Context context) { } @Override diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index 405a3fb53..0b93784e3 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -44,6 +44,10 @@ public class LaserRenderer { RenderType.solid(), ModRenderTypes.LASER }; + + public static final RenderType[] BLOOM_RENDERTYPES = new RenderType[]{ + ModRenderTypes.LASER + }; private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false); private final Queue pendingUploads = new ConcurrentLinkedDeque<>(); @@ -92,12 +96,21 @@ public void releaseBuffers() { valid = false; } + public void blockRemoved(LaserStateAccess laserStateAccess) { + if (lastRebuildTask != null) { + lastRebuildTask.cancel(); + } + laserBlockEntities.remove(laserStateAccess); + compileQueue.add(new RebuildTask()); + } + public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { if (lastRebuildTask != null) { lastRebuildTask.cancel(); } if (baseLaserBlockEntity.removed()) { laserBlockEntities.remove(baseLaserBlockEntity); + laserBlockEntities.removeIf(LaserStateAccess::removed); compileQueue.add(new RebuildTask()); return; } @@ -106,6 +119,17 @@ public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { compileQueue.add(new RebuildTask()); } + public void renderBloomed(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { + if (isEmpty) return; + Window window = Minecraft.getInstance().getWindow(); + Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); + for (RenderType bloomRendertype : BLOOM_RENDERTYPES) { + VertexBuffer vb = buffers.get(bloomRendertype); + RenderState.bloomStage(); + renderLayer(bloomRendertype, vb, frustumMatrix, projectionMatrix, cameraPosition, window); + } + } + public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { RenderSystem.enableBlend(); if (isEmpty) return; @@ -113,13 +137,7 @@ public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); for (RenderType renderType : SUPPORTED_RENDERTYPES) { VertexBuffer vb = buffers.get(renderType); - if (renderType == ModRenderTypes.LASER) { - RenderState.levelStage(); - renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); - RenderState.bloomStage(); - renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); - continue; - } + RenderState.levelStage(); renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); } } @@ -188,7 +206,7 @@ public void run() { pos.getZ() ); LaserState laserState = LaserState.create(laserBlockEntity, poseStack); - if (laserState != null) { + if (laserState != null && laserState.laserLevel() > 0) { float width = LaserCompiler.laserWidth(laserState); LaserCompiler.compileStage( laserState, diff --git a/src/main/java/dev/dubhe/anvilcraft/init/ModBlockEntities.java b/src/main/java/dev/dubhe/anvilcraft/init/ModBlockEntities.java index 6dce18e7f..ed455e62c 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/ModBlockEntities.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/ModBlockEntities.java @@ -32,7 +32,7 @@ import dev.dubhe.anvilcraft.client.renderer.blockentity.CreativeGeneratorRenderer; import dev.dubhe.anvilcraft.client.renderer.blockentity.HasMobBlockRenderer; import dev.dubhe.anvilcraft.client.renderer.blockentity.HeliostatsRenderer; -import dev.dubhe.anvilcraft.client.renderer.blockentity.LaserRenderer; +import dev.dubhe.anvilcraft.client.renderer.blockentity.LaserBlockRenderer; import com.tterrag.registrate.util.entry.BlockEntityEntry; @@ -150,12 +150,12 @@ public class ModBlockEntities { public static final BlockEntityEntry RUBY_PRISM = REGISTRATE .blockEntity("ruby_prism", RubyPrismBlockEntity::createBlockEntity) .validBlock(ModBlocks.RUBY_PRISM) - .renderer(() -> LaserRenderer::new) + .renderer(() -> LaserBlockRenderer::new) .register(); public static final BlockEntityEntry RUBY_LASER = REGISTRATE .blockEntity("ruby_laser", RubyLaserBlockEntity::createBlockEntity) .validBlock(ModBlocks.RUBY_LASER) - .renderer(() -> LaserRenderer::new) + .renderer(() -> LaserBlockRenderer::new) .register(); public static final BlockEntityEntry THERMOELECTRIC_CONVERTER = REGISTRATE diff --git a/src/main/java/dev/dubhe/anvilcraft/integration/iris/IrisState.java b/src/main/java/dev/dubhe/anvilcraft/integration/iris/IrisState.java index 35f90bff0..12f1ddaf4 100644 --- a/src/main/java/dev/dubhe/anvilcraft/integration/iris/IrisState.java +++ b/src/main/java/dev/dubhe/anvilcraft/integration/iris/IrisState.java @@ -7,7 +7,7 @@ public class IrisState { public static boolean isShaderEnabled() { - if (RenderState.isIrisPresent()){ + if (RenderState.isIrisPresent()) { return isShaderEnabledInternal(); } return false; diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelChunkMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelChunkMixin.java new file mode 100644 index 000000000..3f0a89c9d --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelChunkMixin.java @@ -0,0 +1,29 @@ +package dev.dubhe.anvilcraft.mixin; + +import dev.dubhe.anvilcraft.api.LaserStateAccess; +import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.chunk.LevelChunk; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import javax.annotation.Nullable; + +@Mixin(LevelChunk.class) +public abstract class LevelChunkMixin { + @Shadow + @Nullable + public abstract BlockEntity getBlockEntity(BlockPos pos); + + @Inject(method = "removeBlockEntity", at = @At("HEAD")) + void onBlockEntityRemoved(BlockPos pos, CallbackInfo ci) { + BlockEntity be = getBlockEntity(pos); + if (be instanceof LaserStateAccess laserStateAccess) { + LaserRenderer.getInstance().blockRemoved(laserStateAccess); + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 0a1d9134c..0b84343fb 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -25,7 +25,6 @@ import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; @@ -38,9 +37,6 @@ @Mixin(LevelRenderer.class) public abstract class LevelRendererMixin { - @Shadow - protected abstract void renderSectionLayer(RenderType renderType, double x, double y, double z, Matrix4f frustrumMatrix, Matrix4f projectionMatrix); - @Shadow @Final private Minecraft minecraft; @@ -49,8 +45,7 @@ public abstract class LevelRendererMixin { method = "renderLevel", at = @At( value = "INVOKE", - shift = At.Shift.AFTER, - target = "Lnet/minecraft/client/Options;getCloudsType()Lnet/minecraft/client/CloudStatus;" + target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;" ) ) void renderEnhancedTransmitterLines( @@ -71,6 +66,7 @@ void renderEnhancedTransmitterLines( bufferSource, camera.getPosition() ); + LaserRenderer.getInstance().render(frustumMatrix, projectionMatrix); } } @@ -81,7 +77,7 @@ void renderEnhancedTransmitterLines( target = "Lnet/minecraft/client/renderer/LevelRenderer;compileSections(Lnet/minecraft/client/Camera;)V" ) ) - void uploadBuffers(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f frustumMatrix, Matrix4f projectionMatrix, CallbackInfo ci){ + void uploadBuffers(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f frustumMatrix, Matrix4f projectionMatrix, CallbackInfo ci) { LaserRenderer.getInstance().runTasks(); } @@ -105,8 +101,11 @@ void bloomPostProcess( CallbackInfo ci ) { if (!RenderState.isEnhancedRenderingAvailable()) return; - LaserRenderer.getInstance().render(frustumMatrix, projectionMatrix); if (!RenderState.isBloomEffectEnabled()) return; + if (ModRenderTargets.getBloomTarget() != null) { + ModRenderTargets.getBloomTarget().copyDepthFrom(Minecraft.getInstance().getMainRenderTarget()); + } + LaserRenderer.getInstance().renderBloomed(frustumMatrix, projectionMatrix); RenderTarget mcInput = ModShaders.getBloomChain().getTempTarget("mcinput"); mcInput.setClearColor(0, 0, 0, 0); mcInput.clear(Minecraft.ON_OSX); diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java deleted file mode 100644 index 96275c283..000000000 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/RenderSystemMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package dev.dubhe.anvilcraft.mixin; - -import com.mojang.blaze3d.systems.RenderSystem; -import dev.dubhe.anvilcraft.client.renderer.laser.LaserRenderer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(RenderSystem.class) -public class RenderSystemMixin { - @Inject( - method = "flipFrame", - at = @At( - value = "INVOKE", - target = "Lcom/mojang/blaze3d/vertex/Tesselator;clear()V" - ) - ) - private static void clearBuffers(long windowId, CallbackInfo ci){ - if (LaserRenderer.getInstance() != null) { - LaserRenderer.getInstance().clear(); - } - } -} diff --git a/src/main/resources/anvilcraft.mixins.json b/src/main/resources/anvilcraft.mixins.json index fc4ffb8ad..76c81fcf0 100644 --- a/src/main/resources/anvilcraft.mixins.json +++ b/src/main/resources/anvilcraft.mixins.json @@ -38,7 +38,6 @@ "LevelRendererMixin", "MinecraftClientMixin", "MouseHandlerMixin", - "RenderSystemMixin", "RenderTypeMixin", "SectionCompilerMixin", "SoundEngineMixin", @@ -47,7 +46,8 @@ "compat.EmbeddiumDefaultTerrainRenderPassesMixin", "compat.SodiumChunkBuilderMeshingTaskMixin", "compat.SodiumDefaultMaterialsMixin", - "compat.SodiumDefaultTerrainRenderPassesMixin" + "compat.SodiumDefaultTerrainRenderPassesMixin", + "LevelChunkMixin" ], "plugin": "dev.dubhe.anvilcraft.mixin.plugin.AnvilCraftMixinPlugin", "injectors": { From d7609de711c10850fd1e4f1a91f27dfd13e45ab0 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Fri, 20 Dec 2024 23:22:41 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=BF=80=E5=85=89=E5=88=86=E5=8C=BA?= =?UTF-8?q?=E5=9D=97=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/renderer/laser/LaserRenderer.java | 189 +++++++++++------- .../anvilcraft/mixin/LevelRendererMixin.java | 4 +- 2 files changed, 118 insertions(+), 75 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index 0b93784e3..f250f0c24 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -4,15 +4,12 @@ import com.mojang.blaze3d.shaders.Uniform; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexBuffer; import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.blaze3d.vertex.VertexSorting; import dev.dubhe.anvilcraft.api.LaserStateAccess; -import dev.dubhe.anvilcraft.client.init.ModRenderTargets; import dev.dubhe.anvilcraft.client.init.ModRenderTypes; import dev.dubhe.anvilcraft.client.renderer.RenderState; import lombok.EqualsAndHashCode; @@ -22,7 +19,9 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.phys.Vec3; +import org.apache.commons.compress.utils.Lists; import org.joml.Matrix4f; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15C; @@ -32,6 +31,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; @@ -54,13 +54,9 @@ public class LaserRenderer { private final Queue compileQueue = new ConcurrentLinkedDeque<>(); @Getter private static LaserRenderer instance; - private final Map buffers = Arrays.stream(SUPPORTED_RENDERTYPES) - .collect(Collectors.toMap( - Function.identity(), - it -> new VertexBuffer(VertexBuffer.Usage.STATIC) - )); - private Map compileResultMap = new HashMap<>(); + private final Map> buffers = new HashMap<>(); + private Map> compileResultMap = new HashMap<>(); @SuppressWarnings("unused") private final ClientLevel level; @@ -90,9 +86,22 @@ public void runTasks() { } } + private Map getBufferForChunk(ChunkPos chunkPos) { + if (buffers.containsKey(chunkPos)) { + return buffers.get(chunkPos); + } + Map vb = Arrays.stream(SUPPORTED_RENDERTYPES) + .collect(Collectors.toMap( + Function.identity(), + it -> new VertexBuffer(VertexBuffer.Usage.STATIC) + )); + buffers.put(chunkPos, vb); + return vb; + } + public void releaseBuffers() { - buffers.values().forEach(VertexBuffer::close); - compileResultMap.values().forEach(CompileResult::free); + buffers.values().forEach(it -> it.values().forEach(VertexBuffer::close)); + compileResultMap.values().forEach(it -> it.values().forEach(CompileResult::free)); valid = false; } @@ -123,10 +132,20 @@ public void renderBloomed(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { if (isEmpty) return; Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); - for (RenderType bloomRendertype : BLOOM_RENDERTYPES) { - VertexBuffer vb = buffers.get(bloomRendertype); - RenderState.bloomStage(); - renderLayer(bloomRendertype, vb, frustumMatrix, projectionMatrix, cameraPosition, window); + for (Map.Entry> chunkPosMapEntry : buffers.entrySet()) { + ChunkPos chunkPos = chunkPosMapEntry.getKey(); + int renderDistance = Minecraft.getInstance().options.getEffectiveRenderDistance() * 16; + if (cameraPosition.distanceTo(new Vec3(chunkPos.x * 16, cameraPosition.y, chunkPos.z * 16)) > renderDistance) { + continue; + } + Map bufferMap = chunkPosMapEntry.getValue(); + Map compileResultMap = this.compileResultMap.get(chunkPos); + if (compileResultMap == null) continue; + for (RenderType bloomRendertype : BLOOM_RENDERTYPES) { + VertexBuffer vb = bufferMap.get(bloomRendertype); + RenderState.bloomStage(); + renderLayer(bloomRendertype, vb, frustumMatrix, projectionMatrix, cameraPosition, window, compileResultMap); + } } } @@ -135,10 +154,20 @@ public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { if (isEmpty) return; Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); - for (RenderType renderType : SUPPORTED_RENDERTYPES) { - VertexBuffer vb = buffers.get(renderType); - RenderState.levelStage(); - renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); + for (Map.Entry> chunkPosMapEntry : buffers.entrySet()) { + ChunkPos chunkPos = chunkPosMapEntry.getKey(); + int renderDistance = Minecraft.getInstance().options.getEffectiveRenderDistance() * 16; + if (cameraPosition.distanceTo(new Vec3(chunkPos.x * 16, cameraPosition.y, chunkPos.z * 16)) > renderDistance) { + continue; + } + Map bufferMap = chunkPosMapEntry.getValue(); + Map compileResultMap = this.compileResultMap.get(chunkPos); + if (compileResultMap == null) continue; + for (RenderType renderType : SUPPORTED_RENDERTYPES) { + VertexBuffer vb = bufferMap.get(renderType); + RenderState.levelStage(); + renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window, compileResultMap); + } } } @@ -148,7 +177,8 @@ private void renderLayer( Matrix4f frustumMatrix, Matrix4f projectionMatrix, Vec3 cameraPosition, - Window window + Window window, + Map compileResultMap ) { CompileResult compileResult = compileResultMap.get(renderType); renderType.setupRenderState(); @@ -173,11 +203,6 @@ private void renderLayer( renderType.clearRenderState(); } - private VertexSorting createVertexSorting() { - Vec3 cameraPos = minecraft.gameRenderer.getMainCamera().getPosition(); - return VertexSorting.byDistance(cameraPos.toVector3f()); - } - public void clear() { } @@ -187,63 +212,79 @@ private class RebuildTask implements Runnable { @Override public void run() { lastRebuildTask = this; - Map compileResultMap = new HashMap<>(); + Map> compileResultMap = new HashMap<>(); PoseStack poseStack = new PoseStack(); LaserRenderer.this.isEmpty = true; - for (RenderType renderType : SUPPORTED_RENDERTYPES) { - if (cancelled) return; - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder bufferBuilder = tesselator.begin(renderType.mode, renderType.format); - long ptr = tesselator.buffer.pointer; - int offsetBeforeCompile = tesselator.buffer.writeOffset; - for (LaserStateAccess laserBlockEntity : new ArrayList<>(laserBlockEntities)) { + Map> groupedLaserStates = new HashMap<>(); + for (LaserStateAccess laserBlockEntity : laserBlockEntities) { + groupedLaserStates.computeIfAbsent(new ChunkPos(laserBlockEntity.getBlockPos()), it -> Lists.newArrayList()) + .add(laserBlockEntity); + } + for (Map.Entry> chunkPosListEntry : groupedLaserStates.entrySet()) { + ChunkPos chunkPos = chunkPosListEntry.getKey(); + List group = chunkPosListEntry.getValue(); + for (RenderType renderType : SUPPORTED_RENDERTYPES) { if (cancelled) return; - poseStack.pushPose(); - BlockPos pos = laserBlockEntity.getBlockPos(); - poseStack.translate( - pos.getX(), - pos.getY(), - pos.getZ() - ); - LaserState laserState = LaserState.create(laserBlockEntity, poseStack); - if (laserState != null && laserState.laserLevel() > 0) { - float width = LaserCompiler.laserWidth(laserState); - LaserCompiler.compileStage( - laserState, - bufferBuilder, - renderType, - width + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder bufferBuilder = tesselator.begin(renderType.mode, renderType.format); + long ptr = tesselator.buffer.pointer; + int offsetBeforeCompile = tesselator.buffer.writeOffset; + for (LaserStateAccess laserBlockEntity : new ArrayList<>(group)) { + if (cancelled) return; + poseStack.pushPose(); + BlockPos pos = laserBlockEntity.getBlockPos(); + poseStack.translate( + pos.getX(), + pos.getY(), + pos.getZ() ); + LaserState laserState = LaserState.create(laserBlockEntity, poseStack); + if (laserState != null && laserState.laserLevel() > 0) { + float width = LaserCompiler.laserWidth(laserState); + LaserCompiler.compileStage( + laserState, + bufferBuilder, + renderType, + width + ); + } + poseStack.popPose(); } - poseStack.popPose(); - } - if (bufferBuilder.vertices > 0) { - LaserRenderer.this.isEmpty = false; - } - int compiledVertices = bufferBuilder.vertices * bufferBuilder.format.getVertexSize(); - long allocated = ALLOCATOR.malloc(compiledVertices); - MemoryUtil.memCopy(ptr + offsetBeforeCompile, allocated, compiledVertices); - MeshData mesh = bufferBuilder.build(); - if (mesh != null) { - mesh.close(); + if (bufferBuilder.vertices > 0) { + LaserRenderer.this.isEmpty = false; + } + int compiledVertices = bufferBuilder.vertices * bufferBuilder.format.getVertexSize(); + long allocated = ALLOCATOR.malloc(compiledVertices); + MemoryUtil.memCopy(ptr + offsetBeforeCompile, allocated, compiledVertices); + MeshData mesh = bufferBuilder.build(); + if (mesh != null) { + mesh.close(); + } + CompileResult compileResult = new CompileResult( + renderType, + bufferBuilder.vertices, + bufferBuilder.format.getVertexSize(), + allocated, + renderType.mode.indexCount(bufferBuilder.vertices) + ); + compileResultMap.computeIfAbsent(chunkPos, it -> new HashMap<>()) + .put(renderType, compileResult); } - CompileResult compileResult = new CompileResult( - renderType, - bufferBuilder.vertices, - bufferBuilder.format.getVertexSize(), - allocated, - renderType.mode.indexCount(bufferBuilder.vertices) - ); - compileResultMap.put(renderType, compileResult); } - LaserRenderer.this.compileResultMap.values().forEach(CompileResult::free); + + LaserRenderer.this.compileResultMap + .values() + .forEach(it -> it.values().forEach(CompileResult::free)); + LaserRenderer.this.compileResultMap = compileResultMap; - compileResultMap.forEach((renderType, compileResult) -> { - pendingUploads.add(() -> { - VertexBuffer vb = buffers.get(renderType); - compileResult.upload(vb); - }); - }); + compileResultMap.forEach((chunkPos, map) -> + map.forEach((renderType, compileResult) -> + pendingUploads.add(() -> { + VertexBuffer vb = getBufferForChunk(chunkPos).get(renderType); + compileResult.upload(vb); + }) + ) + ); lastRebuildTask = null; } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 0b84343fb..a920de142 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -45,7 +45,8 @@ public abstract class LevelRendererMixin { method = "renderLevel", at = @At( value = "INVOKE", - target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;" + target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", + ordinal = 2 ) ) void renderEnhancedTransmitterLines( @@ -105,6 +106,7 @@ void bloomPostProcess( if (ModRenderTargets.getBloomTarget() != null) { ModRenderTargets.getBloomTarget().copyDepthFrom(Minecraft.getInstance().getMainRenderTarget()); } + RenderSystem.enableDepthTest(); LaserRenderer.getInstance().renderBloomed(frustumMatrix, projectionMatrix); RenderTarget mcInput = ModShaders.getBloomChain().getTempTarget("mcinput"); mcInput.setClearColor(0, 0, 0, 0); From dc5d502db24befd5c8d2aac721c48b4e1033ec20 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Fri, 20 Dec 2024 23:35:36 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B7=B1=E5=BA=A6?= =?UTF-8?q?=E5=8D=87=E5=A4=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/renderer/laser/LaserRenderer.java | 32 +++++++------------ .../anvilcraft/mixin/LevelRendererMixin.java | 17 +++++----- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index f250f0c24..662e20d3e 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -129,27 +129,19 @@ public void requireRecompile(LaserStateAccess baseLaserBlockEntity) { } public void renderBloomed(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { - if (isEmpty) return; - Window window = Minecraft.getInstance().getWindow(); - Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); - for (Map.Entry> chunkPosMapEntry : buffers.entrySet()) { - ChunkPos chunkPos = chunkPosMapEntry.getKey(); - int renderDistance = Minecraft.getInstance().options.getEffectiveRenderDistance() * 16; - if (cameraPosition.distanceTo(new Vec3(chunkPos.x * 16, cameraPosition.y, chunkPos.z * 16)) > renderDistance) { - continue; - } - Map bufferMap = chunkPosMapEntry.getValue(); - Map compileResultMap = this.compileResultMap.get(chunkPos); - if (compileResultMap == null) continue; - for (RenderType bloomRendertype : BLOOM_RENDERTYPES) { - VertexBuffer vb = bufferMap.get(bloomRendertype); - RenderState.bloomStage(); - renderLayer(bloomRendertype, vb, frustumMatrix, projectionMatrix, cameraPosition, window, compileResultMap); - } - } + renderInternal(frustumMatrix, projectionMatrix, BLOOM_RENDERTYPES, RenderState::bloomStage); } public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { + renderInternal(frustumMatrix, projectionMatrix, SUPPORTED_RENDERTYPES, RenderState::levelStage); + } + + private void renderInternal( + Matrix4f frustumMatrix, + Matrix4f projectionMatrix, + RenderType[] renderTypes, + Runnable stateSwitcher + ){ RenderSystem.enableBlend(); if (isEmpty) return; Window window = Minecraft.getInstance().getWindow(); @@ -163,9 +155,9 @@ public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { Map bufferMap = chunkPosMapEntry.getValue(); Map compileResultMap = this.compileResultMap.get(chunkPos); if (compileResultMap == null) continue; - for (RenderType renderType : SUPPORTED_RENDERTYPES) { + for (RenderType renderType : renderTypes) { VertexBuffer vb = bufferMap.get(renderType); - RenderState.levelStage(); + stateSwitcher.run(); renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window, compileResultMap); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index a920de142..fea60100c 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -49,7 +49,7 @@ public abstract class LevelRendererMixin { ordinal = 2 ) ) - void renderEnhancedTransmitterLines( + void renderLaserBeforeTerrain( DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, @@ -62,11 +62,6 @@ void renderEnhancedTransmitterLines( @Local(index = 25) MultiBufferSource.BufferSource bufferSource ) { if (RenderState.isEnhancedRenderingAvailable()) { - PowerGridRenderer.renderEnhancedTransmitterLine( - poseStack, - bufferSource, - camera.getPosition() - ); LaserRenderer.getInstance().render(frustumMatrix, projectionMatrix); } } @@ -99,14 +94,20 @@ void bloomPostProcess( LightTexture lightTexture, Matrix4f frustumMatrix, Matrix4f projectionMatrix, - CallbackInfo ci + CallbackInfo ci, + @Local(index = 24) PoseStack poseStack, + @Local(index = 25) MultiBufferSource.BufferSource bufferSource ) { if (!RenderState.isEnhancedRenderingAvailable()) return; if (!RenderState.isBloomEffectEnabled()) return; if (ModRenderTargets.getBloomTarget() != null) { ModRenderTargets.getBloomTarget().copyDepthFrom(Minecraft.getInstance().getMainRenderTarget()); } - RenderSystem.enableDepthTest(); + PowerGridRenderer.renderEnhancedTransmitterLine( + poseStack, + bufferSource, + camera.getPosition() + ); LaserRenderer.getInstance().renderBloomed(frustumMatrix, projectionMatrix); RenderTarget mcInput = ModShaders.getBloomChain().getTempTarget("mcinput"); mcInput.setClearColor(0, 0, 0, 0);