Jump to content

Custom Texture Loading From Outside The Mod's JAR


Smyler

Recommended Posts

Hi,

I am doing a web map client inside Minecraft, and I am facing a problem.

This kind of maps uses 256*256 tiles which I download from the internet at run time and save to a directory inside the .minecraft directory. I then need to render them on a GUI in the game, and that's were the problem is: I can't get how I am supposed to properly load a texture from a given file BufferedImage (bypassing the minecraft ResourceLocation system). I  believe I do not fully understand how Minecraft handles texture handling, could someone explain it?

 

This is what I am currently doing:

public class TileTexture extends SimpleTexture{

	//A class holding informations about the tile (position, zoom level, and a BufferedImage (which is the texture I need)
	protected ImageWebTile tile;
	
	
	/**
	 * @param textureResourceLocation
	 */
	public TileTexture(ResourceLocation textureResourceLocation, ImageWebTile tile) {
		super(textureResourceLocation);
		this.tile = tile;
	}
	
	
	@Override
	public void loadTexture(IResourceManager resourceManager) throws IOException{
		
        this.deleteGlTexture();

        BufferedImage bufferedimage = tile.getImage();
        TextureUtil.uploadTextureImageAllocate(this.getGlTextureId(), bufferedimage, false, false);
      
	}
	
	

}

 

public class GuiTiledMap extends Gui{
	
	//FIXME MEMORY LEAK

	/*
	 * The position of the map on the GUI
	 */
	protected int x;
	protected int y;
	
	/*
	 * Its dimensions
	 */
	protected int width;
	protected int height;
	
	protected boolean visible;
	protected boolean hovered;
	
	protected TiledMap<?> map; //An object representing the map itself
	
	// Delta of the position of the map (in pixel)
	protected long upperLeftX;
	protected long upperLeftY;
	
	protected float zoomLevel;
	
	public GuiTiledMap(int x, int y, int width, int height, TiledMap<?> map) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.visible = true;
		this.hovered = false;
		this.map = map;
		this.zoomLevel = map.getZoomLevel();
		this.upperLeftX = 0;
		this.upperLeftY = 0;
	}
	
	
	public void draw() {
		
		this.handleMouseInput();
		
		Minecraft mc = Minecraft.getMinecraft();
		TextureManager textureManager = mc.getTextureManager();
		
		ImageWebTile upperLeftTile = this.map.getTileAt(this.upperLeftX, this.upperLeftY);
		ImageWebTile tile = upperLeftTile;
		
		int renderSize = getTileRenderSize(tile);
		long maxX = this.upperLeftX + this.width;
		long maxY = this.upperLeftX + this.width;
		
		while(tile.getY() * renderSize < maxY) {
			
            //The problem is here, I need to reload the texture into the same resource location everytime, which is far from ideal
			textureManager.bindTexture(tile.getTexture()); 
			drawModalRectWithCustomSizedTexture(
					(int)(this.x + tile.getX() * renderSize - this.upperLeftX),
					(int)(this.y + tile.getY() * renderSize - this.upperLeftY),
					0, 0,
					renderSize,
					renderSize,
					renderSize,
					renderSize);
			
			if(tile.getX() * renderSize + renderSize >= maxX)
				tile = this.map.getTile(upperLeftTile.getX(), tile.getY() + 1);
			else
				tile = this.map.getTile(tile.getX() + 1, tile.getY());
			renderSize = getTileRenderSize(tile);
			
		}
		
	}
	
    /**
     * Handles mouse input.
     */
    public void handleMouseInput(){
    	
        int i = Mouse.getDWheel();
        float z;

        if (i != 0){
        	
            if (i > 0) z = 0.1f;
            else z = -0.1f;

            this.zoom(z);
            
            IRLW.logger.info(this.zoomLevel);
        }
    }
    
    public void zoom(float val) {
    	if(this.zoomLevel + val > 0) this.zoomLevel += val;
    	this.setTiledMapZoom();
    }
    
    private void setTiledMapZoom() {
    	this.map.setZoomLevel((int)this.zoomLevel);
    }
    
    public int getTileRenderSize(ImageWebTile tile) {
    	float factor = this.zoomLevel - (float)tile.getZoom();
    	int size = (int) (Math.pow(2, factor) * tile.getSideSize());
    	return size / 2;
    }
	
}

 

public abstract class ImageWebTile implements Cachable {

	protected int x;
	protected int y;
	protected int zoom;
	protected int[] defaultPixel = {0, 0, 0, 0}; //What to return when the tile doesn't exist but should
	protected int size;
	protected BufferedImage image;
	protected ResourceLocation texture = null;
	

	public ImageWebTile(int size, int x, int y, int zoom) {

		this.x = x;
		this.y = y;
		this.zoom = zoom;
		this.size = size;

	}


	public ImageWebTile(int size, int x, int y, int zoom, int[] defaultPixel) {

		this(size, x, y, zoom);
		this.defaultPixel = defaultPixel;

	}


	@Override
	public abstract URL getURL();


	@Override
	public abstract String getFileName();


	public BufferedImage getImage() throws IOException, InvalidMapboxSessionException {
		
      	//Loads the BufferedImage if needed
      
		return this.image;
	}
	
	public ResourceLocation getTexture() {
      
		if(true) { //TODO TEMP
          
        //I want to do something like this to avoid reloading the texture at each frame
		//if(this.texture == null) {
			
          	//This displays the debug texture (ping and black)
			//this.texture = new ResourceLocation(IRLW.MOD_ID, "textures/gui/maps/" + this.x + "/" + this.y + "/" + this.zoom);
          
          	//But this works (the file exists)
			this.texture = new ResourceLocation(IRLW.MOD_ID, "textures/gui/worldmap.png");
          
			Minecraft mc = Minecraft.getMinecraft();
			TextureManager textureManager = mc.getTextureManager();
			textureManager.loadTexture(this.texture, new TileTexture(this.texture, this));
		}
		return this.texture;
		//TODO We should be able to unload textures, there is a big memory leak there
	}
	
	
	///// Various uninteresting getters and setters from here /////

}

 

Just tell me if want a git repo, I just haven't make one yet as it is still very early development.

 

I think a solution would be to have a custom ResourceLocation, but I currently can't find out how to that.

 

Thanks in advance!

Edited by Smyler
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.