Jump to content

Loading & Rendering Item Texture during Run Time


CAS_ual_TY

Recommended Posts

Hello,

 

I am currently working on bringing a trading card game to minecraft. Informations are read from public online APIs, including the cards' look.

 

The card images are being downloaded when the player can see the respective card. Alternatively I could also implement a downloading of all images beforehand, but there are quite a lot of cards out there so I would prefer not to do it that way.

 

Which brings me to my point: How do I render an external texture for my item?

 

I followed the structure of this: https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe15_item_dynamic_item_model

 

I have the location of the File/BufferedImage but I do not know how to load it in, without reloading all textures.

 

Code of the IBakedModel that is being called once the texture is downloaded and ready (I think it is pretty obvious that I have no idea how to do it, the code was just an experiment):

 

public class CardIBakedModelCardID implements IBakedModel
{
	public IBakedModel modelMain;
	private int cardID;
	private List<BakedQuad> list = null;
	
	public CardIBakedModelCardID(IBakedModel modelMain, int cardID, BufferedImage image)
	{
		this.modelMain = modelMain;
		this.cardID = cardID;
	}
	
	@Override
	public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
	{
		if(this.list == null)
		{
			this.list = new ArrayList<BakedQuad>();
			List<BakedQuad> list2 = this.modelMain.getQuads(state, side, rand);
			
			for(BakedQuad quad : list2)
			{
				Minecraft mc = Minecraft.getMinecraft();
				DynamicTexture dt = new DynamicTexture(Main.getImageForID(this.cardID));
				ResourceLocation rl = mc.getTextureManager().getDynamicTextureLocation(Main.MOD_ID + ":" + "card" + this.cardID, dt);
				TextureAtlasSprite tas = mc.getTextureMapBlocks().registerSprite(rl);
				this.list.add(new BakedQuadRetextured(quad, tas));
			}
		}
		
		return this.list;
	}

	@Override
	public boolean isAmbientOcclusion() {
		return this.modelMain.isAmbientOcclusion();
	}

	@Override
	public boolean isGui3d() {
		return this.modelMain.isGui3d();
	}

	@Override
	public boolean isBuiltInRenderer() {
		return false;
	}

	@Override
	public TextureAtlasSprite getParticleTexture() {
		return this.modelMain.getParticleTexture();
	}

	@Override
	public ItemOverrideList getOverrides() {
		throw new UnsupportedOperationException("The finalised model does not have an override list.");
	}
}

 

Everything else is working already, this code is also being called, but the texture ingame is simply nothing / transparent.

 

I hope someone can help me and everything I thought out is possible.

 

Thanks in advance!

Edited by CAS_ual_TY
Link to comment
Share on other sites

Thanks! Kinda what I expected.

 

Almost everything seems to be working, I still have a problem however, It doesnt seem like my textures get loaded from outside the jar. I am getting an error that these textures could not be found. Anyone got any idea?

 

	@SubscribeEvent
	public void stitcherEventPre(TextureStitchEvent.Pre event)
	{
		File[] images = this.cardImageDir.listFiles();
		
		for(File f : images)
		{
			try
			{
				Minecraft mc = Minecraft.getMinecraft();
				DynamicTexture dt = new DynamicTexture(ImageIO.read(f));
				ResourceLocation rl = mc.getTextureManager().getDynamicTextureLocation(TCG.MOD_ID + ":" + "card_" + f.getName().replace("_1.png", ""), dt);
				TextureAtlasSprite tas = event.getMap().registerSprite(rl);
				System.out.println(tas.getIconName()); //TODO debug
				System.out.println("");
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: The following texture errors were found.
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: ==================================================
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:   DOMAIN dynamic/tcg
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: --------------------------------------------------
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:   domain dynamic/tcg is missing 20 textures
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:     domain dynamic/tcg is missing a resource manager - it is probably a side-effect of automatic texture processing
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: -------------------------
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:     The missing resources for domain dynamic/tcg are:
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_34541863_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_44256816_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_295517_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_91231901_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_86198326_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_73262676_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_14261867_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_21597117_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_49140998_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_8949584_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_83994646_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_67048711_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_86988864_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_64163367_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_68170903_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_23771716_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_24140059_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_57769391_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_6850209_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:       textures/card_11714098_1.png
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: -------------------------
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]:     No other errors exist for domain dynamic/tcg
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: ==================================================
[19:10:09] [main/ERROR] [FML.TEXTURE_ERRORS]: +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

 

Link to comment
Share on other sites

IRessourcePack is literally a dream when it comes to this, thanks! Everything works now. Did I "register" (add) the rp correctly? (I know, the field_xxx String is missing. you wouldnt know it by any chance?)

 

EDIT: Unless it got changed it is getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "defaultResourcePacks", "field_110449_ao", "ap") I think

 

For people who will google this:

 

public class ResourcePackCards implements IResourcePack
{
	private File cardImageDir;
	
	public ResourcePackCards(File cardImageDir)
	{
		this.cardImageDir = cardImageDir;
	}
	
	@Override
	public InputStream getInputStream(ResourceLocation location) throws IOException
	{
		return new FileInputStream(new File(this.cardImageDir.getAbsolutePath() + "/" + location.getResourcePath().replace("textures/", "")));
	}
	
	@Override
	public boolean resourceExists(ResourceLocation location)
	{
		return new File(this.cardImageDir.getAbsolutePath() + "/" + location.getResourcePath().replace("textures/", "")).exists();
	}
	
	@Override
	public Set<String> getResourceDomains()
	{
		return ImmutableSet.<String>of(Main.MOD_ID);
	}
	
	@Override
	public <T extends IMetadataSection> T getPackMetadata(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException
	{
		return null;
	}
	
	@Override
	public BufferedImage getPackImage() throws IOException
	{
		return TextureUtil.readBufferedImage(DefaultResourcePack.class.getResourceAsStream("/" + (new ResourceLocation("pack.png")).getResourcePath()));
	}
	
	@Override
	public String getPackName()
	{
		return "Cards Images";
	}
	
}
//in preInit (client side only)
List<IResourcePack> defaultResourcePacks = null;
defaultResourcePacks = ReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "defaultResourcePacks");
defaultResourcePacks.add(new ResourcePackCards(this.cardImageDir));
Minecraft.getMinecraft().refreshResources();

 

Edited by CAS_ual_TY
Link to comment
Share on other sites

1 hour ago, diesieben07 said:

Do not call refreshResources, other than that it looks fine.

If I dont call it I get missing texture errors.

 

Also, currently I am loading in exactly 8313 textures. When using 128x128 textures everything works fine. When using 256x256 textures, however, I am getting the bottom error. Does this happen because my PC is too weak or because the texture atlas is too small or rather it can not fit everything?:

 

[15:41:41] [main/INFO] [FML]: Unable to fit: tcg:53100061 - size: 256x256 - Maybe try a lowerresolution resourcepack?
[15:41:41] [main/INFO] [FML]:   Holder{width=512, height=512, name=tcg:items/back}
[15:41:41] [main/INFO] [FML]:   Holder{width=256, height=256, name=tcg:10000002}
[15:41:41] [main/INFO] [FML]:   Holder{width=256, height=256, name=tcg:10000010}
[15:41:41] [main/INFO] [FML]:   Holder{width=256, height=256, name=tcg:10000022}
... //I removed like 9k lines here
[15:41:41] [main/INFO] [FML]:   Holder{width=16, height=16, name=minecraft:items/wooden_armorstand}
[15:41:41] [main/INFO] [FML]:   Holder{width=16, height=16, name=minecraft:white}
[15:41:41] [main/INFO] [FML]:   Holder{width=16, height=16, name=missingno}
[15:41:41] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ----
// On the bright side, I bought you a teddy bear!

Time: 4/16/18 3:41 PM
Description: Initializing game

net.minecraft.client.renderer.StitcherException: Unable to fit: tcg:53100061 - size: 256x256 - Maybe try a lowerresolution resourcepack?
	at net.minecraft.client.renderer.texture.Stitcher.doStitch(Stitcher.java:71)
	at net.minecraft.client.renderer.texture.TextureMap.finishLoading(TextureMap.java:213)
	at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:112)
	at net.minecraft.client.renderer.texture.TextureMap.loadSprites(TextureMap.java:91)
	at net.minecraftforge.client.model.ModelLoader.setupModelRegistry(ModelLoader.java:172)
	at net.minecraft.client.renderer.block.model.ModelManager.onResourceManagerReload(ModelManager.java:28)
	at net.minecraft.client.resources.SimpleReloadableResourceManager.registerReloadListener(SimpleReloadableResourceManager.java:121)
	at net.minecraft.client.Minecraft.init(Minecraft.java:559)
	at net.minecraft.client.Minecraft.run(Minecraft.java:421)
	at net.minecraft.client.main.Main.main(Main.java:118)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
	at GradleStart.main(GradleStart.java:25)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Client thread
Stacktrace:
	at net.minecraft.client.renderer.texture.Stitcher.doStitch(Stitcher.java:71)
	at net.minecraft.client.renderer.texture.TextureMap.finishLoading(TextureMap.java:213)
	at net.minecraft.client.renderer.texture.TextureMap.loadTextureAtlas(TextureMap.java:112)
	at net.minecraft.client.renderer.texture.TextureMap.loadSprites(TextureMap.java:91)
	at net.minecraftforge.client.model.ModelLoader.setupModelRegistry(ModelLoader.java:172)
	at net.minecraft.client.renderer.block.model.ModelManager.onResourceManagerReload(ModelManager.java:28)
	at net.minecraft.client.resources.SimpleReloadableResourceManager.registerReloadListener(SimpleReloadableResourceManager.java:121)
	at net.minecraft.client.Minecraft.init(Minecraft.java:559)

-- Initialization --
Details:
Stacktrace:
	at net.minecraft.client.Minecraft.run(Minecraft.java:421)
	at net.minecraft.client.main.Main.main(Main.java:118)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
	at GradleStart.main(GradleStart.java:25)

-- System Details --
Details:
	Minecraft Version: 1.12.2
	Operating System: Windows 10 (amd64) version 10.0
	Java Version: 1.8.0_161, Oracle Corporation
	Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
	Memory: 5278637096 bytes (5034 MB) / 8520204288 bytes (8125 MB) up to 8520204288 bytes (8125 MB)
	JVM Flags: 3 total; -Xincgc -Xmx8192M -Xms8192M
	IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
	FML: MCP 9.42 Powered by Forge 14.23.2.2635 5 mods loaded, 5 mods active
	States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored

	| State | ID        | Version      | Source                           | Signature |
	|:----- |:--------- |:------------ |:-------------------------------- |:--------- |
	| UCH   | minecraft | 1.12.2       | minecraft.jar                    | None      |
	| UCH   | mcp       | 9.42         | minecraft.jar                    | None      |
	| UCH   | FML       | 8.0.99.99    | forgeSrc-1.12.2-14.23.2.2635.jar | None      |
	| UCH   | forge     | 14.23.2.2635 | forgeSrc-1.12.2-14.23.2.2635.jar | None      |
	| UCH   | tcg   | 0.1-1.12.2   | bin                              | None      |

	Loaded coremods (and transformers): 
	GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.6.0 NVIDIA 390.77' Renderer: 'GeForce GTX 1070/PCIe/SSE2'
	Launched Version: 1.12.2
	LWJGL: 2.9.4
	OpenGL: GeForce GTX 1070/PCIe/SSE2 GL version 4.6.0 NVIDIA 390.77, NVIDIA Corporation
	GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.

	Using VBOs: Yes
	Is Modded: Definitely; Client brand changed to 'fml,forge'
	Type: Client (map_client.txt)
	Resource Packs: 
	Current Language: English (US)
	Profiler Position: N/A (disabled)
	CPU: 8x Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
[15:41:41] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: #@!@# Game crashed! Crash report saved to: #@!@# C:\Minecraft Coding 1.12.2\run\.\crash-reports\crash-2018-04-16_15.41.41-client.txt

 

Link to comment
Share on other sites

3 hours ago, diesieben07 said:

Then you did not register it early enough.

Im doing it at the end of preInit. Which event would I need then?

 

3 hours ago, diesieben07 said:

Your (and probably most other) graphics cards cannot support a texture that size (over 2,000,000 pixels squared...). Why are you loading that many block textures? O.o

Well, as I said, trading card game with 8313 cards so far. By default, all cards have the same look in their Item form (all use the back side). But you can enable an option, which, instead, lets every single card item use the respective texture. Additionally, you can choose the size of these textures (default: 128).

In the playing GUI, cards are always using the correct picture.

 

Spoiler

https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/wip-mods/2899860-ygo-dueling-mod-adding-all-ygo-cards-to-mc-duel

In case you are still wondering, now youd get the rough idea. Spoiler because I am not a fan of advertising in support forums.

 

Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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