Posted March 2, 20187 yr 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 March 2, 20187 yr by Smyler
March 2, 20187 yr Author I found the solution myself, so here it is for anyone which may have a similar problem: use TextureManager::getDynamicTextureLocation(String, BufferredImage)
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.