package shadersmodcore.client; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.imageio.ImageIO; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.client.renderer.texture.LayeredTexture; import net.minecraft.client.renderer.texture.Stitcher; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.util.ResourceLocation; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResourceManager; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.ARBTextureStorage; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL14; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL30.*; public class ShadersTex { public static final int initialBufferSize = 1048576; public static ByteBuffer byteBuffer = BufferUtils.createByteBuffer(initialBufferSize*4); public static IntBuffer intBuffer = byteBuffer.asIntBuffer(); public static int[] intArray = new int[initialBufferSize]; public static final int defBaseTexColor = 0x00000000; public static final int defNormTexColor = 0xFF7F7FFF; public static final int defSpecTexColor = 0x00000000; public static Map multiTexMap = new HashMap(); public static TextureMap updatingTextureMap = null; public static TextureAtlasSprite updatingSprite = null; public static MultiTexID updatingTex = null; public static MultiTexID boundTex = null; public static int updatingPage = 0; public static String iconName = null; public static IntBuffer getIntBuffer(int size) { if (intBuffer.capacity() < size) { int bufferSize = roundUpPOT(size); byteBuffer = BufferUtils.createByteBuffer(bufferSize*4); intBuffer = byteBuffer.asIntBuffer(); } return intBuffer; } public static int[] getIntArray(int size) { if (intArray.length < size) { intArray = null; intArray = new int[roundUpPOT(size)]; } return intArray; } public static int roundUpPOT(int x) { int i = x-1; i |= (i>>1); i |= (i>>2); i |= (i>>4); i |= (i>>8); i |= (i>>16); return i+1; } public static IntBuffer fillIntBuffer(int size, int value) { int[] aint = getIntArray(size); IntBuffer intBuf = getIntBuffer(size); Arrays.fill(intArray, 0, size, value); intBuffer.put(intArray, 0, size); return intBuffer; } public static int[] createAIntImage(int size) { int[] aint = new int[size*3]; Arrays.fill(aint, 0, size, defBaseTexColor); Arrays.fill(aint, size, size*2, defNormTexColor); Arrays.fill(aint, size*2, size*3, defSpecTexColor); return aint; } public static int[] createAIntImage(int size, int color) { int[] aint = new int[size*3]; Arrays.fill(aint, 0, size, color); Arrays.fill(aint, size, size*2, defNormTexColor); Arrays.fill(aint, size*2, size*3, defSpecTexColor); return aint; } public static MultiTexID getMultiTexID(AbstractTexture tex) { MultiTexID multiTex = tex.multiTex; if (multiTex==null) { int baseTex = tex.getGlTextureId(); multiTex = multiTexMap.get(Integer.valueOf(baseTex)); if (multiTex == null) { multiTex = new MultiTexID(baseTex, GL11.glGenTextures(), GL11.glGenTextures()); multiTexMap.put(baseTex, multiTex); } tex.multiTex = multiTex; } return multiTex; } public static void deleteTextures(AbstractTexture atex) { int texid = atex.glTextureId; if (texid != -1) { GL11.glDeleteTextures(texid); atex.glTextureId = -1; } MultiTexID multiTex = atex.multiTex; if (multiTex != null) { atex.multiTex = null; multiTexMap.remove(Integer.valueOf(multiTex.base)); GL11.glDeleteTextures(multiTex.norm); GL11.glDeleteTextures(multiTex.spec); if (multiTex.base != texid) { System.err.println("Error : MultiTexID.base mismatch."); GL11.glDeleteTextures(multiTex.base); } } } /** Remove MultiTexID object reference and delete textures */ public static int deleteMultiTex(ITextureObject tex) { if (tex instanceof AbstractTexture) { deleteTextures((AbstractTexture)tex); } else { GL11.glDeleteTextures(tex.getGlTextureId()); } return 0; } public static void bindNSTextures(int normTex, int specTex) { //Shaders.checkGLError("pre bindNSTextures"); if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) { GL13.glActiveTexture(GL13.GL_TEXTURE2); GL11.glBindTexture(GL11.GL_TEXTURE_2D, normTex); GL13.glActiveTexture(GL13.GL_TEXTURE3); GL11.glBindTexture(GL11.GL_TEXTURE_2D, specTex); GL13.glActiveTexture(GL13.GL_TEXTURE0); } //Shaders.checkGLError("bindNSTextures"); } public static void bindNSTextures(MultiTexID multiTex) { bindNSTextures(multiTex.norm, multiTex.spec); } public static void bindTextures(int baseTex, int normTex, int specTex) { //Shaders.checkGLError("pre bindTextures"); if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) { GL13.glActiveTexture(GL13.GL_TEXTURE2); GL11.glBindTexture(GL11.GL_TEXTURE_2D, normTex); GL13.glActiveTexture(GL13.GL_TEXTURE3); GL11.glBindTexture(GL11.GL_TEXTURE_2D, specTex); GL13.glActiveTexture(GL13.GL_TEXTURE0); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, baseTex); //Shaders.checkGLError("bindTextures"); } public static void bindTextures(MultiTexID multiTex) { boundTex = multiTex; if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) { if (Shaders.configNormalMap) { GL13.glActiveTexture(GL13.GL_TEXTURE2); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); } if (Shaders.configSpecularMap) { GL13.glActiveTexture(GL13.GL_TEXTURE3); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec); } GL13.glActiveTexture(GL13.GL_TEXTURE0); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); } public static void bindTexture(ITextureObject tex) { if (tex instanceof TextureMap) { Shaders.atlasSizeX = ((TextureMap)tex).atlasWidth; Shaders.atlasSizeY = ((TextureMap)tex).atlasHeight; } else { Shaders.atlasSizeX = 0; Shaders.atlasSizeY = 0; } bindTextures(tex.getMultiTexID()); } /** not used */ public static void bindTextures(int baseTex) { MultiTexID multiTex = multiTexMap.get(Integer.valueOf(baseTex)); bindTextures(multiTex); } public static void allocTexStorage(int width, int height, int maxLevel) { Shaders.checkGLError("pre allocTexStorage"); int level; for (level=0; (width>>level)>0 && (height>>level)>0 /*&& level<=maxLevel*/; ++level) { GL11.glTexImage2D(GL11.GL_TEXTURE_2D, level, GL11.GL_RGBA, (width>>level), (height>>level), 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null); } GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, level-1); Shaders.checkGLError("allocTexStorage"); //clear unused level otherwise glTexSubImage2D will crash on AMD when reallocation texture of different size. //for ( ; level < 16 ; ++level) { // GL11.glTexImage2D(GL11.GL_TEXTURE_2D, level, GL11.GL_RGBA, 0, 0, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null); //} GL11.glGetError(); // It usually returns error 0x0501 Invalid value for width 0 height 0. Ignore it. } // for Dynamic Texture public static void initDynamicTexture(int texID, int width, int height, DynamicTexture tex) { MultiTexID multiTex = tex.getMultiTexID(); int[] aint = tex.getTextureData(); int size = width * height; Arrays.fill(aint, size, size*2, defNormTexColor); Arrays.fill(aint, size*2, size*3, defSpecTexColor); // base texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); allocTexStorage(width,height,0); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); // norm texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); allocTexStorage(width,height,0); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); // spec texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec); allocTexStorage(width,height,0); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); // base texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); } public static ITextureObject createDefaultTexture() { DynamicTexture tex = new DynamicTexture(1,1); tex.getTextureData()[0] = 0xffffffff; tex.updateDynamicTexture(); return tex; } // for TextureMap public static void allocateTextureMap(int texID, int mipmapLevels, int width, int height, float anisotropy, Stitcher stitcher, TextureMap tex) { System.out.println("allocateTextureMap "+tex.getTextureType()+" "+mipmapLevels+" "+width+" "+height+" "+anisotropy+" "); updatingTextureMap = tex; tex.atlasWidth = width; tex.atlasHeight = height; MultiTexID multiTex = getMultiTexID(tex); updatingTex = multiTex; TextureUtil.allocateTextureImpl(multiTex.base, mipmapLevels, width, height, anisotropy); if (Shaders.configNormalMap ) TextureUtil.allocateTextureImpl(multiTex.norm, mipmapLevels, width, height, anisotropy); if (Shaders.configSpecularMap) TextureUtil.allocateTextureImpl(multiTex.spec, mipmapLevels, width, height, anisotropy); GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID); } public static TextureAtlasSprite setSprite(TextureAtlasSprite tas) { return updatingSprite = tas; } public static String setIconName(String name) { return iconName = name; } public static void uploadTexSubForLoadAtlas(int[][] data, int width, int height, int xoffset, int yoffset, boolean linear, boolean clamp) { TextureUtil.uploadTextureMipmap(data, width, height, xoffset, yoffset, linear, clamp); boolean border = updatingSprite.useAnisotropicFiltering; int[][] aaint; // if (Shaders.configNormalMap ) { aaint = readImageAndMipmaps(iconName+"_n", width, height, data.length, border, defNormTexColor); GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.norm); TextureUtil.uploadTextureMipmap(aaint, width, height, xoffset, yoffset, linear, clamp); } // if (Shaders.configSpecularMap) { aaint = readImageAndMipmaps(iconName+"_s", width, height, data.length, border, defSpecTexColor); GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec); TextureUtil.uploadTextureMipmap(aaint, width, height, xoffset, yoffset, linear, clamp); } // GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.base); } public static int[][] readImageAndMipmaps(String name, int width, int height, int numLevels, boolean border, int defColor) { int[][] aaint = new int[numLevels][]; int[] aint; aaint[0] = aint = new int[width*height]; boolean goodImage = false; BufferedImage image = readImage(updatingTextureMap.completeResourceLocation(new ResourceLocation(name), 0)); if (image != null) { int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); if (imageWidth + (border? 16: 0) == width) { goodImage = true; image.getRGB(0, 0, imageWidth, imageWidth, aint, 0, imageWidth); if (border) TextureUtil.prepareAnisotropicData(aint, imageWidth, imageWidth, 8); } } if (!goodImage) { Arrays.fill(aint, defColor); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec); aaint = genMipmapsSimple(aaint.length-1, width, aaint); return aaint; } public static BufferedImage readImage(ResourceLocation resLoc) { BufferedImage image = null; InputStream istr = null; try { istr = resManager.getResource(resLoc).getInputStream(); image = ImageIO.read(istr); } catch (IOException e) { } if (istr != null) { try { istr.close(); } catch (IOException e) { } istr = null; } return image; } public static int[][] genMipmapsSimple(int maxLevel, int width, int[][]data) { int level; for (level=1; level<=maxLevel; ++level) { if (data[level]==null) { int cw = width>>level; int pw = cw*2; int[] aintp = data[level-1]; int[] aintc = data[level] = new int[cw*cw]; int x,y; for (y=0; y>> 24) & 255; int a1 = (c1 >>> 24) & 255; int a2 = (c2 >>> 24) & 255; int a3 = (c3 >>> 24) & 255; int as = a0+a1+a2+a3; int an = (as+2)/4; //int an = Math.min(Math.min(Math.min(a0,a1),a2),a3); int dv; if (as != 0) { dv = as; } else { dv=4; a3=a2=a1=a0=1; } int frac = (dv+1)/2; //return (((Math.min(Math.min(Math.min(a0,a1),a2),a3)/ 4) << 24) | int color = (an << 24) | (((((c0>>>16)&255)*a0 + ((c1>>>16)&255)*a1 + ((c2>>>16)&255)*a2 + ((c3>>>16)&255)*a3 + frac)/dv) << 16) | (((((c0>>> 8)&255)*a0 + ((c1>>> 8)&255)*a1 + ((c2>>> 8)&255)*a2 + ((c3>>> 8)&255)*a3 + frac)/dv) << 8) | (((((c0>>> 0)&255)*a0 + ((c1>>> 0)&255)*a1 + ((c2>>> 0)&255)*a2 + ((c3>>> 0)&255)*a3 + frac)/dv) << 0) ; return color; } public static int blend4Simple(int c0, int c1, int c2, int c3) { int color = (((((c0>>>24)&255) + ((c1>>>24)&255) + ((c2>>>24)&255) + ((c3>>>24)&255) + 2)/4) << 24) | (((((c0>>>16)&255) + ((c1>>>16)&255) + ((c2>>>16)&255) + ((c3>>>16)&255) + 2)/4) << 16) | (((((c0>>> 8)&255) + ((c1>>> 8)&255) + ((c2>>> 8)&255) + ((c3>>> 8)&255) + 2)/4) << 8) | (((((c0>>> 0)&255) + ((c1>>> 0)&255) + ((c2>>> 0)&255) + ((c3>>> 0)&255) + 2)/4) << 0) ; return color; } public static void genMipmapAlpha(int[] aint, int offset, int width, int height) { int minwh = Math.min(width, height); int level; int w1, w2, h1, h2, o1, o2; w1 = w2 = width; h1 = h2 = height; o1 = o2 = offset; // generate mipmap from big to small o2 = offset; w2 = width; h2 = height; o1 = 0; w1 = 0; h1 = 0; for (level=0; w2>1 && h2>1; ++level,w2=w1,h2=h1,o2=o1) { o1 = o2 + w2*h2; w1 = w2/2; h1 = h2/2; for (int y=0; y0) { --level; w2 = width>>level; h2 = height>>level; o2 = o1 - w2*h2; int p2 = o2; for (int y=0; y1 && h2>1; ++level,w2=w1,h2=h1,o2=o1) { o1 = o2 + w2*h2; w1 = w2/2; h1 = h2/2; for (int y=0; y0) { --level; w2 = width>>level; h2 = height>>level; o2 = o1 - w2*h2; int p2 = o2; for (int y=0; y>> 24 == 255 && aint[size-1] == 0) return true; for (int i=0; i>> 24; if (alpha!=0 && alpha!=255) return true; } return false; } public static void updateSubImage1(int[] src, int width, int height, int posX, int posY, int page, int color) { int size = width * height; IntBuffer intBuf = getIntBuffer(size); int[] aint = getIntArray((size*4+2)/3); if (src.length >= size*(page+1)) { System.arraycopy(src, size*page, aint, 0, size); } else { Arrays.fill(aint, color); } // // if (page == 0) genMipmapAlpha(aint,0,width,height); // else // genMipmapSimple(aint,0,width,height); // for (int level=0, offset=0, lw=width, lh=height, px=posX, py=posY; lw>0 && lh>0; ++level) { int lsize = lw*lh; intBuf.clear(); intBuf.put(aint, offset, lsize).position(0).limit(lsize); GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, level, px, py, lw, lh, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); offset += lsize; lw/=2; lh/=2; px/=2; py/=2; } intBuf.clear(); } public static void updateSubTex1(int[] src, int width, int height, int posX, int posY) { int level; int cw; int ch; int cx; int cy; for (level = 0, cw=width, ch=height, cx=posX, cy=posY; cw>0 && ch>0; ++level, cw/=2, ch/=2, cx/=2, cy/=2) { GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, level, cx, cy, 0, 0, cw, ch); } } /* updateSubImage for single Texture with mipmap */ public static void updateSubImage1(int[][] src, int width, int height, int posX, int posY, int page, int color) { int size = width * height; IntBuffer intBuf = getIntBuffer(size); int numLevel = src.length; for (int level=0, //offset=0, lw=width, lh=height, px=posX, py=posY; lw>0 && lh>0 && level iterator; MultiTexID multiTex = tex.getMultiTexID(); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); for (iterator = tasList.iterator(); iterator.hasNext(); ) { TextureAtlasSprite tas = iterator.next(); tas.updateAnimation(); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); for (iterator = tasList.iterator(); iterator.hasNext(); ) { TextureAtlasSprite tas = iterator.next(); tas.updateAnimation(); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); for (iterator = tasList.iterator(); iterator.hasNext(); ) { TextureAtlasSprite tas = iterator.next(); tas.updateAnimation(); } } public static void setupTexture(MultiTexID multiTex, int[] src, int width, int height, boolean linear, boolean clamp) { int mmfilter = linear? GL11.GL_LINEAR: GL11.GL_NEAREST; int wraptype = clamp? GL11.GL_CLAMP: GL11.GL_REPEAT; int size = width * height; IntBuffer intBuf = getIntBuffer(size); // intBuf.clear(); intBuf.put(src, 0, size).position(0).limit(size); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype); // intBuf.put(src, size, size).position(0).limit(size); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype); // intBuf.put(src, size*2, size).position(0).limit(size); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec); GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype); // GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); } /* currently not used */ public static void updateSubImage(MultiTexID multiTex, int[] src, int width, int height, int posX, int posY, boolean linear, boolean clamp) { int size = width * height; IntBuffer intBuf = getIntBuffer(size); // intBuf.clear(); intBuf.put(src, 0, size); intBuf.position(0).limit(size); GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, posX, posY, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); if (src.length == size*3) { intBuf.clear(); intBuf.put(src, size, size).position(0); intBuf.position(0).limit(size); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, posX, posY, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); if (src.length == size*3) { intBuf.clear(); intBuf.put(src, size*2, size); intBuf.position(0).limit(size); } GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, posX, posY, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf); GL13.glActiveTexture(GL13.GL_TEXTURE0); } public static ResourceLocation getNSMapLocation(ResourceLocation location, String mapName) { String basename = location.getResourcePath(); String[] basenameParts = basename.split(".png"); String basenameNoFileType = basenameParts[0]; return new ResourceLocation(location.getResourceDomain(),basenameNoFileType+"_"+mapName+".png"); } public static void loadNSMap(IResourceManager manager, ResourceLocation location, int width, int height, int[] aint) { if (Shaders.configNormalMap) ShadersTex.loadNSMap1(manager, getNSMapLocation(location,"n"), width, height, aint, width*height , defNormTexColor); if (Shaders.configSpecularMap) ShadersTex.loadNSMap1(manager, getNSMapLocation(location,"s"), width, height, aint, width*height*2, defSpecTexColor); } public static void loadNSMap1(IResourceManager manager, ResourceLocation location, int width, int height, int[] aint, int offset, int defaultColor) { boolean good = false; try { IResource res = manager.getResource(location); BufferedImage bufferedimage = ImageIO.read(res.getInputStream()); if (bufferedimage.getWidth()==width && bufferedimage.getHeight()==height) { bufferedimage.getRGB(0, 0, width, height, aint, offset, width); good = true; } } catch (IOException ex) { } if (!good) { java.util.Arrays.fill(aint,offset,offset+width*height,defaultColor); } } /** init and upload from BufferedImage */ /* Replacement for TextureUtil.func_110989_a call in SimpleTexture.func_110551_a. Keep par0...par5 the same as func_110989_a for easy patching. More parameters added for reading N-S-Map. */ public static int loadSimpleTexture(int textureID, BufferedImage bufferedimage, boolean linear, boolean clamp, IResourceManager resourceManager, ResourceLocation location, MultiTexID multiTex) { int width = bufferedimage.getWidth(); int height = bufferedimage.getHeight(); int size = width*height; int[] aint = getIntArray(size*3); bufferedimage.getRGB(0, 0, width, height, aint, 0, width); loadNSMap(resourceManager, location, width, height, aint); setupTexture(multiTex, aint, width, height, linear, clamp); return textureID; } public static void mergeImage(int[] aint, int dstoff, int srcoff, int size) { } public static int blendColor(int color1, int color2, int factor1) { int factor2 = 255-factor1; return (( (((color1>>>24)&255)*factor1 + ((color2>>>24)&255)*factor2) /255 ) << 24) | (( (((color1>>>16)&255)*factor1 + ((color2>>>16)&255)*factor2) /255 ) << 16) | (( (((color1>>> 8)&255)*factor1 + ((color2>>> 8)&255)*factor2) /255 ) << 8) | (( (((color1>>> 0)&255)*factor1 + ((color2>>> 0)&255)*factor2) /255 ) << 0); } public static void loadLayeredTexture(LayeredTexture tex, IResourceManager manager, List list) { int width = 0; int height = 0; int size = 0; int[] image = null; Iterator iterator; for (iterator = list.iterator(); iterator.hasNext(); ) { String s = iterator.next(); if (s != null) { try { ResourceLocation location = new ResourceLocation(s); InputStream inputstream = manager.getResource(location).getInputStream(); BufferedImage bufimg = ImageIO.read(inputstream); if (size == 0) { width = bufimg.getWidth(); height = bufimg.getHeight(); size = width*height; image = createAIntImage(size,0x00000000); } int[] aint = getIntArray(size * 3); bufimg.getRGB(0, 0, width, height, aint, 0, width); loadNSMap(manager, location, width, height, aint); // merge for (int i = 0; i < size; ++i) { int alpha = (aint[i] >>> 24) & 255; image[size*0+i] = blendColor(aint[size*0+i], image[size*0+i], alpha); image[size*1+i] = blendColor(aint[size*1+i], image[size*1+i], alpha); image[size*2+i] = blendColor(aint[size*2+i], image[size*2+i], alpha); } } catch (IOException ex) { ex.printStackTrace(); } } } // init and upload setupTexture(tex.getMultiTexID(), image, width, height, false, false); } /* update block texture filter +/- items texture */ static void updateTextureMinMagFilter() { TextureManager texman = Minecraft.getMinecraft().getTextureManager(); ITextureObject texObj = texman.getTexture(TextureMap.locationBlocksTexture); if (texObj != null) { MultiTexID multiTex = texObj.getMultiTexID(); // base texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilB]); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilB]); // norm texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilN]); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilN]); // spec texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilS]); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilS]); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); } } static IResourceManager resManager = null; static ResourceLocation resLocation = null; static int imageSize = 0; public static IResource loadResource(IResourceManager manager, ResourceLocation location) throws IOException { resManager = manager; resLocation = location; return manager.getResource(location); } public static int[] loadAtlasSprite(BufferedImage bufferedimage, int startX, int startY, int w, int h, int[] aint, int offset, int scansize) { imageSize = w*h; bufferedimage.getRGB(startX, startY, w, h, aint, offset, scansize); loadNSMap(resManager, resLocation, w, h, aint); return aint; } public static int[] extractFrame(int[] src, int width, int height, int frameIndex) { int srcSize = imageSize; int frameSize = width * height; int[] dst = new int[frameSize * 3]; int srcPos = frameSize * frameIndex; int dstPos = 0; System.arraycopy(src, srcPos, dst, dstPos, frameSize); srcPos += srcSize; dstPos += frameSize; System.arraycopy(src, srcPos, dst, dstPos, frameSize); srcPos += srcSize; dstPos += frameSize; System.arraycopy(src, srcPos, dst, dstPos, frameSize); return dst; } public static void fixTransparentColor(TextureAtlasSprite tas, int[] aint) { } }