Add support for custom particle render layers
ParticleTextureSheet defines the GL state particles are rendered under (it's basically an older and way more primitive version of RenderLayer for particles)
In ParticleManager.renderParticles, vanilla iterates over a final immutable list of layers, instead of using the Map<ParticleTextureSheet, Queue<Particle>>'s keyset (and skipping NO_RENDER)
It would be convenient for modders with custom particle render types (like Botania) if a mixin could be added to iterate over the keyset instead of the final immutable list. Such a mixin would be small and be the only fix that is needed, vanilla handles everything else already.
As for why this needs to be in FAPI:
- It's small
- All modders with custom particle GL state need it
- Multiple modders doing this same fix could be catastrophous (render particles multiple times)
- Adding to the final immutable list is dirty and inconvenient.
I can see the benefit of this. I would like to see RenderLayer abstracted just a little bit, perhaps with some kind of builder.
In your use case, are you using a custom RenderLayer or manipulating Gl state directly?
all particle render layers manipulate GL state directly (See implementations of ParticleTextureSheet in vanilla)
At the moment I do the same.
Fixing this issue is really just a matter of replacing the iterator in ParticleManager.renderParticles like this:
@Mixin(ParticleManager.class)
public class ParticleRenderFix {
@Final
@Shadow
private Map<ParticleTextureSheet, Queue<Particle>> particles;
@ModifyVariable(method="renderParticles", at=@At("STORE"), ordinal = 0)
private Iterator<ParticleTextureSheet> fixParticleTextureSheets(Iterator<ParticleTextureSheet> i){
return this.particles.keySet().stream().toList().iterator();
}
}
But I agree this should really just be part of the FAPI
Feel free to PR it. :)
5 years old and i still need it
It is not as simple as replacing the iterator as suggested because the map is unsorted and its key order is not guaranteed to match the vanilla order specified in PARTICLE_TEXTURE_SHEETS. NeoForge solves this by making the map sorted, but in such a way that the order of custom types is not deterministic between game startups and cannot be specified, which is not great in my opinion. Also, particles of the CUSTOM type are rendered separately after the for loop and particles of the NO_RENDER should not be rendered, so it is necessary to explicitly ignore these in the for loop if the keys are iterated over.