99import com .mojang .blaze3d .buffers .GpuBufferSlice ;
1010import it .unimi .dsi .fastutil .Stack ;
1111import it .unimi .dsi .fastutil .objects .ObjectArrayList ;
12+ import meteordevelopment .meteorclient .mixininterface .IEntityRenderState ;
1213import meteordevelopment .meteorclient .mixininterface .IWorldRenderer ;
1314import meteordevelopment .meteorclient .systems .modules .Modules ;
1415import meteordevelopment .meteorclient .systems .modules .render .BlockSelection ;
16+ import meteordevelopment .meteorclient .systems .modules .render .ESP ;
1517import meteordevelopment .meteorclient .systems .modules .render .Freecam ;
1618import meteordevelopment .meteorclient .systems .modules .render .NoRender ;
19+ import meteordevelopment .meteorclient .utils .OutlineRenderCommandQueue ;
20+ import meteordevelopment .meteorclient .utils .render .NoopImmediateVertexConsumerProvider ;
21+ import meteordevelopment .meteorclient .utils .render .NoopOutlineVertexConsumerProvider ;
22+ import meteordevelopment .meteorclient .utils .render .WrapperImmediateVertexConsumerProvider ;
23+ import meteordevelopment .meteorclient .utils .render .color .Color ;
24+ import meteordevelopment .meteorclient .utils .render .postprocess .EntityShader ;
1725import meteordevelopment .meteorclient .utils .render .postprocess .PostProcessShaders ;
1826import net .minecraft .client .gl .Framebuffer ;
1927import net .minecraft .client .render .*;
28+ import net .minecraft .client .render .command .OrderedRenderCommandQueue ;
29+ import net .minecraft .client .render .command .RenderDispatcher ;
30+ import net .minecraft .client .render .entity .EntityRenderManager ;
2031import net .minecraft .client .render .state .OutlineRenderState ;
2132import net .minecraft .client .render .state .WeatherRenderState ;
2233import net .minecraft .client .render .state .WorldBorderRenderState ;
34+ import net .minecraft .client .render .state .WorldRenderState ;
2335import net .minecraft .client .util .Handle ;
2436import net .minecraft .client .util .ObjectAllocator ;
2537import net .minecraft .client .util .math .MatrixStack ;
38+ import net .minecraft .entity .Entity ;
2639import net .minecraft .util .math .Vec3d ;
2740import org .joml .Matrix4f ;
2841import org .joml .Vector4f ;
3649import org .spongepowered .asm .mixin .injection .callback .CallbackInfo ;
3750import org .spongepowered .asm .mixin .injection .callback .CallbackInfoReturnable ;
3851
52+ import java .util .function .Function ;
53+
54+ import static meteordevelopment .meteorclient .MeteorClient .mc ;
55+
3956@ Mixin (WorldRenderer .class )
4057public abstract class WorldRendererMixin implements IWorldRenderer {
4158 @ Inject (method = "checkEmpty" , at = @ At ("HEAD" ), cancellable = true )
@@ -87,31 +104,68 @@ private void onRenderHead(ObjectAllocator allocator,
87104 PostProcessShaders .beginRender ();
88105 }
89106
90- /*
91- todo Entity rendering is batched in pushEntityRenders before they are all rendered at once by calling
92- net.minecraft.client.render.entity.command.EntityRenderDispatcher.render
93- Our renders need to be rewritten
107+ @ Unique
108+ private final OutlineRenderCommandQueue outlineRenderCommandQueue = new OutlineRenderCommandQueue ();
109+
110+ @ Unique
111+ private VertexConsumerProvider provider ;
94112
95- @Inject(method = "renderEntity", at = @At("HEAD"))
96- private void renderEntity(Entity entity, double cameraX, double cameraY, double cameraZ, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo info) {
97- draw(entity, cameraX, cameraY, cameraZ, tickDelta, vertexConsumers, matrices, PostProcessShaders.CHAMS, Color.WHITE);
98- draw(entity, cameraX, cameraY, cameraZ, tickDelta, vertexConsumers, matrices, PostProcessShaders.ENTITY_OUTLINE, Modules.get().get(ESP.class).getColor(entity));
113+ @ Unique
114+ private RenderDispatcher renderDispatcher ;
115+
116+ @ Inject (method = "pushEntityRenders" , at = @ At ("TAIL" ))
117+ private void onPushEntityRenders (MatrixStack matrices , WorldRenderState worldState , OrderedRenderCommandQueue queue , CallbackInfo info ) {
118+ if (renderDispatcher == null ) {
119+ renderDispatcher = new RenderDispatcher (
120+ outlineRenderCommandQueue ,
121+ mc .getBlockRenderManager (),
122+ new WrapperImmediateVertexConsumerProvider (() -> provider ),
123+ mc .getAtlasManager (),
124+ NoopOutlineVertexConsumerProvider .INSTANCE ,
125+ NoopImmediateVertexConsumerProvider .INSTANCE ,
126+ mc .textRenderer
127+ );
128+ }
129+
130+ draw (worldState , matrices , PostProcessShaders .CHAMS , entity -> Color .WHITE );
131+ draw (worldState , matrices , PostProcessShaders .ENTITY_OUTLINE , entity -> Modules .get ().get (ESP .class ).getColor (entity ));
99132 }
100133
101134 @ Unique
102- private void draw(Entity entity, double cameraX, double cameraY, double cameraZ, float tickDelta, VertexConsumerProvider vertexConsumers, MatrixStack matrices, EntityShader shader, Color color) {
103- if (shader.shouldDraw(entity) && !PostProcessShaders.isCustom(vertexConsumers) && color != null) {
104- meteor$pushEntityOutlineFramebuffer(shader.framebuffer);
105- PostProcessShaders.rendering = true;
135+ private void draw (WorldRenderState worldState , MatrixStack matrices , EntityShader shader , Function <Entity , Color > colorGetter ) {
136+ var camera = worldState .cameraRenderState .pos ;
137+ var empty = true ;
138+
139+ for (var state : worldState .entityRenderStates ) {
140+ if (!shader .shouldDraw (((IEntityRenderState ) state ).meteor$getEntity ())) continue ;
106141
107- shader.vertexConsumerProvider.setColor(color.getPacked());
108- renderEntity(entity, cameraX, cameraY, cameraZ, tickDelta, matrices, shader.vertexConsumerProvider);
142+ var color = colorGetter .apply (((IEntityRenderState ) state ).meteor$getEntity ());
143+ if (color == null ) continue ;
144+ outlineRenderCommandQueue .setColor (color );
109145
110- PostProcessShaders.rendering = false;
111- meteor$popEntityOutlineFramebuffer();
146+ var renderer = entityRenderManager .getRenderer (state );
147+ var offset = renderer .getPositionOffset (state );
148+
149+ matrices .push ();
150+ matrices .translate (state .x - camera .x + offset .x , state .y - camera .y + offset .y , state .z - camera .z + offset .z );
151+ renderer .render (state , matrices , outlineRenderCommandQueue , worldState .cameraRenderState );
152+ matrices .pop ();
153+
154+ empty = false ;
112155 }
156+
157+ if (empty )
158+ return ;
159+
160+ meteor$pushEntityOutlineFramebuffer (shader .framebuffer );
161+ provider = shader .vertexConsumerProvider ;
162+
163+ renderDispatcher .render ();
164+ outlineRenderCommandQueue .onNextFrame ();
165+
166+ provider = null ;
167+ meteor$popEntityOutlineFramebuffer ();
113168 }
114- */
115169
116170 @ Inject (method = "method_62214" , at = @ At (value = "INVOKE" , target = "Lnet/minecraft/client/render/OutlineVertexConsumerProvider;draw()V" ))
117171 private void onRender (CallbackInfo ci ) {
@@ -132,6 +186,9 @@ private void onResized(int width, int height, CallbackInfo info) {
132186 @ Final
133187 private DefaultFramebufferSet framebufferSet ;
134188
189+ @ Shadow
190+ @ Final
191+ private EntityRenderManager entityRenderManager ;
135192 @ Unique
136193 private Stack <Framebuffer > framebufferStack ;
137194
0 commit comments