package ttftcuts.physis.common.helper; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.nio.IntBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.imageio.ImageIO; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import ttftcuts.physis.Physis; import ttftcuts.physis.client.texture.DigSiteAtlasSprite; import ttftcuts.physis.client.texture.PhysisAbstractTexture; import ttftcuts.physis.client.texture.PhysisAtlasSprite; import ttftcuts.physis.utils.ColourBrightnessComparator; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.client.shader.Framebuffer; import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.ForgeHooksClient; public class TextureHelper { public static ResourceLocation loadTexture(String location, ITextureObject texture) { ResourceLocation resource = new ResourceLocation(Physis.MOD_ID, location); Minecraft.getMinecraft().getTextureManager().loadTexture(resource, texture); return resource; } public static IIcon buildDigSprite(TextureMap map, String iconname, String base, String[] layernames, ResourceLocation[] layers) { String name = DigSiteAtlasSprite.getDerivedName(iconname, base, layernames); TextureAtlasSprite texture = map.getTextureExtry(name); if (texture == null) { texture = new DigSiteAtlasSprite(iconname, base, layernames, layers); map.setTextureEntry(name, texture); } return map.getTextureExtry(name); } public static BufferedImage getImageForResource(ResourceLocation resource) throws IOException{ ITextureObject texob = Minecraft.getMinecraft().getTextureManager().getTexture(resource); if( texob instanceof PhysisAbstractTexture) { return ((PhysisAbstractTexture)texob).generatedImage; } else { InputStream layer = Minecraft.getMinecraft().getResourceManager().getResource(resource).getInputStream(); return ImageIO.read(layer); } } public static Map<String, TextureAtlasSprite> addedItemIcons; public static Map<String, TextureAtlasSprite> addedBlockIcons; public static IIcon getIconForDynamicResource(TextureMap map, String resourcename, ResourceLocation resource, boolean item) { if (addedItemIcons == null) { addedItemIcons = new HashMap<String, TextureAtlasSprite>(); } if (addedBlockIcons == null) { addedBlockIcons = new HashMap<String, TextureAtlasSprite>(); } Map<String, TextureAtlasSprite> iconlist = item ? addedItemIcons : addedBlockIcons; TextureAtlasSprite texture = new PhysisAtlasSprite(resourcename, resource); if (iconlist.containsKey(resourcename)) { iconlist.remove(resourcename); } iconlist.put(resourcename, texture); return texture; } public static Framebuffer stackBuffer; public static RenderItem renderItem = new RenderItem(); public static RenderBlocks renderBlocks = new RenderBlocks(); public static BufferedImage getItemStackImage(ItemStack stack) { if (stackBuffer == null) { stackBuffer = new Framebuffer(16,16,true); } Minecraft mc = Minecraft.getMinecraft(); // bind the buffer and such GL11.glPushMatrix(); GL11.glLoadIdentity(); stackBuffer.bindFramebuffer(true); GL11.glClearColor(0, 0, 0, 0); GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); GL11.glOrtho(0.0D, 16, 16, 0.0D, 1000.0D, 3000.0D); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glLoadIdentity(); GL11.glTranslatef(0.0F, 0.0F, -2000.0F); //GL11.glTranslatef(0, 0, -5); GL11.glColor3f(1, 0, 0); // draw image GL11.glPushMatrix(); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); RenderHelper.enableGUIStandardItemLighting(); GL11.glEnable(GL12.GL_RESCALE_NORMAL); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDisable(GL11.GL_ALPHA_TEST); //render.renderItemIntoGUI(mc.fontRenderer, mc.getTextureManager(), stack, 0, 0); renderItem.zLevel += 50; try { if (!ForgeHooksClient.renderInventoryItem(renderBlocks, mc.getTextureManager(), stack, true, renderItem.zLevel, (float)0, (float)0)) { renderItem.renderItemIntoGUI(mc.fontRenderer, mc.getTextureManager(), stack, 0, 0, false); } } catch(Exception e) {} renderItem.zLevel -= 50; RenderHelper.disableStandardItemLighting(); GL11.glEnable(GL11.GL_ALPHA_TEST); GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glDisable(GL11.GL_BLEND); GL11.glPopMatrix(); // set back to normal stackBuffer.unbindFramebuffer(); GL11.glPopMatrix(); // dump to image int width = 16; int height = 16; int length = width * height; IntBuffer data = BufferUtils.createIntBuffer(length); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1); GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); GL11.glBindTexture(GL11.GL_TEXTURE_2D, stackBuffer.framebufferTexture); GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, data); int[] dataarray = new int[length]; data.get(dataarray); TextureUtil.func_147953_a(dataarray, 16, 16); int l = stackBuffer.framebufferTextureHeight - stackBuffer.framebufferHeight; image.setRGB(0, 0, 16, 16, dataarray, 0, 16); for (int i1 = l; i1 < stackBuffer.framebufferTextureHeight; ++i1) { for (int j1 = 0; j1 < stackBuffer.framebufferWidth; ++j1) { image.setRGB(j1, i1 - l, dataarray[i1 * stackBuffer.framebufferTextureWidth + j1]); } } // send out the image return image; } public static BufferedImage scaleBufferedImage(BufferedImage original, double ratio) { int newWidth = new Double(original.getWidth() * ratio).intValue(); int newHeight = new Double(original.getHeight() * ratio).intValue(); BufferedImage resized = new BufferedImage(newWidth, newHeight, original.getType()); Graphics2D g = resized.createGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(original, 0, 0, newWidth, newHeight, 0, 0, original.getWidth(), original.getHeight(), null); g.dispose(); return resized; } public static List<Integer> getImageColourRange(BufferedImage image) { List<Integer> collist = new ArrayList<Integer>(); int w = image.getWidth(); int h = image.getHeight(); int len = w*h; int[] data = new int[len]; image.getRGB(0, 0, w, h, data, 0, w); int col, a; for(int i=0; i<len; i++) { col = data[i]; a = alpha(col); if (a > 0) { collist.add(col); } } Collections.sort(collist, new ColourBrightnessComparator()); return collist; } public static int getAverageColour(List<Integer> colours) { double r = 0; double g = 0; double b = 0; int a = 0; int col; int count = colours.size(); double ir,ig,ib; for (int i=0; i<count; i++) { col = colours.get(i); ir = red(col) / 255.0; r += ir*ir; ig = green(col) / 255.0; g += ig*ig; ib = blue(col) / 255.0; b += ib*ib; a += alpha(col); } int fr = (int)(Math.sqrt(r / count) * 255.0); int fg = (int)(Math.sqrt(g / count) * 255.0); int fb = (int)(Math.sqrt(b / count) * 255.0); return compose(fr, fg, fb, a / count); } public static int getPerceptualBrightness(int col) { double r = red(col) / 255.0; double g = green(col) / 255.0; double b = blue(col) / 255.0; double brightness = Math.sqrt(0.241 * r*r + 0.691 * g*g + 0.068 * b*b); return (int)(brightness*255); } // Bitwise colour ops! public static int compose(int r, int g, int b, int a) { int rgb = a; rgb = (rgb << 8) + r; rgb = (rgb << 8) + g; rgb = (rgb << 8) + b; return rgb; } public static int compose(int[] col) { int r = col[0]; int g = col[1]; int b = col[2]; int a = col.length > 3 ? col[3] : 255; return compose(r,g,b,a); } public static int alpha(int c) { return (c >> 24) & 0xFF; } public static int red(int c) { return (c >> 16) & 0xFF; } public static int green(int c) { return (c >> 8) & 0xFF; } public static int blue(int c) { return (c) & 0xFF; } protected static int mult(int c1, int c2) { return (int)(c1 * (c2/255.0)); } protected static double hue2rgb(double p, double q, double t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1/6.0) return p + (q - p) * 6 * t; if (t < 1/2.0) return q; if (t < 2/3.0) return p + (q - p) * (2/3.0 - t) * 6; return p; } public static int[] hsl2rgb(double h, double s, double l) { //h *= 360.0; double r,g,b; if (s<=0) { r = g = b = l; } else { double q = l < 0.5 ? l * (1+s) : l + s - l*s; double p = 2 * l - q; r = hue2rgb(p, q, h + 1/3.0); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1/3.0); } return new int[]{(int)Math.round(r * 255), (int)Math.round(g * 255), (int)Math.round(b * 255)}; } public static double[] rgb2hsl(int r, int g, int b) { double dr = r/255.0; double dg = g/255.0; double db = b/255.0; double max = Math.max(dr, Math.max(dg, db)); double min = Math.min(dr, Math.min(dg, db)); double h, s; double l = (max+min)*0.5; if (max == min) { h = 0; s = 0; } else { double d = max - min; s = l > 0.5 ? d / (2.0 - max - min) : d / (max + min); if (max == dr) { h = (dg - db) / d + (dg < db ? 6 : 0); } else if (max == dg) { h = (db - dr) / d + 2; } else { h = (dr - dg) / d + 4; } h /= 6.0; } return new double[]{h,s,l}; } public static double[] rgb2hsl(int colour) { return rgb2hsl(red(colour), green(colour), blue(colour)); } }