129 lines
5.3 KiB
Java
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|