Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

So the current way I've been using DynamicTextures is causing a constant memory leak as I have to create a new one every 10th of a second.

I am creating the DynamicTexture using a BufferedImage I am creating at run time. My only problem is that I don't know how to update the texture after it has already been created with the initial BufferedImage.

So to fix the memory leak issue, I need some way to either delete the previous DynamicTexture object or reuse the already existing one. I've looked into the MapItemRenderer as it uses the DynamicTexture but I am not sure how to implement this.

 

This is essentially what I currently have:

public static BufferedImage image = new BufferedImage(75, 75, BufferedImage.TYPE_INT_ARGB);
public static DynamicTexture redrawnImage = new DynamicTexture(image);

public static void updateImage() {
	redrawnImage.deleteGlTexture();
	//(re-create the BufferedImage 'image' here)
	redrawnImage = new DynamicTexture(image);
}

 

  • Author

I THINK I fixed it. I looked more into the MapItemRenderer and tried creating my own texture handler based off of it.

 

After running the game for a solid 10 minutes while running the redraw process (an amount of time which would have definitely ate up a bunch of memory by now), the leak seems to have been fixed.

 

This is what I came up with to fix it:

package com.Whodundid.main.util;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;

public class InGameTextureHandler {
	
	private final TextureManager textureManager;
	private final DynamicTexture texture;
	private int[] textureData;
	
	public InGameTextureHandler(TextureManager manager, DynamicTexture textureIn) {
		this.textureManager = manager;
		this.texture = textureIn;
		this.textureData = textureIn.getTextureData();
	}
	
	public void updateTextureData(BufferedImage newImage) {
		int[] newImgData = ((DataBufferInt)newImage.getRaster().getDataBuffer()).getData();
		if (this.textureData.length == newImgData.length) {
			for (int i = 0; i < newImgData.length; i++) {
				this.textureData[i] = newImgData[i];
			}
		}
		this.texture.updateDynamicTexture();
	}
	
	public ResourceLocation getTextureLocation() {
		return textureManager.getDynamicTextureLocation("texture/", texture);
	}
}

 

Then back in the class where I am re-creating the BufferedImage I do:

public static BufferedImage image = new BufferedImage(75, 75, BufferedImage.TYPE_INT_ARGB);
public static DynamicTexture redrawnImage = new DynamicTexture(image);
public static InGameTextureHandler handler = new InGameTextureHandler(Minecraft.getMinecraft.getTextureManager(), redrawnImage);

public static void updateImage() {
	//(re-create the BufferedImage 'image' here)
	handler.updateTextureData(image);
}

 

  • Author

Update:

That does not appear to have fixed it. I am really not sure what is causing it at this point.

 

EDIT:

Tried another thing which actually fixed it:

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;

public class InGameTextureHandler {
	
	private final TextureManager textureManager;
	private final DynamicTexture texture;
	private int[] textureData;
	private ResourceLocation loc;
	
	public InGameTextureHandler(TextureManager manager, DynamicTexture textureIn) {
		this.textureManager = manager;
		this.texture = textureIn;
		this.textureData = textureIn.getTextureData();
		this.loc = textureManager.getDynamicTextureLocation("texture/", texture);
	}
	
	public void updateTextureData(BufferedImage newImage) {
		int[] newImgData = ((DataBufferInt)newImage.getRaster().getDataBuffer()).getData();
		if (this.textureData.length == newImgData.length) {
			for (int i = 0; i < newImgData.length; i++) {
				this.textureData[i] = newImgData[i];
			}
		}
		this.texture.updateDynamicTexture();
	}
	
	public ResourceLocation getTextureLocation() {
		return loc;
	}
}

The problem was that it seemed to be creating a new ResourceLocation every time it returned the texture location. So to fix, I just made one and paired it with the dynamic texture.

Edited by Whodundid

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.