net.betabears.the2dlibrary.graphics.Image.java Source code

Java tutorial

Introduction

Here is the source code for net.betabears.the2dlibrary.graphics.Image.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.betabears.the2dlibrary.graphics;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import net.betabears.the2dlibrary.structure.PreLoadable;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;

import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL33;
import static org.lwjgl.opengl.GL33.*;

/**
 * This class represents a simple image. To load an Image, set the filepath and
 * params (OGL sampler parameters for creation). Then call <code>load</code> and
 * <code>init()</code>.
 *
 * @author Bobthepeanut
 */
public class Image implements PreLoadable {

    private File f;
    private String filepath;
    private static final Logger LOGGER = Logger.getLogger(Image.class.getName());
    private int texWidth, texHeight, id, samplerID;
    private static ByteBuffer imageBuffer;
    private boolean isLoaded, isInitialised;
    private SamplerParameters params = standardParams;
    private static SamplerParameters standardParams = (id) -> {
        glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    };

    private Image() {
    }

    /**
     * Needed for all rendering processes.
     *
     * @return The OGL id of this Image.
     */
    public int getId() {
        return id;
    }

    void setId(int id) {
        this.id = id;
    }

    public SamplerParameters getParams() {
        return params;
    }

    public void setParams(SamplerParameters params) {
        this.params = params;
    }

    public static SamplerParameters getStandardParams() {
        return standardParams;
    }

    public Image(String filepath) {
        this.filepath = filepath;
        f = new File(filepath);
    }

    @Override
    public void load() {
        try {
            BufferedImage img = ImageIO.read(new BufferedInputStream(new FileInputStream(f)));
            texWidth = img.getWidth();
            texHeight = img.getHeight();
            int[] pixels = new int[texWidth * texHeight];
            img.getRGB(0, 0, texWidth, texHeight, pixels, 0, texWidth);
            imageBuffer = BufferUtils.createByteBuffer(texWidth * texHeight * 4);
            for (int i : pixels) {
                imageBuffer.put((byte) ((i >> 16) & 0xFF)).put((byte) ((i >> 8) & 0xFF)).put((byte) (i & 0xFF))
                        .put((byte) ((i >> 24) & 0xFF));
            }
            imageBuffer.flip();
        } catch (IOException ex) {
            LOGGER.log(Level.WARNING, "Image file under {0} was not found or inacessible.", filepath);
            imageBuffer = BufferUtils.createByteBuffer(4);
            imageBuffer.put((byte) 0b0).put((byte) 0b0).put((byte) 0b11111111).put((byte) 0b01111111);
            texWidth = 1;
            texHeight = 1;
        }
        isLoaded = true;
    }

    @Override
    public void init() {
        if (!isLoaded) {
            LOGGER.log(Level.SEVERE, "load() wasn't called before init().");
        } else {
            if (!isInitialised) {
                glEnable(GL_TEXTURE_2D);
                id = glGenTextures();
                samplerID = glGenSamplers();
                glBindTexture(GL_TEXTURE_2D, id);
                params.specifyParameters(samplerID);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                        imageBuffer);
                glDisable(GL_TEXTURE_2D);
                isInitialised = true;
            } else {
                LOGGER.log(Level.SEVERE, "init() had already been called before when init() was called.");
            }
        }
    }

    /**
     * Binds this image and prepares rendering. Make sure to call
     * glEnable(GL_TEXTURE_2D) before.
     */
    public void bind() {
        GL13.glActiveTexture(GL13.GL_TEXTURE0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
        GL33.glBindSampler(0, samplerID);
    }

    public String getFilepath() {
        return filepath;
    }

    public int getTexWidth() {
        return texWidth;
    }

    public void setTexWidth(int texWidth) {
        this.texWidth = texWidth;
    }

    public int getTexHeight() {
        return texHeight;
    }

    public void setTexHeight(int texHeight) {
        this.texHeight = texHeight;
    }

    public int getSamplerID() {
        return samplerID;
    }

    @Override
    public boolean isLoaded() {
        return isLoaded;
    }

    @Override
    public boolean isInitialised() {
        return isInitialised;
    }
}