2025-11-24 22:52:51 +03:00

129 lines
5.3 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.jspecify.annotations.Nullable
*/
package net.minecraft.client.renderer.feature;
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.FilterMode;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.Queue;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MappableRingBuffer;
import net.minecraft.client.renderer.SubmitNodeCollection;
import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.state.QuadParticleRenderState;
import net.minecraft.client.renderer.texture.TextureManager;
import org.jspecify.annotations.Nullable;
public class ParticleFeatureRenderer
implements AutoCloseable {
private final Queue<ParticleBufferCache> availableBuffers = new ArrayDeque<ParticleBufferCache>();
private final List<ParticleBufferCache> usedBuffers = new ArrayList<ParticleBufferCache>();
public void render(SubmitNodeCollection nodeCollection) {
if (nodeCollection.getParticleGroupRenderers().isEmpty()) {
return;
}
GpuDevice device = RenderSystem.getDevice();
Minecraft minecraft = Minecraft.getInstance();
TextureManager textureManager = minecraft.getTextureManager();
RenderTarget mainTarget = minecraft.getMainRenderTarget();
RenderTarget particleTarget = minecraft.levelRenderer.getParticlesTarget();
for (SubmitNodeCollector.ParticleGroupRenderer particleGroupRenderer : nodeCollection.getParticleGroupRenderers()) {
ParticleBufferCache buffer = this.availableBuffers.poll();
if (buffer == null) {
buffer = new ParticleBufferCache();
}
this.usedBuffers.add(buffer);
QuadParticleRenderState.PreparedBuffers prepared = particleGroupRenderer.prepare(buffer);
if (prepared == null) continue;
try (RenderPass renderPass = device.createCommandEncoder().createRenderPass(() -> "Particles - Main", mainTarget.getColorTextureView(), OptionalInt.empty(), mainTarget.getDepthTextureView(), OptionalDouble.empty());){
this.prepareRenderPass(renderPass);
particleGroupRenderer.render(prepared, buffer, renderPass, textureManager, false);
if (particleTarget == null) {
particleGroupRenderer.render(prepared, buffer, renderPass, textureManager, true);
}
}
if (particleTarget == null) continue;
renderPass = device.createCommandEncoder().createRenderPass(() -> "Particles - Transparent", particleTarget.getColorTextureView(), OptionalInt.empty(), particleTarget.getDepthTextureView(), OptionalDouble.empty());
try {
this.prepareRenderPass(renderPass);
particleGroupRenderer.render(prepared, buffer, renderPass, textureManager, true);
}
finally {
if (renderPass == null) continue;
renderPass.close();
}
}
}
public void endFrame() {
for (ParticleBufferCache usedBuffer : this.usedBuffers) {
usedBuffer.rotate();
}
this.availableBuffers.addAll(this.usedBuffers);
this.usedBuffers.clear();
}
private void prepareRenderPass(RenderPass renderPass) {
renderPass.setUniform("Projection", RenderSystem.getProjectionMatrixBuffer());
renderPass.setUniform("Fog", RenderSystem.getShaderFog());
renderPass.bindTexture("Sampler2", Minecraft.getInstance().gameRenderer.lightTexture().getTextureView(), RenderSystem.getSamplerCache().getClampToEdge(FilterMode.LINEAR));
}
@Override
public void close() {
this.availableBuffers.forEach(ParticleBufferCache::close);
}
public static class ParticleBufferCache
implements AutoCloseable {
private @Nullable MappableRingBuffer ringBuffer;
public void write(ByteBuffer byteBuffer) {
if (this.ringBuffer == null || this.ringBuffer.size() < byteBuffer.remaining()) {
if (this.ringBuffer != null) {
this.ringBuffer.close();
}
this.ringBuffer = new MappableRingBuffer(() -> "Particle Vertices", 34, byteBuffer.remaining());
}
try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.ringBuffer.currentBuffer().slice(), false, true);){
view.data().put(byteBuffer);
}
}
public GpuBuffer get() {
if (this.ringBuffer == null) {
throw new IllegalStateException("Can't get buffer before it's made");
}
return this.ringBuffer.currentBuffer();
}
void rotate() {
if (this.ringBuffer != null) {
this.ringBuffer.rotate();
}
}
@Override
public void close() {
if (this.ringBuffer != null) {
this.ringBuffer.close();
}
}
}
}