From ae0c02159ff2fe0f9f2a2ef689da96e8878da9c1 Mon Sep 17 00:00:00 2001 From: mezz Date: Wed, 13 Jul 2016 04:34:05 -0700 Subject: [PATCH 1/2] Force mipmap even if textures are the wrong size --- .../renderer/texture/TextureMap.java.patch | 16 +++++++++++- .../renderer/texture/TextureUtil.java.patch | 26 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch index 73e5da46a..02b60191e 100644 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch @@ -84,7 +84,16 @@ continue; } finally -@@ -129,6 +158,7 @@ +@@ -122,17 +151,18 @@ + + if (lvt_11_2_ < k) + { +- field_147635_d.warn("Texture {} with size {}x{} limits mip level from {} to {}", new Object[] {resourcelocation, Integer.valueOf(textureatlassprite.func_94211_a()), Integer.valueOf(textureatlassprite.func_94216_b()), Integer.valueOf(MathHelper.func_151239_c(k)), Integer.valueOf(MathHelper.func_151239_c(lvt_11_2_))}); +- k = lvt_11_2_; ++ // FORGE: do not lower the mipmap level, just log the problematic textures ++ field_147635_d.warn("Texture {} with size {}x{} will have visual artifacts at mip level {}, it can only support level {}. Please report to the mod author that the texture should be some multiple of 16x16.", resourcelocation, textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b(), MathHelper.func_151239_c(k), MathHelper.func_151239_c(lvt_11_2_)); + } + stitcher.func_110934_a(textureatlassprite); } @@ -92,6 +101,11 @@ int l = Math.min(j, k); int i1 = MathHelper.func_151239_c(l); +- if (i1 < this.field_147636_j) ++ if (false && i1 < this.field_147636_j) // FORGE: do not lower the mipmap level + { + field_147635_d.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", new Object[] {this.field_94254_c, Integer.valueOf(this.field_147636_j), Integer.valueOf(i1), Integer.valueOf(l)}); + this.field_147636_j = i1; @@ -140,9 +170,12 @@ this.field_94249_f.func_147963_d(this.field_147636_j); diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch index cb9c3dc8e..1c5abc42e 100644 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch @@ -1,6 +1,30 @@ --- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java +++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java -@@ -202,9 +202,11 @@ +@@ -83,6 +83,7 @@ + int[] aint1 = aint[l1 - 1]; + int[] aint2 = new int[aint1.length >> 2]; + int j = p_147949_1_ >> l1; ++ if (j > 0) { // FORGE: forcing higher mipmap levels on odd textures needs this check + int k = aint2.length / j; + int l = j << 1; + +@@ -94,6 +95,7 @@ + aint2[i1 + j1 * j] = func_147943_a(aint1[k1 + 0], aint1[k1 + 1], aint1[k1 + 0 + l], aint1[k1 + 1 + l], flag); + } + } ++ } // end if (j > 0) + + aint[l1] = aint2; + } +@@ -168,6 +170,7 @@ + for (int i = 0; i < p_147955_0_.length; ++i) + { + int[] aint = p_147955_0_[i]; ++ if ((p_147955_1_ >> i <= 0) || (p_147955_2_ >> i <= 0)) break; + func_147947_a(i, aint, p_147955_1_ >> i, p_147955_2_ >> i, p_147955_3_ >> i, p_147955_4_ >> i, p_147955_5_, p_147955_6_, p_147955_0_.length > 1); + } + } +@@ -202,9 +205,11 @@ public static void func_180600_a(int p_180600_0_, int p_180600_1_, int p_180600_2_, int p_180600_3_) { From 93a7ac3d89b16f8381e34d9fdb03823ded717d0a Mon Sep 17 00:00:00 2001 From: mezz Date: Wed, 13 Jul 2016 04:34:05 -0700 Subject: [PATCH 2/2] Add TextureDump forge test mod --- .../renderer/texture/TextureMap.java.patch | 12 ++- .../net/minecraftforge/debug/TextureDump.java | 82 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/test/java/net/minecraftforge/debug/TextureDump.java diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch index 02b60191e..a5e2031d3 100644 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch @@ -168,7 +168,7 @@ if (textureatlassprite == null) { -@@ -318,4 +363,42 @@ +@@ -318,4 +363,52 @@ { return this.field_94249_f; } @@ -209,5 +209,15 @@ + public boolean setTextureEntry(TextureAtlasSprite entry) + { + return setTextureEntry(entry.func_94215_i(), entry); ++ } ++ ++ public String getBasePath() ++ { ++ return field_94254_c; ++ } ++ ++ public int getMipmapLevels() ++ { ++ return field_147636_j; + } } diff --git a/src/test/java/net/minecraftforge/debug/TextureDump.java b/src/test/java/net/minecraftforge/debug/TextureDump.java new file mode 100644 index 000000000..a93689eed --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/TextureDump.java @@ -0,0 +1,82 @@ +package net.minecraftforge.debug; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.IntBuffer; + +import javax.imageio.ImageIO; + +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.common.MinecraftForge; + +@Mod(modid = TextureDump.MODID, name = "Forge Texture Atlas Dump", version = TextureDump.VERSION, clientSideOnly = true) +public class TextureDump +{ + public static final String MODID = "forge_texture_dump"; + public static final String VERSION = "1.0"; + + public static final boolean ENABLE = true; + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent event) + { + if (ENABLE) + { + MinecraftForge.EVENT_BUS.register(this); + } + } + + @SubscribeEvent + public void postTextureStitch(TextureStitchEvent.Post e) throws Exception + { + TextureMap map = e.getMap(); + String name = map.getBasePath().replace('/', '_'); + int mip = map.getMipmapLevels(); + saveGlTexture(name, map.getGlTextureId(), mip); + } + + public static void saveGlTexture(String name, int textureId, int mipmapLevels) + { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId); + + GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1); + GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); + + for (int level = 0; level <= mipmapLevels; level++) + { + int width = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_WIDTH); + int height = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_HEIGHT); + int size = width * height; + + BufferedImage bufferedimage = new BufferedImage(width, height, 2); + File output = new File("texture_atlas_dump_" + name + "_mipmap_" + level + ".png"); + + IntBuffer buffer = BufferUtils.createIntBuffer(size); + int[] data = new int[size]; + + GL11.glGetTexImage(GL11.GL_TEXTURE_2D, level, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buffer); + buffer.get(data); + bufferedimage.setRGB(0, 0, width, height, data, 0, width); + + try + { + ImageIO.write(bufferedimage, "png", output); + FMLLog.info("[TextureDump] Exported png to: %s", output.getAbsolutePath()); + } + catch (IOException ioexception) + { + FMLLog.info("[TextureDump] Unable to write: ", ioexception); + } + } + } +}