Pony: Fetch skin texture directly from the GL matrix

This commit is contained in:
Matthew Messinger 2019-06-26 20:12:31 -04:00
parent c57a48065e
commit 50686dd1b4
3 changed files with 34 additions and 78 deletions

View file

@ -1,7 +0,0 @@
package com.minelittlepony.client.ducks;
import net.minecraft.client.texture.NativeImage;
public interface IBufferedTexture {
NativeImage getBufferedImage();
}

View file

@ -1,33 +0,0 @@
package com.minelittlepony.client.mixin;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.PlayerSkinTexture;
import net.minecraft.client.texture.ResourceTexture;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.client.ducks.IBufferedTexture;
@Mixin(PlayerSkinTexture.class)
public abstract class MixinThreadDownloadImageData extends ResourceTexture implements IBufferedTexture {
MixinThreadDownloadImageData() {super(null);}
private NativeImage cachedImage;
@Override
public NativeImage getBufferedImage() {
return cachedImage;
}
@Inject(method = "method_4534("
+ "Lnet/minecraft/client/texture/NativeImage;)V",
at = @At("HEAD"))
private void onSetImage(NativeImage skin, CallbackInfo info) {
cachedImage = new NativeImage(skin.getFormat(), skin.getWidth(), skin.getHeight(), false);
cachedImage.copyFrom(skin);
}
}

View file

@ -3,39 +3,41 @@ package com.minelittlepony.client.pony;
import com.google.common.base.MoreObjects;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.client.PonyRenderManager;
import com.minelittlepony.client.ducks.IBufferedTexture;
import com.minelittlepony.client.render.IPonyRender;
import com.minelittlepony.client.transform.PonyTransformation;
import com.minelittlepony.pony.IPony;
import com.minelittlepony.pony.IPonyData;
import com.minelittlepony.pony.meta.Race;
import com.minelittlepony.pony.meta.Size;
import net.minecraft.block.Material;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.Texture;
import net.minecraft.client.texture.MissingSprite;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.resource.Resource;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.BufferUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
import static com.mojang.blaze3d.platform.GlStateManager.getTexLevelParameter;
import static org.lwjgl.opengl.GL11.*;
@Immutable
public class Pony implements IPony {
@ -61,14 +63,6 @@ public class Pony implements IPony {
}
NativeImage ponyTexture = getBufferedImage(resource);
if (ponyTexture == null) {
ponyTexture = new NativeImage(16, 16, true);
ponyTexture.copyFrom(MissingSprite.getMissingSpriteTexture().getImage());
MinecraftClient.getInstance().getTextureManager().registerTexture(resource, new NativeImageBackedTexture(ponyTexture));
}
return checkSkin(ponyTexture);
}
@ -99,33 +93,35 @@ public class Pony implements IPony {
return null;
}
@Nullable
public static NativeImage getBufferedImage(@Nullable Identifier resource) {
if (resource == null) {
return null;
return MissingSprite.getMissingSpriteTexture().getImage();
}
MinecraftClient mc = MinecraftClient.getInstance();
TextureManager textures = mc.getTextureManager();
// recreate NativeImage from the GL matrix
textures.bindTexture(resource);
int format = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT);
int width = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
int height = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT);
int channels = 4;
if (format == GL_RGB) {
channels = 3;
}
ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * channels);
glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, buffer);
try {
Resource skin = MinecraftClient.getInstance().getResourceManager().getResource(resource);
NativeImage skinImage = NativeImage.fromInputStream(skin.getInputStream());
MineLittlePony.logger.debug("Obtained skin from resource location {}", resource);
return skinImage;
} catch (IOException ignored) {
return NativeImage.fromByteBuffer(buffer);
} catch (IOException e) {
return MissingSprite.getMissingSpriteTexture().getImage();
}
Texture texture = MinecraftClient.getInstance().getTextureManager().getTexture(resource);
if (texture instanceof NativeImageBackedTexture) {
return ((NativeImageBackedTexture)texture).getImage();
}
if (texture instanceof IBufferedTexture) {
return ((IBufferedTexture) texture).getBufferedImage();
}
return null;
}
private IPonyData checkSkin(NativeImage bufferedimage) {