ParticleFeatureRenderer.java

net.minecraft.client.renderer.feature.ParticleFeatureRenderer

信息

  • 全限定名:net.minecraft.client.renderer.feature.ParticleFeatureRenderer
  • 类型:public class
  • 包:net.minecraft.client.renderer.feature
  • 源码路径:src/main/java/net/minecraft/client/renderer/feature/ParticleFeatureRenderer.java
  • 起始行号:L28
  • 实现:AutoCloseable
  • 职责:

    TODO

字段/常量

  • availableBuffers

    • 类型: Queue<ParticleFeatureRenderer.ParticleBufferCache>
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

  • usedBuffers

    • 类型: List<ParticleFeatureRenderer.ParticleBufferCache>
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.feature.ParticleFeatureRenderer.ParticleBufferCache
    • 类型: class
    • 修饰符: public static
    • 源码定位: L100
    • 说明:

      TODO

构造器

方法

下面的方法块按源码顺序生成。

public void renderSolid(SubmitNodeCollection nodeCollection) @ L32

  • 方法名:renderSolid
  • 源码定位:L32
  • 返回类型:void
  • 修饰符:public

参数:

  • nodeCollection: SubmitNodeCollection

说明:

TODO

public void renderTranslucent(SubmitNodeCollection nodeCollection) @ L36

  • 方法名:renderTranslucent
  • 源码定位:L36
  • 返回类型:void
  • 修饰符:public

参数:

  • nodeCollection: SubmitNodeCollection

说明:

TODO

private void render(SubmitNodeCollection nodeCollection, boolean translucent) @ L40

  • 方法名:render
  • 源码定位:L40
  • 返回类型:void
  • 修饰符:private

参数:

  • nodeCollection: SubmitNodeCollection
  • translucent: boolean

说明:

TODO

public void endFrame() @ L79

  • 方法名:endFrame
  • 源码定位:L79
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private void prepareRenderPass(RenderPass renderPass) @ L88

  • 方法名:prepareRenderPass
  • 源码定位:L88
  • 返回类型:void
  • 修饰符:private

参数:

  • renderPass: RenderPass

说明:

TODO

public void close() @ L94

  • 方法名:close
  • 源码定位:L94
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class ParticleFeatureRenderer implements AutoCloseable {
    private final Queue<ParticleFeatureRenderer.ParticleBufferCache> availableBuffers = new ArrayDeque<>();
    private final List<ParticleFeatureRenderer.ParticleBufferCache> usedBuffers = new ArrayList<>();
 
    public void renderSolid(SubmitNodeCollection nodeCollection) {
        this.render(nodeCollection, false);
    }
 
    public void renderTranslucent(SubmitNodeCollection nodeCollection) {
        this.render(nodeCollection, true);
    }
 
    private void render(SubmitNodeCollection nodeCollection, boolean translucent) {
        if (!nodeCollection.getParticleGroupRenderers().isEmpty()) {
            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()) {
                if (!particleGroupRenderer.isEmpty()) {
                    ParticleFeatureRenderer.ParticleBufferCache buffer = this.availableBuffers.poll();
                    if (buffer == null) {
                        buffer = new ParticleFeatureRenderer.ParticleBufferCache();
                    }
 
                    this.usedBuffers.add(buffer);
                    QuadParticleRenderState.PreparedBuffers prepared = particleGroupRenderer.prepare(buffer, translucent);
                    if (prepared != null) {
                        boolean useParticleTarget = particleTarget != null && translucent;
                        GpuTextureView colorTextureView = useParticleTarget ? particleTarget.getColorTextureView() : mainTarget.getColorTextureView();
                        GpuTextureView depthTextureView = useParticleTarget ? particleTarget.getDepthTextureView() : mainTarget.getDepthTextureView();
 
                        try (RenderPass renderPass = device.createCommandEncoder()
                                .createRenderPass(
                                    () -> "Particles - " + (translucent ? "Translucent" : "Solid"),
                                    colorTextureView,
                                    OptionalInt.empty(),
                                    depthTextureView,
                                    OptionalDouble.empty()
                                )) {
                            this.prepareRenderPass(renderPass);
                            particleGroupRenderer.render(prepared, buffer, renderPass, textureManager);
                        }
                    }
                }
            }
        }
    }
 
    public void endFrame() {
        for (ParticleFeatureRenderer.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.lightmap(), RenderSystem.getSamplerCache().getClampToEdge(FilterMode.LINEAR));
    }
 
    @Override
    public void close() {
        this.availableBuffers.forEach(ParticleFeatureRenderer.ParticleBufferCache::close);
    }
 
    @OnlyIn(Dist.CLIENT)
    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");
            } else {
                return this.ringBuffer.currentBuffer();
            }
        }
 
        void rotate() {
            if (this.ringBuffer != null) {
                this.ringBuffer.rotate();
            }
        }
 
        @Override
        public void close() {
            if (this.ringBuffer != null) {
                this.ringBuffer.close();
            }
        }
    }
}

引用的其他类

  • RenderPass

    • 引用位置: 参数
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.getDevice(), RenderSystem.getProjectionMatrixBuffer(), RenderSystem.getSamplerCache(), RenderSystem.getShaderFog()
  • Minecraft

    • 引用位置: 方法调用
    • 关联成员: Minecraft.getInstance()
  • MappableRingBuffer

    • 引用位置: 构造调用
    • 关联成员: MappableRingBuffer()
  • SubmitNodeCollection

    • 引用位置: 参数