9393import net .neoforged .neoforge .common .util .Lazy ;
9494import net .neoforged .neoforge .event .TickEvent .ClientTickEvent ;
9595import net .neoforged .neoforge .event .TickEvent .Phase ;
96+ import org .jetbrains .annotations .NotNull ;
9697import org .jetbrains .annotations .Nullable ;
9798import org .joml .Matrix4f ;
9899import org .joml .Vector3f ;
@@ -104,7 +105,7 @@ public class RenderTickHandler {
104105
105106 private static final Map <BlockState , List <Vertex []>> cachedWireFrames = new HashMap <>();
106107 private static final Map <Direction , Map <TransmissionType , Model3D >> cachedOverlays = new EnumMap <>(Direction .class );
107- private static final Map < RenderType , List <LazyRender >> transparentRenderers = new HashMap <>();
108+ private static final List <LazyRender > transparentRenderers = new ArrayList <>();
108109 private static final BoltRenderer boltRenderer = new BoltRenderer ();
109110
110111 private boolean outliningArea = false ;
@@ -144,8 +145,8 @@ public static void guiOpening(ScreenEvent.Opening event) {
144145 }
145146 }
146147
147- public static void addTransparentRenderer (RenderType renderType , LazyRender render ) {
148- transparentRenderers .computeIfAbsent ( renderType , r -> new ArrayList <>()). add (render );
148+ public static void addTransparentRenderer (LazyRender render ) {
149+ transparentRenderers .add (render );
149150 }
150151
151152 @ SubscribeEvent
@@ -162,31 +163,19 @@ public void renderWorld(RenderLevelStageEvent event) {
162163 profiler .push (ProfilerConstants .DELAYED );
163164 if (transparentRenderers .size () == 1 ) {
164165 //If we only have one render type we don't need to bother calculating any distances
165- for (Entry <RenderType , List <LazyRender >> entry : transparentRenderers .entrySet ()) {
166- doTransparentRender (entry .getKey (), entry .getValue (), camera , renderer , poseStack , renderTick , partialTick , profiler );
167- }
166+ LazyRender lazyRender = transparentRenderers .get (0 );
167+ doTransparentRender (lazyRender .getRenderType (), lazyRender , camera , renderer , poseStack , renderTick , partialTick , profiler );
168168 } else {
169- List <TransparentRenderInfo > toSort = new ArrayList <>(transparentRenderers .size ());
170- for (Entry <RenderType , List <LazyRender >> renderTypeListEntry : transparentRenderers .entrySet ()) {
171- List <LazyRender > renders = renderTypeListEntry .getValue ();
172- double closest = Double .MAX_VALUE ;
173- for (LazyRender render : renders ) {
174- Vec3 renderPos = render .getCenterPos (partialTick );
175- if (renderPos != null ) {
176- //Note: We can just use the distance sqr as we use it for both things, so they compare the same anyway
177- double distanceSqr = camera .getPosition ().distanceToSqr (renderPos );
178- if (distanceSqr < closest ) {
179- closest = distanceSqr ;
180- }
181- }
182- }
183- //Note: we remap it in order to keep track of the closest distance so that we only have to calculate it once
184- toSort .add (new TransparentRenderInfo (renderTypeListEntry .getKey (), renders , closest ));
169+
170+ for (LazyRender render : transparentRenderers ) {
171+ Vec3 renderPos = render .getCenterPos (partialTick );
172+ //Note: We can just use the distance sqr as we use it for both things, so they compare the same anyway
173+ render .distance = camera .getPosition ().distanceToSqr (renderPos );
185174 }
186175 //Sort in the order of furthest to closest (reverse of by closest)
187- toSort .sort (Comparator .comparingDouble (info -> -info .closest ));
188- for (TransparentRenderInfo apply : toSort ) {
189- apply . render ( camera , renderer , poseStack , renderTick , partialTick , profiler );
176+ transparentRenderers .sort (Comparator .comparingDouble (info -> -info .distance ));
177+ for (LazyRender render : transparentRenderers ) {
178+ doTransparentRender ( render . getRenderType (), render , camera , renderer , poseStack , renderTick , partialTick , profiler );
190179 }
191180 }
192181 transparentRenderers .clear ();
@@ -541,41 +530,32 @@ private Model3D getOverlayModel(Direction side, TransmissionType type) {
541530 return model ;
542531 }
543532
544- public interface LazyRender {
533+ public static abstract class LazyRender {
545534
546- void render ( Camera camera , VertexConsumer buffer , PoseStack poseStack , int renderTick , float partialTick , ProfilerFiller profiler ) ;
535+ public double distance ;
547536
548- @ Nullable
549- default Vec3 getCenterPos (float partialTick ) {
550- return null ;
551- }
537+ public abstract void render (Camera camera , VertexConsumer buffer , PoseStack poseStack , int renderTick , float partialTick , ProfilerFiller profiler );
552538
553- @ Nullable
554- default String getProfilerSection () {
555- return null ;
556- }
557- }
539+ @ NotNull
540+ public abstract Vec3 getCenterPos (float partialTick );
558541
559- private record TransparentRenderInfo (RenderType renderType , List <LazyRender > renders , double closest ) {
560- private void render (Camera camera , MultiBufferSource .BufferSource renderer , PoseStack poseStack , int renderTick , float partialTick , ProfilerFiller profiler ) {
561- doTransparentRender (renderType , renders , camera , renderer , poseStack , renderTick , partialTick , profiler );
562- }
542+ @ NotNull
543+ public abstract String getProfilerSection ();
544+
545+ @ NotNull
546+ public abstract RenderType getRenderType ();
563547 }
564548
565- private static void doTransparentRender (RenderType renderType , List < LazyRender > renders , Camera camera , BufferSource renderer , PoseStack poseStack , int renderTick , float partialTick , ProfilerFiller profiler ) {
549+ private static void doTransparentRender (RenderType renderType , LazyRender transparentRender , Camera camera , BufferSource renderer , PoseStack poseStack , int renderTick , float partialTick , ProfilerFiller profiler ) {
566550 //Batch all renders for a single render type into a single buffer addition
567551 VertexConsumer buffer = renderer .getBuffer (renderType );
568- for (LazyRender transparentRender : renders ) {
569- String profilerSection = transparentRender .getProfilerSection ();
570- if (profilerSection != null ) {
571- profiler .push (profilerSection );
572- }
573- //Note: We don't bother sorting renders in a specific render type as we assume the render type has sortOnUpload as true
574- transparentRender .render (camera , buffer , poseStack , renderTick , partialTick , profiler );
575- if (profilerSection != null ) {
576- profiler .pop ();
577- }
578- }
552+
553+ String profilerSection = transparentRender .getProfilerSection ();
554+ profiler .push (profilerSection );
555+ //Note: We don't bother sorting renders in a specific render type as we assume the render type has sortOnUpload as true
556+ transparentRender .render (camera , buffer , poseStack , renderTick , partialTick , profiler );
557+ profiler .pop ();
558+
579559 renderer .endBatch (renderType );
580560 }
581561}
0 commit comments