com.voxelplugineering.voxelsniper.util.TextureUtilities.java Source code

Java tutorial

Introduction

Here is the source code for com.voxelplugineering.voxelsniper.util.TextureUtilities.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 The Voxel Plugineering Team
 *
 * 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 com.voxelplugineering.voxelsniper.util;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL30;

public class TextureUtilities {

    private static int debugTexture = 0;

    public static int loadPNGTexture(File file, int textureUnit) {
        ByteBuffer buf = null;
        int tWidth = 0;
        int tHeight = 0;

        try {
            BufferedImage image = ImageIO.read(file);
            tWidth = image.getWidth();
            tHeight = image.getHeight();
            buf = imageToRGBABuffer(image);
        } catch (IOException e) {
            e.printStackTrace();
            if (file.getName().endsWith("debug.png")) {
                System.exit(-1);
            } else {
                return debugTexture;
            }
        }

        // Create a new texture object in memory and bind it
        int texId = GL11.glGenTextures();
        GL13.glActiveTexture(textureUnit);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId);

        // All RGB bytes are aligned to each other and each component is 1 byte
        GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);

        // Upload the texture data and generate mip maps (for scaling)
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tWidth, tHeight, 0, GL11.GL_RGBA,
                GL11.GL_UNSIGNED_BYTE, buf);
        GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);

        // Setup the ST coordinate system
        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);

        // Setup what to do when the texture has to be scaled
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_NEAREST);

        OpenGLUtilities.checkGLError("loadPNGTexture");
        if (file.getName().endsWith("debug.png")) {
            debugTexture = texId;
        }
        return texId;
    }

    public static ByteBuffer imageToRGBABuffer(BufferedImage img) throws IOException {
        ByteBuffer buf = null;

        // Decode the PNG file in a ByteBuffer
        buf = ByteBuffer.allocateDirect(4 * img.getWidth() * img.getHeight());
        byte[] pixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();
        boolean hasAlpha = img.getAlphaRaster() != null;

        for (int pixel = 0; pixel < pixels.length; pixel += (hasAlpha ? 4 : 3)) {
            int offset = hasAlpha ? 1 : 0;
            buf.put(pixels[pixel + 2 + offset]);
            buf.put(pixels[pixel + 1 + offset]);
            buf.put(pixels[pixel + offset]);
            if (hasAlpha) {
                buf.put(pixels[pixel]);
            } else {
                buf.put((byte) 0);
            }
        }

        buf.flip();
        return buf;
    }
}