me.ukl.api.util.TextureUtil.java Source code

Java tutorial

Introduction

Here is the source code for me.ukl.api.util.TextureUtil.java

Source

/**
 * This file is part of SpoutcraftMod, licensed under the MIT License (MIT).
 *
 * Copyright (c) 2013 SpoutcraftDev <http://spoutcraft.org/>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package me.ukl.api.util;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.imageio.ImageIO;

import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL30;

public class TextureUtil {
    public static final Minecraft MINECRAFT = Minecraft.getMinecraft();

    public static int[] getRGB(BufferedImage img) {
        int[] rgb = new int[img.getWidth() * img.getHeight()];
        img.getRGB(0, 0, img.getWidth(), img.getHeight(), rgb, 0, img.getWidth());
        return rgb;
    }

    public static int loadTexture(BufferedImage img) {
        return loadTexture(getRGB(img), img.getWidth(), img.getHeight());
    }

    public static int loadTexture(int[] rgb, int width, int height) {
        IntBuffer rgbBuf = BufferUtils.createIntBuffer(rgb.length);
        rgbBuf.put(rgb);
        rgbBuf.flip();

        int tex = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, tex);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA,
                GL12.GL_UNSIGNED_INT_8_8_8_8_REV, rgbBuf);
        return tex;
    }

    public static void loadTextureMipmap(int tex, BufferedImage img) {
        int newWidth = nextPowerOf2(img.getWidth());
        int newHeight = nextPowerOf2(img.getHeight());
        if (newWidth == img.getWidth() && newHeight == img.getHeight()) {
            loadTextureMipmap(tex, getRGB(img), newWidth, newHeight);
        } else {
            //Resize to a power of 2. The aspect ratio isn't a problem because all texture access uses U/V coords anyway
            //
            //Just a note here, this REALLY screws up transparency it turns out. You can't mipmap
            //a non power of 2 texture though, so if it makes stuff look bad switch to a power of 2 texture
            //
            //Any problems caused by this resize would happen with a power of 2 mipmapped texture as well
            //(like pixels bleeding between tiles)
            BufferedImage newImg = new BufferedImage(newWidth, newHeight,
                    img.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB
                            : BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = newImg.createGraphics();
            //Best scaling
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            g2d.drawImage(img, 0, 0, newWidth, newHeight, null);
            loadTextureMipmap(tex, getRGB(newImg), newWidth, newHeight);
        }
    }

    //Requires pre-creation of texture to set filters first
    public static void loadTextureMipmap(int tex, int[] rgb, int width, int height) {
        IntBuffer rgbBuf = BufferUtils.createIntBuffer(rgb.length);
        rgbBuf.put(rgb);
        rgbBuf.flip();

        bind(tex);

        //If OpenGL30, use glGenerateMipmap, else use the GL_GENERATE_MIPMAP tex param
        if (RenderUtil.GL_30) {
            GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA,
                    GL12.GL_UNSIGNED_INT_8_8_8_8_REV, rgbBuf);
            GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
        } else {
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
            GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA,
                    GL12.GL_UNSIGNED_INT_8_8_8_8_REV, rgbBuf);
        }
    }

    public static ByteBuffer createImageBufferFrom(ResourceLocation location, boolean alpha) {
        ByteBuffer buffer = null;
        if (!Files.isDirectory(Paths.get(location.getResourcePath()))) {
            try {
                final BufferedImage image = ImageIO
                        .read(MINECRAFT.getResourceManager().getResource(location).getInputStream());
                int[] pixels = getRGB(image);
                buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * ((alpha) ? 4 : 3));

                for (int y = 0; y < image.getHeight(); y++) {
                    for (int x = 0; x < image.getWidth(); x++) {
                        int pixel = pixels[y * image.getWidth() + x];
                        buffer.put((byte) ((pixel >> 16) & 0xFF));
                        buffer.put((byte) ((pixel >> 8) & 0xFF));
                        buffer.put((byte) (pixel & 0xFF));
                        buffer.put((byte) ((pixel >> 24) & 0xFF));
                    }
                }

                buffer.flip();
            } catch (IOException ignore) {
            }
        }
        return buffer;
    }

    public static int loadTexture(ResourceLocation location) {
        if (!Files.isDirectory(Paths.get(location.getResourcePath()))) {
            try {
                final BufferedImage image = ImageIO
                        .read(MINECRAFT.getResourceManager().getResource(location).getInputStream());
                return loadTexture(image);
            } catch (IOException ignore) {
            }
        }
        return 0;
    }

    public static void setMinFilter(int filter) {
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter);
    }

    public static void setMagFilter(int filter) {
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filter);
    }

    public static void setWrapS(int wrap) {
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrap);
    }

    public static void setWrapT(int wrap) {
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrap);
    }

    public static void bind(int tex) {
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, tex);
    }

    public static void delete(int tex) {
        GL11.glDeleteTextures(tex);
    }

    private static int nextPowerOf2(int val) {
        val--;
        val |= val >> 1;
        val |= val >> 2;
        val |= val >> 4;
        val |= val >> 8;
        val |= val >> 16;
        val++;
        return val;
    }
}