Jump to content

[1.20.1] Can't figure out how to get EntityRendererProvider.Context - Difficulty getting custom player model to render


Recommended Posts

Posted

Hello, I've decided I want to replace the default player model with a custom one but can't quite seem to figure it out. I'm somewhat new to minecraft modding so please forgive me if I'm missing something obvious. My code is also a bit jumbled and nothing atm (been deleting any code that hasn't been working) and imports things that aren't being used as I've been doing a lot of experimenting with this problem.

I've read through probably every other existing topic on rendering player models but their solutions don't seem to quite translate to my particular issue. My PlayerRenderOverride class can't access the render method since the render is static.


On a side note, I have successfully been able to render mobs using my model and renderer files.


My replacement code

package net.grem.bioniclemod.playerrender;


import net.grem.bioniclemod.BionicleMod;

import net.grem.bioniclemod.entity.custom.ToaModelLayers;
import net.grem.bioniclemod.entity.custom.toamodel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraftforge.api.distmarker.Dist;

import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.util.EventObject;


@Mod.EventBusSubscriber(modid = BionicleMod.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)


public class PlayerRenderOverride {

    public static toamodel model;


    @SubscribeEvent
    public static void onRenderPlayer(RenderPlayerEvent.Pre e) {


            e.setCanceled(true);

            ToaPlayerRenderer.render(e.getEntity(), 0f, 0f, e.getPoseStack(), 0f, 0f);

    }






}

My render code

package net.grem.bioniclemod.playerrender;

import com.mojang.blaze3d.vertex.PoseStack;
import net.grem.bioniclemod.BionicleMod;
import net.grem.bioniclemod.entity.custom.ToaModelLayers;
import net.grem.bioniclemod.entity.custom.toamodel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;

import net.minecraft.resources.ResourceLocation;


public class ToaPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, toamodel<AbstractClientPlayer>>{



    public ToaPlayerRenderer(EntityRendererProvider.Context pContext, boolean pUseSlimModel) {
        super(pContext, new toamodel<>(pContext.bakeLayer(ToaModelLayers.toalayer)), 0.5F);

        // this.addLayer(new ToaArmorLayer -- doesn't exist yet. do later



    }


   @Override
    public void render(AbstractClientPlayer pEntity, float pEntityYaw, float pPartialTicks, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight){

        super.render(pEntity, pEntityYaw, pPartialTicks, pPoseStack, pBuffer, pPackedLight);


    }






    @Override
    public ResourceLocation getTextureLocation(AbstractClientPlayer pEntity) {
        return new ResourceLocation(BionicleMod.MODID, "textures/entity/toa.png");
    }






}

My model file
 

package net.grem.bioniclemod.entity.custom;// Made with Blockbench 4.11.0-beta.1
// Exported for Minecraft version 1.17 or later with Mojang mappings
// Paste this class into your mod and generate all required imports


import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.model.HierarchicalModel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.*;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.world.entity.Entity;

public class toamodel<T extends Entity> extends HierarchicalModel<T> {
	// This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor

	private final ModelPart toa;
	private final ModelPart body;
	private final ModelPart right_leg;
	private final ModelPart left_leg;
	private final ModelPart torso;
	private final ModelPart head;
	private final ModelPart brain;
	private final ModelPart right_arm;
	private final ModelPart left_arm;

	public toamodel(ModelPart root) {
		this.toa = root.getChild("toa");
		this.body = root.getChild("toa").getChild("body");
		this.right_leg = root.getChild("toa").getChild("body").getChild("right_leg");
		this.left_leg = root.getChild("toa").getChild("body").getChild("left_leg");
		this.torso = root.getChild("toa").getChild("body").getChild("torso");
		this.head = root.getChild("toa").getChild("body").getChild("head");
		this.brain = root.getChild("toa").getChild("body").getChild("head").getChild("brain");
		this.right_arm = root.getChild("toa").getChild("body").getChild("right_arm");
		this.left_arm = root.getChild("toa").getChild("body").getChild("left_arm");
	}




	public static LayerDefinition createBodyLayer() {
		MeshDefinition meshdefinition = new MeshDefinition();
		PartDefinition partdefinition = meshdefinition.getRoot();

		PartDefinition toa = partdefinition.addOrReplaceChild("toa", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F));

		PartDefinition body = toa.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.offset(0.0F, 0.0F, 0.0F));

		PartDefinition right_leg = body.addOrReplaceChild("right_leg", CubeListBuilder.create().texOffs(24, 47).mirror().addBox(-1.5F, 5.7394F, -2.5568F, 3.0F, 7.0F, 4.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offset(-2.5F, -12.75F, 0.0F));

		PartDefinition cube_r1 = right_leg.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(26, 38).mirror().addBox(-1.0F, -16.0F, -2.0F, 2.0F, 6.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(0.0F, 15.95F, -2.15F, -0.1745F, 0.0F, 0.0F));

		PartDefinition cube_r2 = right_leg.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(25, 32).mirror().addBox(0.0F, -1.5F, -1.5F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-1.5F, 0.25F, 0.0F, 0.7418F, 0.0F, 0.0F));

		PartDefinition left_leg = body.addOrReplaceChild("left_leg", CubeListBuilder.create().texOffs(24, 47).addBox(1.0F, -7.0106F, -3.0568F, 3.0F, 7.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.5F));

		PartDefinition cube_r3 = left_leg.addOrReplaceChild("cube_r3", CubeListBuilder.create().texOffs(26, 38).addBox(-1.0F, -16.0F, -2.0F, 2.0F, 6.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(2.5F, 3.2F, -2.65F, -0.1745F, 0.0F, 0.0F));

		PartDefinition cube_r4 = left_leg.addOrReplaceChild("cube_r4", CubeListBuilder.create().texOffs(25, 32).addBox(0.0F, -1.5F, -1.5F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(1.0F, -12.5F, -0.5F, 0.7418F, 0.0F, 0.0F));

		PartDefinition torso = body.addOrReplaceChild("torso", CubeListBuilder.create().texOffs(58, 34).addBox(-8.0F, -23.75F, -0.5F, 2.0F, 1.0F, 1.0F, new CubeDeformation(0.0F))
		.texOffs(58, 34).addBox(-18.0F, -23.75F, -0.5F, 2.0F, 1.0F, 1.0F, new CubeDeformation(0.0F))
		.texOffs(20, 23).addBox(-16.0F, -23.75F, -1.0F, 8.0F, 5.0F, 2.0F, new CubeDeformation(0.0F))
		.texOffs(45, 43).addBox(-15.0F, -13.0F, -0.5F, 6.0F, 1.0F, 1.0F, new CubeDeformation(0.0F))
		.texOffs(44, 34).addBox(-15.0F, -16.0F, -1.0F, 6.0F, 1.0F, 2.0F, new CubeDeformation(0.0F))
		.texOffs(40, 19).addBox(-15.5F, -23.5F, -3.0F, 7.0F, 6.0F, 5.0F, new CubeDeformation(0.0F))
		.texOffs(48, 30).addBox(-13.0F, -18.0F, -1.0F, 2.0F, 2.0F, 2.0F, new CubeDeformation(0.0F))
		.texOffs(48, 37).addBox(-13.0F, -15.0F, -1.0F, 2.0F, 4.0F, 2.0F, new CubeDeformation(0.0F))
		.texOffs(50, 11).addBox(-13.0F, -29.0F, -1.0F, 2.0F, 6.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offset(12.0F, 0.0F, 0.0F));

		PartDefinition cube_r5 = torso.addOrReplaceChild("cube_r5", CubeListBuilder.create().texOffs(40, 30).addBox(0.0F, -1.0F, 0.0F, 4.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-9.0353F, -14.8863F, -0.5F, 0.0F, 0.0F, -1.309F));

		PartDefinition cube_r6 = torso.addOrReplaceChild("cube_r6", CubeListBuilder.create().texOffs(40, 30).mirror().addBox(-4.0F, -1.0F, 0.0F, 4.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-14.9647F, -14.8863F, -0.5F, 0.0F, 0.0F, 1.309F));

		PartDefinition head = body.addOrReplaceChild("head", CubeListBuilder.create().texOffs(21, 11).addBox(-1.5F, 0.0F, -4.45F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F))
		.texOffs(19, 17).addBox(-2.0F, 2.05F, -3.45F, 4.0F, 1.0F, 4.0F, new CubeDeformation(0.0F))
		.texOffs(6, 10).addBox(0.0094F, 0.0F, -3.1379F, 3.0F, 3.0F, 4.0F, new CubeDeformation(0.0F))
		.texOffs(6, 10).mirror().addBox(-3.0094F, 0.0F, -3.1379F, 3.0F, 3.0F, 4.0F, new CubeDeformation(0.0F)).mirror(false)
		.texOffs(23, 0).addBox(-0.5F, -4.6985F, -2.7399F, 1.0F, 1.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -27.5F, -0.55F));

		PartDefinition cube_r7 = head.addOrReplaceChild("cube_r7", CubeListBuilder.create().texOffs(24, 4).addBox(0.0F, -4.0F, 0.0F, 1.0F, 5.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-0.5F, -0.9397F, -4.108F, -0.3491F, 0.0F, 0.0F));

		PartDefinition cube_r8 = head.addOrReplaceChild("cube_r8", CubeListBuilder.create().texOffs(18, 7).mirror().addBox(-2.0F, -2.0F, 0.0F, 2.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-0.4075F, -2.4747F, -2.8121F, -0.1278F, 0.0283F, 0.2164F));

		PartDefinition cube_r9 = head.addOrReplaceChild("cube_r9", CubeListBuilder.create().texOffs(16, 10).mirror().addBox(-2.0F, -3.0F, 0.0F, 3.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-1.0568F, 0.4292F, -3.1944F, -0.1278F, 0.0283F, 0.2164F));

		PartDefinition cube_r10 = head.addOrReplaceChild("cube_r10", CubeListBuilder.create().texOffs(18, 7).addBox(0.0F, -2.0F, 0.0F, 2.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.4075F, -2.4747F, -2.8121F, -0.1278F, -0.0283F, -0.2164F));

		PartDefinition cube_r11 = head.addOrReplaceChild("cube_r11", CubeListBuilder.create().texOffs(16, 10).addBox(-1.0F, -3.0F, 0.0F, 3.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(1.0568F, 0.4292F, -3.1944F, -0.1278F, -0.0283F, -0.2164F));

		PartDefinition cube_r12 = head.addOrReplaceChild("cube_r12", CubeListBuilder.create().texOffs(17, 17).mirror().addBox(-0.9393F, -1.0F, -0.3536F, 2.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-2.0685F, 1.0F, -3.4873F, 0.0F, 0.7156F, 0.0F));

		PartDefinition cube_r13 = head.addOrReplaceChild("cube_r13", CubeListBuilder.create().texOffs(17, 17).addBox(-1.0607F, -1.0F, -0.3536F, 2.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(2.0685F, 1.0F, -3.4873F, 0.0F, -0.7156F, 0.0F));

		PartDefinition cube_r14 = head.addOrReplaceChild("cube_r14", CubeListBuilder.create().texOffs(18, 4).mirror().addBox(0.0F, -5.0F, 0.0F, 2.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-2.5F, 0.9F, -5.0F, -0.3914F, 0.0334F, 0.0807F));

		PartDefinition cube_r15 = head.addOrReplaceChild("cube_r15", CubeListBuilder.create().texOffs(18, 4).addBox(-2.0F, -5.0F, 0.0F, 2.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(2.5F, 0.9F, -5.0F, -0.3914F, -0.0334F, -0.0807F));

		PartDefinition brain = head.addOrReplaceChild("brain", CubeListBuilder.create().texOffs(39, 3).addBox(-2.0F, -4.0515F, -0.5601F, 4.0F, 1.0F, 1.0F, new CubeDeformation(0.0F))
		.texOffs(44, 0).addBox(-2.0F, -6.0F, 0.0F, 4.0F, 5.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 2.3015F, -2.4899F));

		PartDefinition right_arm = body.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(0, 34).mirror().addBox(-1.5F, 1.6F, -10.25F, 3.0F, 4.0F, 6.0F, new CubeDeformation(0.0F)).mirror(false)
		.texOffs(0, 18).mirror().addBox(-1.5F, -1.5F, -1.25F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(-5.5F, -23.0F, -0.25F, 0.9861F, 0.0F, 0.0F));

		PartDefinition cube_r16 = right_arm.addOrReplaceChild("cube_r16", CubeListBuilder.create().texOffs(0, 24).mirror().addBox(-1.0F, -2.0F, 0.0F, 2.0F, 3.0F, 7.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(0.0F, 4.8F, -5.0F, 0.637F, 0.0F, 0.0F));

		PartDefinition left_arm = body.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(0, 34).addBox(-1.5F, 1.6F, -10.25F, 3.0F, 4.0F, 6.0F, new CubeDeformation(0.0F))
		.texOffs(0, 18).addBox(-1.5F, -1.5F, -1.25F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.5F, -23.0F, -0.25F, 1.0036F, 0.0F, 0.0F));

		PartDefinition cube_r17 = left_arm.addOrReplaceChild("cube_r17", CubeListBuilder.create().texOffs(0, 24).addBox(-2.0F, -2.0F, 0.0F, 2.0F, 3.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(1.0F, 4.8F, -5.0F, 0.637F, 0.0F, 0.0F));

		return LayerDefinition.create(meshdefinition, 64, 64);
	}

	@Override
	public void setupAnim(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
	// no anims yet
	}


	@Override
	public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
		toa.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha);
	}

	@Override
	public ModelPart root(){

		return toa;
	}



}

 

 

 

Posted
  @SubscribeEvent
    public static void onRenderPlayer(RenderPlayerEvent.Pre e) {


            e.setCanceled(true);



           model.renderToBuffer(e.getPoseStack(), pBuffer, e.getPackedLight(), 0f, 0f, 0f, 0f, 0f);
            //ToaPlayerRenderer.render();
    }

Since getting the render method from a separate class is proving to be bit of a brick wall for me (but seems to be the solution in older versions of minecraft/forge) I've decided to try and pursue using the renderToBuffer method directly from the model itself. I've tried this route before but can't figure out what variables to feed it for the vertexConsumer and still can't seem to figure it out; if this is even a path to pursue. 

The vanilla model files do not include any form of render methods, and seem to be fully constructed from their layer definitions? Their renderer files seem to take their layers which are used by the render method in the vanilla MobRenderer class. But for modded entities we @Override this function and don't have to feed the method variables because of that? I assume that the render method in the extended renderer takes the layer definitions from the renderer classes which take those from the model files.

Or maybe instead of trying to use a render method I should be calling the super from the renderer like
 

new ToaPlayerRenderer(context, false);

Except I'm not sure what I would provide for context? There's a context method in the vanilla EntityRendererProvider class which doesn't look especially helpful. I've been trying something like

<e.getEntity(), model<e.getEntity()>>

since that generally seems to be what is provided to the renderers for context, but I don't know if it's THE context I'm looking for? Especially since the method being called doesn't want to take this or variations of this.

 





In short; I feel like I'm super super close but I have to be missing something obvious? Maybe this insane inane ramble post will provide some insight into this puzzle?

Posted

If I make a new renderer class it seems it lets me use the render method off of that. But I have no idea how to get the context? Additionally, I'm not sure that even if I do get the context for the constructor it won't just red line out the render method again telling me "non static method can't be used in static context"

 

 final EntityRendererProvider context = ??????;

        ToaPlayerRenderer h = new ToaPlayerRenderer(context, false);
        h.render(p, 1f,pTicks, stack, buffer, paLights);


However, I feel like this isn't going to work even if I somehow figure out where to look to get context and the render method can actually be used

 

Posted (edited)

Maybe it's just that my model is janked in some way? My .java model class file from blockbench doesn't have a render method, but every model from everyone who's had this issue in the past has had a render or doRender method that take different values than my models renderToBuffer method which requires the ever puzzling and mysterious vertexConsumer.

But if that were the case, surely I'd have issues rendering mob entities with the model as well?

 

Note: making my own either leads to infinite recursion or the exact same "can't use static method in non-static context" message

 

Edited by Shipwrecker
Posted (edited)

So the default PlayerModel contains this code here to set the players arms to slim

 

 if (pSlim) {
            $$3.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(32, 48).addBox(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, pCubeDeformation), PartPose.offset(5.0F, 2.5F, 0.0F));
            $$3.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(40, 16).addBox(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, pCubeDeformation), PartPose.offset(-5.0F, 2.5F, 0.0F));
            $$3.addOrReplaceChild("left_sleeve", CubeListBuilder.create().texOffs(48, 48).addBox(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, pCubeDeformation.extend(0.25F)), PartPose.offset(5.0F, 2.5F, 0.0F));
            $$3.addOrReplaceChild("right_sleeve", CubeListBuilder.create().texOffs(40, 32).addBox(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, pCubeDeformation.extend(0.25F)), PartPose.offset(-5.0F, 2.5F, 0.0F));
        } else {
            $$3.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(32, 48).addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, pCubeDeformation), PartPose.offset(5.0F, 2.0F, 0.0F));
            $$3.addOrReplaceChild("left_sleeve", CubeListBuilder.create().texOffs(48, 48).addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, pCubeDeformation.extend(0.25F)), PartPose.offset(5.0F, 2.0F, 0.0F));
            $$3.addOrReplaceChild("right_sleeve", CubeListBuilder.create().texOffs(40, 32).addBox(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, pCubeDeformation.extend(0.25F)), PartPose.offset(-5.0F, 2.0F, 0.0F));
        }


And that's got me thinking. If I can't replace the whole model in one fell swoop, what if I replaced each individual limb with my models mesh definitions?

Note: It was crazy. The createMesh method in PlayerModel could not be @Overriden and addOrReplaceChild just makes changes to a new model that uses the original as a base.
 

 


However, I did render my model using this
 

    final toatestentity idk = entities.toatest.get().create(p.level());
    Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(idk).render(idk, 0f, pTicks, stack, buffer, paLights);

However that just uses the render from the entity I used to test getting the model to render in the first place. I don't want to do that. I want to fully replace the player model which this doesn't actually do (I don't think?). 

Maybe it'd just be best to render my model as a new layer and make the base player model invisible? Maybe I'll take a look at how armor is rendered to move with the player so I won't have to make my own animations? Idk, I'm really set on figuring this out though.

Edited by Shipwrecker
Posted (edited)

I got my model to render from the models renderToBuffer method. But still not quite what I want. I want to render the model from my renderer's render method. I feel that having access to the renderer and its methods will open some doors for me later down the line.

    //EntityRendererProvider.Context pContext = ;  I want this
        //ToaPlayerRenderer render = new ToaPlayerRenderer(pContext, false);
		// if I can get the above line to work, having the methods from the renderer class would be incredibly helpful down the line

        RenderType rendertype = model.renderType(p.getSkinTextureLocation()); // this should be something like render.getTextureLocation()
        VertexConsumer vertexconsumer = buffer.getBuffer(rendertype);

        model.renderToBuffer(stack, vertexconsumer, paLights, 1, 1, 1, 1, 1); // I don't want the render to happen here since it doesn't use the renderer


        //model.render(p, 1f, pTicks, stack, buffer, paLights); I want to render the model using this

It is certainly getting closer though. Probably.

I am still worried that even if pContext is initialized this new instance of the renderer class will still hit me with the classic and all too familiar "can't use static method in non-static context"

Edited by Shipwrecker
  • Shipwrecker changed the title to [1.20.1] Can't figure out how to get EntityRendererProvider.Context - Difficulty getting custom player model to render
Posted

So apparently geckolib has documentation for replacing a renderer as well as adding layers to entity renderers. Probably should've looked into it sooner.

https://github.com/bernie-g/geckolib/blob/1.20.1/Forge/src/main/java/software/bernie/example/client/renderer/entity/ReplacedCreeperRenderer.java

I see this being huge since I'm having trouble getting the context I need for my current approach. I was earnestly going to use what I've learned on replacing the player model to replace most entity models so I'm pretty excited for this discovery.

Posted (edited)

I can't delete comments so just gonna edit this later when I figure out or fail at using geckolib for this

Edited by Shipwrecker
double posted due to connection issue
Posted (edited)

So the geckolib GeoReplacedEntityRenderer doesn't work on the player by default. But I figured out how to use mixins to let me use it on the player entity anyways. 

This still requires geckolib and using mixins so maybe it ain't the best approach but it's gonna be mega easy to work on animations, custom armor layers, and all sorts of other stuff. Compat with other mods with the mixins ain't a huge issue to me though since changing the player model already probably does that anyway.

Maybe the mixin approach was the missing step for regular forge player rendering. However, I'm past that point and don't really care enough to forego my solution to throw myself at a problem that is now irrelevant. It would be nice to know though.


Regardless; I figured out a solution that works for me! Hooray!

Edited by Shipwrecker

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Welcome to our exclusive guide on the Temu coupon code 100€ off — your ticket to massive savings on your next Temu purchase! Whether you're a new shopper or a loyal customer, the acr639380 coupon code is specially designed to deliver premium discounts, free shipping, and bonus perks across European nations. Ready to score incredible deals? Let’s dive in.  What Is The Coupon Code For Temu 100€ Off? Looking for unbeatable savings on your Temu orders? We’ve got you covered! The Temu coupon 100€ off and 100€ off Temu coupon work flawlessly for both new and existing customers throughout Europe. Here’s what you can unlock with our exclusive code: Coupon Code Benefits acr639380 Flat 100€ off on your purchase acr639380 100€ coupon pack for multiple use acr639380 100€ flat discount for new customers acr639380 Extra 100€ promo for existing customers acr639380 Valid for European shoppers (Germany, France, Italy, Switzerland & more)  Temu Coupon Code 100€ Off for New Users in 2025 New to Temu? You’re in for a treat! With our Temu coupon 100€ off and Temu coupon code 100€ off, first-time users get the best value deals available. Check out these awesome perks for 2025: acr639380 — Flat 100€ discount for new users   acr639380 — 100€ coupon bundle for first-time customers   acr639380 — Up to 100€ coupon pack for multiple uses   acr639380 — Free shipping across Europe (Germany, France, Italy, Spain & more)   acr639380 — Extra 30% off on any first-time purchase    How To Redeem The Temu Coupon 100€ Off (acr639380) Getting your Temu 100€ off coupon code activated is super easy. Follow these quick steps and start saving: Download the Temu app or visit Temu.com   Create a new account (if you're a first-time user)   Browse your favorite products and add them to your cart   Proceed to checkout   Enter the coupon code acr639380 in the promo code field   Enjoy your instant 100€ discount and free shipping!    Pro Tip: This 100€ discount bundle can be combined with other Temu offers like 30% off fashion, home, and beauty categories for even more savings.  Latest Verified Temu Discount Codes 2025 You can also use acr639380 with other available Temu deals. Here’s a list you might love: ➥ Temu Discount Code 100€ Off {acr639380}   ➥ Temu Discount Code 90€ Off {acr639380}   ➥ Temu Discount Code 70€ Off {acr639380}   ➥ Temu Discount Code 50€ Off {acr639380}   ➥ Temu Discount Code 40€ Off {acr639380}   ➥ Temu Discount Code 30€ Off {acr639380}   ➥ Temu Discount Code First Order {acr639380}   ➥ Temu Discount Code Existing User {acr639380}   ➥ Temu Discount Code | "$100 off" | [acr639380] New & Existing Customers    Final Note: Use The Latest Temu Coupon Code 100€ Off Don’t miss your chance to save big with our Temu coupon code 100€ off — it’s verified, tested, and trusted for 2025. Whether you’re picking up fashion finds, home essentials, or beauty products, this deal delivers unbeatable value, premium shipping perks, and extra discounts. Use it now and treat yourself to incredible savings!  FAQs: Temu 100€ Off Coupon (acr639380) ✅ Is the Temu coupon code acr639380 valid in all European countries? Yes! It works across Germany, France, Italy, Switzerland, Spain, and other European nations. Enjoy your 100€ discount and free shipping, no matter where you shop from. ✅ How many times can I use the Temu coupon code? The acr639380 coupon code is valid for multiple uses by both new and existing customers. New users get extra perks like bonus discounts and free gifts on their first purchase. ✅ Is there a minimum purchase requirement? No minimum purchase is needed. Apply the acr639380 code on any order value and claim the full 100€ discount instantly. ✅ Does the Temu coupon code have an expiry date? As of now, the acr639380 coupon code has no expiration date. Use it anytime in 2025 for guaranteed savings on your next Temu order. ✅ Do existing customers get the same benefits as new users? While existing customers get slightly different perks, they still enjoy a 100€ discount, free shipping, and exclusive promotions with acr639380.
    • Looking for a fantastic way to save big on your next Temu order? The acr639380 Temu coupon code is exactly what you need! Whether you're shopping from the USA, Canada, or Europe, this code offers unbeatable savings — up to $100 off your next purchase. If you’ve been eyeing something on Temu, now’s the perfect time to grab it with this exclusive offer!  What Is the Coupon Code for Temu $100 Off? Both new and existing customers can benefit from this incredible deal when shopping on the Temu app or website. Just use code acr639380 at checkout to unlock your $100 discount. Here’s what it offers: acr639380: Flat $100 off your next purchase.   acr639380: Receive a $100 coupon pack for multiple uses.   acr639380: New customers get an exclusive $100 off their first purchase.   acr639380: Existing customers can claim an extra $100 off future purchases.   acr639380: Valid in the USA, Canada, and across Europe.    Temu $100 Off Coupon for New Users in 2025 If you're new to Temu, this coupon code is perfect for you. It’s your chance to enjoy huge savings right from your very first order. Here’s what new customers get with acr639380: Flat $100 discount on your first order.   Access to a $100 coupon bundle for multiple purchases.   Stack up to $100 in discounts across various orders.   Free shipping to 68 countries, including the USA, Canada, and UK.   An additional 30% off any item on your first purchase.    How to Redeem the Temu $100 Off Coupon (For New Users) It’s simple! Follow these quick steps: Visit the Temu website or download the Temu app.   Create a new account.   Add your favorite products to your cart.   At checkout, enter the Temu $100 off coupon code: acr639380.   Apply the code, enjoy the savings, and complete your purchase!    Temu Coupon $100 Off for Existing Customers Good news — existing customers aren’t left out! Temu rewards loyal shoppers too. Perks for returning users with acr639380: Get an extra $100 off your next order.   A $100 coupon bundle for multiple future purchases.   Free gifts with express shipping (USA & Canada).   An additional 30% off on any purchase.   Free shipping to 68 countries globally.    How to Use Temu $100 Off Coupon (For Existing Customers) To redeem: Log into your Temu account.   Add your items to the cart.   At checkout, enter acr639380.   Apply the code and enjoy your savings!    Temu $100 Off Coupon for First Orders Your first Temu order just got better with acr639380: $100 off your initial purchase.   Access to exclusive first-time user discounts.   Up to $100 in savings on multiple items.   Free shipping to 68 countries.   Extra 30% off your first order.    Where to Find the Latest Temu $100 Off Coupon Looking for the newest and verified Temu coupon codes? Here’s where you can find them: Temu’s newsletter: Subscribe for email-exclusive deals.   Official Temu social media pages.   Trusted coupon websites.   Community threads like Temu coupon $100 off Reddit where users share legit codes.    Is the Temu $100 Off Coupon Legit? Absolutely — the acr639380 coupon is verified, tested, and 100% legit. It works for both new and existing customers worldwide, with no expiration date. Use it with confidence!  How Does the Temu $100 Off Coupon Work? Simple — enter acr639380 at checkout, and the discount is applied automatically. Whether it’s your first order or a repeat purchase, you’ll enjoy direct savings.  How to Earn Temu $100 Coupons as a New Customer New customers can score extra Temu savings by: Signing up for a new Temu account.   Making your first purchase using acr639380.   Watching for special promotions and email deals.   Checking Temu’s homepage for limited-time coupon bundles.    Advantages of Using the Temu $100 Off Coupon Here’s what makes this coupon so appealing: Flat $100 discount on first-time and future orders.   $100 coupon bundle for multiple uses.   Up to 90% off popular products.   Extra 30% off for existing customers.   Free gifts for new users.   Free shipping to 68 countries, including the USA, UK, and Canada.    Temu $100 Discount Code + Free Gift for Everyone Both new and existing customers get added perks: $100 off your first order.   An extra 30% off any product.   Free gifts on first purchases.   Up to 90% off select deals on the Temu app.   Free shipping to 68 countries.    Pros and Cons of Using the Temu Coupon Code $100 Off in 2025 Pros: Massive $100 discount.   Up to 90% off on select items.   Free global shipping to 68 countries.   30% off bonus for existing users.   Verified, legit, and no expiration date.   Cons: Free shipping limited to select countries.   Some exclusions may apply to already discounted items.    Terms and Conditions (2025) No expiration date.   Valid in 68 countries.   No minimum spend required.   Applicable for multiple purchases.   Some product exclusions may apply.    Final Note: Don’t Miss Out on the $100 Temu Coupon If you’re shopping on Temu, don’t leave money on the table. Use coupon code acr639380 to unlock $100 off, free shipping, extra discounts, and exclusive perks. It’s one of the easiest ways to make your shopping spree even more rewarding.  FAQs: Temu $100 Off Coupon Q: Is the $100 off coupon available for both new and existing customers? A: Yes! Both can use acr639380 for amazing discounts. Q: How do I redeem the Temu $100 coupon? A: Enter acr639380 at checkout to instantly save $100. Q: Does the Temu coupon expire? A: No — this coupon currently has no expiration date. Q: Can the coupon be used for multiple purchases? A: Yes, the $100 off coupon and bundle can apply to multiple orders. Q: Does it work for international users? A: Absolutely! It’s valid in 68 countries, including the USA, Canada, and Europe.
    • Yes that’s the full log, I managed to get it working last night, the anvil fix mod is what was causing it to crash
    • Hey guys, i'm currently developping a mod with forge 1.12.2 2860 and i'm using optifine and gradle 4.9. The thing is i'm trying to figure out how to show the player's body in first person. So far everything's going well since i've try to use a shader. The player's body started to blink dark when using a shader. I've try a lot of shader like chocapic, zeus etc etc but still the same issue. So my question is : How should i apply the current shader to the body ? At the same time i'm also drawing a HUD so maybe it could be the problem?   Here is the issue :    And here is the code where i'm trying to display the body :    private static void renderFirstPersonBody(EntityPlayerSP player, float partialTicks) { Minecraft mc = Minecraft.getMinecraft(); GlStateManager.pushMatrix(); GlStateManager.pushAttrib(); try { // Préparation OpenGL GlStateManager.enableDepth(); GlStateManager.depthMask(true); GlStateManager.enableAlpha(); GlStateManager.alphaFunc(GL11.GL_GREATER, 0.1F); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // Éclairage correct pour shaders GlStateManager.enableLighting(); RenderHelper.enableStandardItemLighting(); GlStateManager.enableRescaleNormal(); // Active la lightmap pour les shaders mc.entityRenderer.enableLightmap(); // Position de rendu interpolée double px = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks; double py = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks; double pz = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks; GlStateManager.translate( px - mc.getRenderManager().viewerPosX, py - mc.getRenderManager().viewerPosY, pz - mc.getRenderManager().viewerPosZ ); // Rendu du joueur sans la tête Render<?> render = mc.getRenderManager().getEntityRenderObject(player); if (render instanceof RenderPlayer) { RenderPlayer renderPlayer = (RenderPlayer) render; boolean oldHeadHidden = renderPlayer.getMainModel().bipedHead.isHidden; boolean oldHeadwearHidden = renderPlayer.getMainModel().bipedHeadwear.isHidden; renderPlayer.getMainModel().bipedHead.isHidden = true; renderPlayer.getMainModel().bipedHeadwear.isHidden = true; setArmorHeadVisibility(renderPlayer, false); renderPlayer.doRender(player, 0, 0, 0, player.rotationYaw, partialTicks); renderPlayer.getMainModel().bipedHead.isHidden = oldHeadHidden; renderPlayer.getMainModel().bipedHeadwear.isHidden = oldHeadwearHidden; setArmorHeadVisibility(renderPlayer, !oldHeadwearHidden); } // Nettoyage post rendu mc.entityRenderer.disableLightmap(); GlStateManager.disableRescaleNormal(); } catch (Exception e) { // silent fail } finally { GlStateManager.popAttrib(); GlStateManager.popMatrix(); } }   Ty for your help. 
    • Item successfully registered, but there was a problem with the texture of the item, it did not insert and has just the wrong texture.     
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.