Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
feb41ee
initial commit for render state data extraction pull request
Ramixin Mar 1, 2026
dab345e
Fixed EntityRendererMixin being a common mixin rather than client
Ramixin Mar 1, 2026
a66635a
Added game test for RenderStateDataExtractionRegistry
Ramixin Mar 1, 2026
b61fef4
26.1-snapshot-11 (#5240)
modmuss50 Mar 3, 2026
9451711
Bump version
modmuss50 Mar 3, 2026
1bd9c6c
Bump version
modmuss50 Mar 3, 2026
17d6d79
Fix opaque water by not overriding existing ChunkSectionLayer for flu…
modmuss50 Mar 5, 2026
b24f50f
Bump version
modmuss50 Mar 5, 2026
1e4130d
Pivoted to entity renderers
Ramixin Mar 8, 2026
5f74a07
Pivoted to events instead of registration (proof of concept)
Ramixin Mar 8, 2026
aac8b1d
Cleaned up
Ramixin Mar 8, 2026
fa98c24
House cleaning
Ramixin Mar 8, 2026
273e35e
initial commit for render state data extraction pull request
Ramixin Mar 1, 2026
01cf6f4
Fixed EntityRendererMixin being a common mixin rather than client
Ramixin Mar 1, 2026
f34be3f
Added game test for RenderStateDataExtractionRegistry
Ramixin Mar 1, 2026
e55b6c5
Pivoted to entity renderers
Ramixin Mar 8, 2026
6aafd40
Pivoted to events instead of registration (proof of concept)
Ramixin Mar 8, 2026
13b1974
Fixed conflict
Ramixin Mar 9, 2026
2cb10e4
House cleaning
Ramixin Mar 8, 2026
fb27347
Merge remote-tracking branch 'origin/renderStateDataExtraction' into …
Ramixin Mar 9, 2026
bd3d302
Fixed silent conflict
Ramixin Mar 9, 2026
14b21be
Add global data attachments (#5231)
DennisOchulor Mar 10, 2026
3042174
Merge remote-tracking branch 'origin/renderStateDataExtraction' into …
Ramixin Mar 10, 2026
ffb05a0
attempt to remedy merge blunder
Ramixin Mar 11, 2026
259635a
removed leftover classes from cleanup
Ramixin Mar 11, 2026
caf9215
added back changes to classes that were undone
Ramixin Mar 11, 2026
1612e9f
ran spotless
Ramixin Mar 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.rendering.v1;

import net.minecraft.client.renderer.entity.state.EntityRenderState;
import net.minecraft.world.entity.Entity;

public interface EntityRenderStateDataExtractor {
void extract(Entity entity, EntityRenderState state);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.rendering.v1;

import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.Nullable;

import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.world.entity.EntityType;

import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;

public interface EntityRenderStateExtractionCallback {
Event<EntityRenderStateExtractionCallback> EVENT = EventFactory.createArrayBacked(
EntityRenderStateExtractionCallback.class, listeners -> ctx -> {
for (EntityRenderStateExtractionCallback callback : listeners) {
callback.onRenderStateExtraction(ctx);
}
});

void onRenderStateExtraction(Context ctx);

@ApiStatus.NonExtendable
interface Context {
@Nullable EntityType<?> type();

EntityRenderer<?, ?> renderer();

EntityRendererProvider.Context rendererContext();

void add(EntityRenderStateDataExtractor extractor);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.rendering.v1;

import java.util.List;

public interface EntityRenderStateExtractorHolder {
void fabric_addExtractors(List<EntityRenderStateDataExtractor> extractors);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.impl.client.rendering;

import java.util.ArrayList;
import java.util.List;

import org.jspecify.annotations.Nullable;

import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.world.entity.EntityType;

import net.fabricmc.fabric.api.client.rendering.v1.EntityRenderStateDataExtractor;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRenderStateExtractionCallback;

public final class RenderStateExtractionCallbackContextImpl implements EntityRenderStateExtractionCallback.Context {
private final @Nullable EntityType<?> type;
private final EntityRenderer<?, ?> renderer;
private final EntityRendererProvider.Context rendererContext;
private final List<EntityRenderStateDataExtractor> extractors = new ArrayList<>();

public RenderStateExtractionCallbackContextImpl(@Nullable EntityType<?> type, EntityRenderer<?, ?> renderer, EntityRendererProvider.Context rendererContext) {
this.type = type;
this.renderer = renderer;
this.rendererContext = rendererContext;
}

@Override
public void add(EntityRenderStateDataExtractor extractor) {
extractors.add(extractor);
}

@Override
public @Nullable EntityType<?> type() {
return type;
}

@Override
public EntityRenderer<?, ?> renderer() {
return renderer;
}

@Override
public EntityRendererProvider.Context rendererContext() {
return rendererContext;
}

public List<EntityRenderStateDataExtractor> extractors() {
return extractors;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.mixin.client.rendering;

import java.util.ArrayList;
import java.util.List;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.state.EntityRenderState;
import net.minecraft.world.entity.Entity;

import net.fabricmc.fabric.api.client.rendering.v1.EntityRenderStateDataExtractor;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRenderStateExtractorHolder;

@Mixin(EntityRenderer.class)
public abstract class EntityRendererMixin<T extends Entity, S extends EntityRenderState> implements EntityRenderStateExtractorHolder {
@Unique
private final List<EntityRenderStateDataExtractor> renderStateExtractors = new ArrayList<>();

@Inject(method = "extractRenderState", at = @At("TAIL"))
private void runRenderStateExtractors(T entity, S state, float partialTicks, CallbackInfo ci) {
for (EntityRenderStateDataExtractor extractor : renderStateExtractors) {
extractor.extract(entity, state);
}
}

@Override
public void fabric_addExtractors(List<EntityRenderStateDataExtractor> extractors) {
this.renderStateExtractors.addAll(extractors);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.collect.ImmutableMap;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
Expand All @@ -34,12 +35,16 @@
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.player.AvatarRenderer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;

import net.fabricmc.fabric.api.client.rendering.v1.EntityRenderStateExtractionCallback;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRenderStateExtractorHolder;
import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityRenderLayerRegistrationCallback;
import net.fabricmc.fabric.impl.client.rendering.EntityRendererRegistryImpl;
import net.fabricmc.fabric.impl.client.rendering.RegistrationHelperImpl;
import net.fabricmc.fabric.impl.client.rendering.RenderStateExtractionCallbackContextImpl;

@Mixin(EntityRenderers.class)
public abstract class EntityRenderersMixin {
Expand Down Expand Up @@ -77,4 +82,22 @@ private static AvatarRenderer createAvatarRenderer(EntityRendererProvider.Contex

return entityRenderer;
}

@WrapOperation(method = "lambda$createEntityRenderers$0", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/EntityRendererProvider;create(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;)Lnet/minecraft/client/renderer/entity/EntityRenderer;"))
private static <T extends Entity> EntityRenderer<T, ?> applyExtractorsToRenderer(EntityRendererProvider<T> instance, EntityRendererProvider.Context context, Operation<EntityRenderer<T, ?>> original, @Local(argsOnly = true) EntityType<T> entityType) {
EntityRenderer<T, ?> entityRenderer = original.call(instance, context);
RenderStateExtractionCallbackContextImpl ctx = new RenderStateExtractionCallbackContextImpl(entityType, entityRenderer, context);
EntityRenderStateExtractionCallback.EVENT.invoker().onRenderStateExtraction(ctx);
((EntityRenderStateExtractorHolder) entityRenderer).fabric_addExtractors(ctx.extractors());
return entityRenderer;
}

@WrapOperation(method = "createAvatarRenderers", at = @At(value = "NEW", target = "(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;Z)Lnet/minecraft/client/renderer/entity/player/AvatarRenderer;"))
private static AvatarRenderer<?> applyExtractorsToAvatarRenderer(EntityRendererProvider.Context context, boolean slimSteve, Operation<AvatarRenderer<?>> original) {
AvatarRenderer<?> entityRenderer = original.call(context, slimSteve);
RenderStateExtractionCallbackContextImpl ctx = new RenderStateExtractionCallbackContextImpl(null, entityRenderer, context);
EntityRenderStateExtractionCallback.EVENT.invoker().onRenderStateExtraction(ctx);
((EntityRenderStateExtractorHolder) entityRenderer).fabric_addExtractors(ctx.extractors());
return entityRenderer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,8 @@
},
"overwrites": {
"requireAnnotations": true
}
},
"mixins": [
"EntityRendererMixin"
]
}
Loading