Jump to content

Recommended Posts

Posted (edited)

I have an entity and I want its head to have the texture of the player's head.

I wrote my layer class like this:

public class PlayerHeadLayer extends GeoLayerRenderer<PowerArmorEntity> {

    public PlayerHeadLayer(IGeoRenderer<PowerArmorEntity> entityRenderer) {
        super(entityRenderer);
    }

    @Override
    public void render(PoseStack matrixStackIn, MultiBufferSource bufferIn, int packedLightIn, PowerArmorEntity entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) {
        if(!entity.isInvisible() && entity.isVehicle() && entity.getControllingPassenger() instanceof AbstractClientPlayer clientPlayer ) {
            var texture = clientPlayer.getSkinTextureLocation();
            int overlay = OverlayTexture.NO_OVERLAY;
            var cameo = RenderType.armorCutoutNoCull(texture);
            matrixStackIn.pushPose();
            matrixStackIn.scale(1.0f, 1.0f, 1.0f);
            matrixStackIn.translate(0.0d, 0.0d, 0.0d);
            this.getRenderer().render(
                    this.getEntityModel().getModel(POWER_ARMOR_MODEL_LOCATION),
                    entity,
                    partialTicks,
                    cameo,
                    matrixStackIn,
                    bufferIn,
                    bufferIn.getBuffer(cameo),
                    packedLightIn,
                    overlay,
                    1f, 1f, 1f, 1f);
            matrixStackIn.popPose();
        }
    }
}

But the player texture scale is too big

yqqtKHh.png

Texture of my entity:

3OHWrWV.png

Edited by Jetug
  • Jetug changed the title to How to scale texture?
Posted (edited)
49 minutes ago, ChampionAsh5357 said:

Render the head and the rest of the model separately. Apply the player texture to the head and your texture to the rest of the model. Currently, the head texture is being applied to the entire model.

I understood the logic, but I don't know how to implement it. I'm new to minecraft modding

Edited by Jetug
Posted
23 hours ago, Jetug said:

I understood the logic, but I don't know how to implement it.

Look at how the LivingEntityRenderer sets the texture and repeat the process in your render method. You already have access to the entity model, so you should know how to render it. As how to separate it, either use two separate models or handle the rendering on the same model in two separate methods or implementations.

Posted (edited)
1 hour ago, ChampionAsh5357 said:

Look at how the LivingEntityRenderer sets the texture and repeat the process in your render method. You already have access to the entity model, so you should know how to render it. As how to separate it, either use two separate models or handle the rendering on the same model in two separate methods or implementations.

I decided that it would be easier to do this with the resizing of the player texture and wrote this code while waiting for an answer:

@Override
public void render(PoseStack matrixStackIn, MultiBufferSource bufferIn, int packedLightIn, PowerArmorEntity entity, float limbSwing, float limbSwingAmount, float parti
    if(!entity.isInvisible() && entity.isVehicle() && entity.getControllingPassenger() instanceof AbstractClientPlayer clientPlayer ) {
        var texture = getHeadResourceLocation(clientPlayer, entity);
        if (texture == null) return;
        var cameo = RenderType.armorCutoutNoCull(texture);
        int overlay = OverlayTexture.NO_OVERLAY;
        matrixStackIn.pushPose();
        matrixStackIn.scale(1.0f, 1.0f, 1.0f);
        matrixStackIn.translate(0.0d, 0.0d, 0.0d);
        this.getRenderer().render(
                getEntityModel().getModel(POWER_ARMOR_MODEL_LOCATION),
                entity,
                partialTicks,
                cameo,
                matrixStackIn,
                bufferIn,
                bufferIn.getBuffer(cameo),
                packedLightIn,
                overlay,
                1f, 1f, 1f, 1f);
        matrixStackIn.popPose();
    }
}
                   
@Nullable
private ResourceLocation getHeadResourceLocation(AbstractClientPlayer clientPlayer, PowerArmorEntity entity) {
    var tag = clientPlayer.getUUID().toString();
    if (playerTextures.containsKey(tag)) {
        return playerTextures.get(tag);
    } else {
        var playerHead = getPlayerHead(clientPlayer);
        var entityTextureRL = entityRenderer.getTextureLocation(entity);
        var entityTexture = resourceToBufferedImage(entityTextureRL);
        if (playerHead == null || entityTexture == null) return null;
        playerHead = extendImage(playerHead, entityTexture.getWidth(), entityTexture.getHeight());
        var nativeImage = getNativeImage(playerHead);
        var dynamicTexture = new DynamicTexture(nativeImage);
        var finalTextureLocation = new ResourceLocation(Global.MOD_ID, tag);
        Minecraft.getInstance().getTextureManager().register(finalTextureLocation, dynamicTexture);
        playerTextures.put(tag, finalTextureLocation);
        return finalTextureLocation;
    }
}

And it actually worked, but Steve looks like he's turned into a vampire

XDbT0tH.png

I think the problem is in this method:

public static NativeImage getNativeImage(BufferedImage img) {
    NativeImage nativeImage = new NativeImage(img.getWidth(), img.getHeight(), true);
    for (int x = 0; x < img.getWidth(); x++) {
        for (int y = 0; y < img.getHeight(); y++) {
            var color = img.getRGB(x, y);
            nativeImage.setPixelRGBA(x, y, color);
        }
    }
    return nativeImage;
}

Full code: https://github.com/Jetug/PowerArmorMod/blob/1.18/src/main/java/com/jetug/power_armor_mod/client/render/layers/PlayerHeadLayer.java

Edited by Jetug
Posted
23 minutes ago, Jetug said:

I decided that it would be easier to do this with the resizing of the player texture

That's a lot harder. You literally just need two models or simply render the head part manually with the applied texture. And then you just need to create the rendertype with the texture twice. It's literally just what the LivingEntityRenderer is doing twice.

26 minutes ago, Jetug said:

I think the problem is in this method:

The pixel information is stored in BGRA format, so that makes sense.

  • Thanks 1
Posted
2 hours ago, ChampionAsh5357 said:

That's a lot harder. You literally just need two models or simply render the head part manually with the applied texture. And then you just need to create the rendertype with the texture twice. It's literally just what the LivingEntityRenderer is doing twice.

The pixel information is stored in BGRA format, so that makes sense.

Maybe harder but i already did it :) Anyway thank you, I corrected the method and now it works

    public static NativeImage getNativeImage(BufferedImage img) {
        NativeImage nativeImage = new NativeImage(img.getWidth(), img.getHeight(), true);
        for (int x = 0; x < img.getWidth(); x++) {
            for (int y = 0; y < img.getHeight(); y++) {
                int clr = img.getRGB(x, y);
                int alpha = (clr & 0xff000000) >> 24;
                int red =   (clr & 0x00ff0000) >> 16;
                int green = (clr & 0x0000ff00) >> 8;
                int blue =   clr & 0x000000ff;

                int rgb = alpha;
                rgb = (rgb << 8) + blue;
                rgb = (rgb << 8) + green;
                rgb = (rgb << 8) + red;

                nativeImage.setPixelRGBA(x, y, rgb);
            }
        }
        return nativeImage;
    }

 

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



×
×
  • Create New...

Important Information

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