-
Notifications
You must be signed in to change notification settings - Fork 522
Render State Data Extraction #5235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Ramixin
wants to merge
27
commits into
FabricMC:26.1
Choose a base branch
from
Ramixin:renderStateDataExtraction
base: 26.1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 5 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 dab345e
Fixed EntityRendererMixin being a common mixin rather than client
Ramixin a66635a
Added game test for RenderStateDataExtractionRegistry
Ramixin b61fef4
26.1-snapshot-11 (#5240)
modmuss50 9451711
Bump version
modmuss50 1bd9c6c
Bump version
modmuss50 17d6d79
Fix opaque water by not overriding existing ChunkSectionLayer for flu…
modmuss50 b24f50f
Bump version
modmuss50 1e4130d
Pivoted to entity renderers
Ramixin 5f74a07
Pivoted to events instead of registration (proof of concept)
Ramixin aac8b1d
Cleaned up
Ramixin fa98c24
House cleaning
Ramixin 273e35e
initial commit for render state data extraction pull request
Ramixin 01cf6f4
Fixed EntityRendererMixin being a common mixin rather than client
Ramixin f34be3f
Added game test for RenderStateDataExtractionRegistry
Ramixin e55b6c5
Pivoted to entity renderers
Ramixin 6aafd40
Pivoted to events instead of registration (proof of concept)
Ramixin 13b1974
Fixed conflict
Ramixin 2cb10e4
House cleaning
Ramixin fb27347
Merge remote-tracking branch 'origin/renderStateDataExtraction' into …
Ramixin bd3d302
Fixed silent conflict
Ramixin 14b21be
Add global data attachments (#5231)
DennisOchulor 3042174
Merge remote-tracking branch 'origin/renderStateDataExtraction' into …
Ramixin ffb05a0
attempt to remedy merge blunder
Ramixin 259635a
removed leftover classes from cleanup
Ramixin caf9215
added back changes to classes that were undone
Ramixin 1612e9f
ran spotless
Ramixin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
...-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/FabricEntityRenderer.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | ||
|
|
||
| public interface FabricEntityRenderer { | ||
| default void addExtractor(RenderStateDataExtractor extractor) { | ||
| throw new UnsupportedOperationException("Implemented via mixin"); | ||
| } | ||
| } | ||
31 changes: 31 additions & 0 deletions
31
...src/client/java/net/fabricmc/fabric/api/client/rendering/v1/RenderStateDataExtractor.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /* | ||
| * 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.EntityRendererProvider; | ||
| import net.minecraft.client.renderer.entity.state.EntityRenderState; | ||
| import net.minecraft.world.entity.Entity; | ||
|
|
||
| public abstract class RenderStateDataExtractor { | ||
Ramixin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| public RenderStateDataExtractor(EntityRendererProvider.Context context) { | ||
|
Check failure on line 25 in fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/RenderStateDataExtractor.java
|
||
|
|
||
| } | ||
|
|
||
| public abstract void extract(Entity entity, EntityRenderState state); | ||
|
|
||
| } | ||
45 changes: 45 additions & 0 deletions
45
...lient/java/net/fabricmc/fabric/api/client/rendering/v1/RenderStateExtractionCallback.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package net.fabricmc.fabric.api.client.rendering.v1; | ||
|
|
||
| import java.util.List; | ||
| import java.util.function.Function; | ||
|
|
||
| import org.jetbrains.annotations.ApiStatus; | ||
|
|
||
| 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; | ||
|
|
||
| import org.jspecify.annotations.Nullable; | ||
|
|
||
| public interface RenderStateExtractionCallback { | ||
Ramixin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Event<RenderStateExtractionCallback> EVENT = EventFactory.createArrayBacked( | ||
| RenderStateExtractionCallback.class, listeners -> ctx -> { | ||
| for (RenderStateExtractionCallback callback : listeners) { | ||
| callback.onRenderStateExtraction(ctx); | ||
| for (Function<EntityRendererProvider.Context, RenderStateDataExtractor> factory : ctx.factories()) { | ||
| ctx.renderer().addExtractor(factory.apply(ctx.rendererContext())); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| void onRenderStateExtraction(RenderStateExtractionCallback.Context ctx); | ||
|
|
||
| @ApiStatus.NonExtendable | ||
| interface Context { | ||
|
|
||
| @Nullable EntityType<?> type(); | ||
|
|
||
| EntityRenderer<?, ?> renderer(); | ||
|
|
||
| EntityRendererProvider.Context rendererContext(); | ||
|
|
||
| void add(Function<EntityRendererProvider.Context, RenderStateDataExtractor> extractorFactory); | ||
Ramixin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| List<Function<EntityRendererProvider.Context, RenderStateDataExtractor>> factories(); | ||
Ramixin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| } | ||
| } | ||
20 changes: 20 additions & 0 deletions
20
...a/net/fabricmc/fabric/impl/client/rendering/RenderStateExtractionCallbackContextImpl.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package net.fabricmc.fabric.impl.client.rendering; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.function.Function; | ||
|
|
||
| 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.RenderStateDataExtractor; | ||
| import net.fabricmc.fabric.api.client.rendering.v1.RenderStateExtractionCallback; | ||
|
|
||
| import org.jspecify.annotations.Nullable; | ||
|
|
||
| public record RenderStateExtractionCallbackContextImpl(@Nullable EntityType<?> type, EntityRenderer<?, ?> renderer, EntityRendererProvider.Context rendererContext, ArrayList<Function<EntityRendererProvider.Context, RenderStateDataExtractor>> factories) implements RenderStateExtractionCallback.Context { | ||
| @Override | ||
| public void add(Function<EntityRendererProvider.Context, RenderStateDataExtractor> extractorFactory) { | ||
| factories.add(extractorFactory); | ||
| } | ||
| } | ||
51 changes: 51 additions & 0 deletions
51
...ng-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/EntityRendererMixin.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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.FabricEntityRenderer; | ||
| import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataExtractor; | ||
|
|
||
| @Mixin(EntityRenderer.class) | ||
| public abstract class EntityRendererMixin<T extends Entity, S extends EntityRenderState> implements FabricEntityRenderer { | ||
| @Unique | ||
| private final List<RenderStateDataExtractor> renderStateExtractors = new ArrayList<>(); | ||
|
|
||
| @Inject(method = "extractRenderState", at = @At("TAIL")) | ||
| private void runRenderStateExtractors(T entity, S state, float partialTicks, CallbackInfo ci) { | ||
| for (RenderStateDataExtractor extractor : renderStateExtractors) { | ||
| extractor.extract(entity, state); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void addExtractor(RenderStateDataExtractor extractor) { | ||
| renderStateExtractors.add(extractor); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
144 changes: 144 additions & 0 deletions
144
...dClient/java/net/fabricmc/fabric/test/rendering/client/RenderStateDataExtractionTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| /* | ||
| * 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.test.rendering.client; | ||
|
|
||
| import com.mojang.blaze3d.vertex.PoseStack; | ||
|
|
||
| import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityRenderLayerRegistrationCallback; | ||
|
|
||
| import net.fabricmc.fabric.api.client.rendering.v1.ModelLayerRegistry; | ||
| import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataExtractor; | ||
| import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; | ||
|
|
||
| import net.fabricmc.fabric.api.client.rendering.v1.RenderStateExtractionCallback; | ||
|
|
||
| import net.minecraft.client.renderer.entity.EntityRendererProvider; | ||
| import net.minecraft.client.renderer.entity.state.EntityRenderState; | ||
| import net.minecraft.world.entity.Entity; | ||
|
|
||
| import net.minecraft.world.entity.LivingEntity; | ||
|
|
||
| import org.jspecify.annotations.NonNull; | ||
|
|
||
| import net.minecraft.client.model.Model; | ||
| import net.minecraft.client.model.geom.EntityModelSet; | ||
| import net.minecraft.client.model.geom.ModelLayerLocation; | ||
| import net.minecraft.client.model.geom.ModelPart; | ||
| import net.minecraft.client.model.geom.PartPose; | ||
| import net.minecraft.client.model.geom.builders.CubeDeformation; | ||
| import net.minecraft.client.model.geom.builders.CubeListBuilder; | ||
| import net.minecraft.client.model.geom.builders.LayerDefinition; | ||
| import net.minecraft.client.model.geom.builders.MeshDefinition; | ||
| import net.minecraft.client.model.geom.builders.PartDefinition; | ||
| import net.minecraft.client.model.player.PlayerModel; | ||
| import net.minecraft.client.renderer.SubmitNodeCollector; | ||
| import net.minecraft.client.renderer.entity.LivingEntityRenderer; | ||
| import net.minecraft.client.renderer.entity.RenderLayerParent; | ||
| import net.minecraft.client.renderer.entity.layers.RenderLayer; | ||
| import net.minecraft.client.renderer.entity.player.AvatarRenderer; | ||
| import net.minecraft.client.renderer.entity.state.AvatarRenderState; | ||
| import net.minecraft.client.renderer.rendertype.RenderTypes; | ||
| import net.minecraft.resources.Identifier; | ||
|
|
||
| import net.fabricmc.api.ClientModInitializer; | ||
|
|
||
| /** | ||
| * Renders a small red cube in front of the player's chest when in f5. The cube's | ||
| * transparency is determined by the player's health percentage. | ||
| * | ||
| * <p> | ||
| * Tests: | ||
| * <ul> | ||
| * <li>{@link RenderStateExtractionCallback}</li> | ||
| * </ul> | ||
| * | ||
| * <p> | ||
| * Assumes the following work as intended: | ||
| * <ul> | ||
| * <li>{@link ModelLayerRegistry}</li> | ||
| * <li>{@link RenderStateDataKey}</li> | ||
| * <li>{@link LivingEntityRenderLayerRegistrationCallback}</li> | ||
| * </ul> | ||
| */ | ||
| public class RenderStateDataExtractionTest implements ClientModInitializer { | ||
| public static final ModelLayerLocation TEST_MODEL_LOCATION = new ModelLayerLocation(Identifier.fromNamespaceAndPath("fabric", "test_rse_model"), "test_rse_model"); | ||
|
|
||
| public static final RenderStateDataKey<Float> PLAYER_HEALTH_PERCENTAGE = RenderStateDataKey.create(() -> "Test RSE: Player Health Percentage"); | ||
|
|
||
| @Override | ||
| public void onInitializeClient() { | ||
| ModelLayerRegistry.registerModelLayer(TEST_MODEL_LOCATION, TestModel::createLayer); | ||
|
|
||
| LivingEntityRenderLayerRegistrationCallback.EVENT.register((_, entityRenderer, registrationHelper, context) -> { | ||
| if (entityRenderer instanceof AvatarRenderer<?> avatarRenderer) { | ||
| registrationHelper.register(new TestRenderLayer(avatarRenderer, context.getModelSet())); | ||
| } | ||
| }); | ||
|
|
||
| RenderStateExtractionCallback.EVENT.register(context -> { | ||
| if (context.renderer() instanceof AvatarRenderer<?>) { | ||
| context.add(TestExtractor::new); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| public static class TestRenderLayer extends RenderLayer<AvatarRenderState, PlayerModel> { | ||
| private final TestModel model; | ||
|
|
||
| public TestRenderLayer(RenderLayerParent<AvatarRenderState, PlayerModel> renderer, final EntityModelSet modelSet) { | ||
| super(renderer); | ||
| this.model = new TestModel(modelSet.bakeLayer(TEST_MODEL_LOCATION)); | ||
| } | ||
|
|
||
| @Override | ||
| public void submit(@NonNull PoseStack poseStack, @NonNull SubmitNodeCollector submitNodeCollector, int lightCoords, AvatarRenderState state, float yRot, float xRot) { | ||
| int overlayCoords = LivingEntityRenderer.getOverlayCoords(state, 0.0F); | ||
| float healthPercentage = state.getDataOrDefault(PLAYER_HEALTH_PERCENTAGE, 0f); | ||
| int tint = (int) (healthPercentage * 255) << 24 | 0x00FF0000; | ||
| submitNodeCollector.submitModel(model, state, poseStack, RenderTypes.entityTranslucent(Identifier.fromNamespaceAndPath("minecraft", "textures/block/diamond_block.png")), lightCoords, overlayCoords, tint, null, state.outlineColor, null); | ||
| } | ||
| } | ||
|
|
||
| public static class TestModel extends Model<AvatarRenderState> { | ||
| public TestModel(ModelPart root) { | ||
| super(root, RenderTypes::entityTranslucent); | ||
| } | ||
|
|
||
| public static LayerDefinition createLayer() { | ||
| MeshDefinition mesh = PlayerModel.createMesh(CubeDeformation.NONE, false); | ||
| PartDefinition root = mesh.getRoot().clearRecursively(); | ||
| PartDefinition head = root.getChild("body"); | ||
|
|
||
| CubeListBuilder cube = CubeListBuilder.create().addBox(-4, 2, -12, 8, 8, 8); | ||
| head.addOrReplaceChild("fabric:test_rse_model", cube, PartPose.ZERO); | ||
| return LayerDefinition.create(mesh, 16, 16); | ||
| } | ||
| } | ||
|
|
||
| public static class TestExtractor extends RenderStateDataExtractor { | ||
|
|
||
| public TestExtractor(EntityRendererProvider.Context context) { | ||
| super(context); | ||
| } | ||
|
|
||
| @Override | ||
| public void extract(Entity entity, EntityRenderState state) { | ||
| LivingEntity livingEntity = (LivingEntity) entity; | ||
| state.setData(PLAYER_HEALTH_PERCENTAGE, livingEntity.getHealth() / livingEntity.getMaxHealth()); | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.