espresso3d.engine.fileloaders.E3DImageLoader.java Source code

Java tutorial

Introduction

Here is the source code for espresso3d.engine.fileloaders.E3DImageLoader.java

Source

/*
 * Created on Jul 23, 2004
 *
     
  Copyright 2004 Curtis Moxley
  This file is part of Espresso3D.
     
  Espresso3D is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
Espresso3D is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.
    
You should have received a copy of the GNU Lesser General Public License
along with Espresso3D.  If not, see <http://www.gnu.org/licenses/>.
 */
package espresso3d.engine.fileloaders;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.StringTokenizer;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import espresso3d.engine.E3DEngine;
import espresso3d.engine.exceptions.E3DInvalidFileFormatException;
import espresso3d.engine.logger.E3DEngineLogger;
import espresso3d.engine.renderer.texture.E3DTexture;

/**
 * 
 * @author espresso3d
 * 
 * Loads image (PNG, JPG, etc) files
 */
public class E3DImageLoader extends E3DFileLoader {
    /**
     * Loads a texture set of format :  <textureName>, <path to texture>;\n
     * into the textureSet map passed in with entries: value: Integer(glTextureAddress), key:texturename
     * It will -not- replace an item if its already in the map under texturename
     * @param textureSetFileName
     * @return
     * @throws E3DInvalidFileFormatException
     */
    public static void loadTextureSet(E3DEngine engine, String textureSetFileName, HashMap textureSet)
            throws E3DInvalidFileFormatException, IOException {
        InputStream is = null;
        BufferedReader textureSetFileReader = null;
        try {
            is = openFile(textureSetFileName);

            if (is == null) {
                engine.getLogger().writeLine(E3DEngineLogger.SEVERITY_ERROR,
                        "Unable to load textureset from jar or filesystem: " + textureSetFileName);
                return;
            }

            textureSetFileReader = new BufferedReader(new InputStreamReader(is));

            readTextureSet(engine, textureSetFileReader, textureSet);
        } finally {
            if (textureSetFileReader != null)
                textureSetFileReader.close();
            closeFile(is);
        }
    }

    private static void readTextureSet(E3DEngine engine, BufferedReader textureSetFile, HashMap textureSet)
            throws E3DInvalidFileFormatException, IOException {
        StringTokenizer tokenizer = null;
        String line = "";
        String path = "", textureName = "";

        int i = 0;
        while ((line = textureSetFile.readLine()) != null) {
            i = 0;
            tokenizer = new StringTokenizer(line, " ,;");
            while (tokenizer.hasMoreTokens()) {
                if (i == 0)
                    textureName = tokenizer.nextToken();
                else if (i == 1) {
                    path = tokenizer.nextToken();
                    if (!textureSet.containsKey(textureName)) //dont' load it twice
                    {
                        E3DTexture texture;
                        texture = loadImageIntoGL(engine, textureName, loadImage(path));

                        addTexture(textureSet, textureName, texture);
                    }
                } else if (i >= 2) //too many tokens
                    throw new E3DInvalidFileFormatException();

                i++;
            }
            if (i == 0)
                continue;
            else if (i < 2) //too few tokens
                throw new E3DInvalidFileFormatException();

        }

    }

    public static BufferedImage loadImage(String name) throws IOException {
        BufferedImage image = null;
        InputStream is = null;

        try {
            is = openFile(name);
            image = ImageIO.read(is);
        } finally {
            closeFile(is);
        }
        return image;
    }

    public static E3DTexture loadImageIntoGL(E3DEngine engine, String textureName, Image image) {
        // Extract The Image
        BufferedImage tex = new BufferedImage(image.getWidth(null), image.getHeight(null),
                BufferedImage.TYPE_3BYTE_BGR);

        Graphics2D g = (Graphics2D) tex.getGraphics();
        g.drawImage(image, null, null);
        g.dispose();

        // Flip Image
        AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
        tx.translate(0, -image.getHeight(null));
        AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        tex = op.filter(tex, null);

        // Put Image In Memory
        ByteBuffer scratch = ByteBuffer.allocateDirect(4 * tex.getWidth() * tex.getHeight());

        byte data[] = (byte[]) tex.getRaster().getDataElements(0, 0, tex.getWidth(), tex.getHeight(), null);
        scratch.clear();
        scratch.put(data);
        scratch.rewind();

        // Create A IntBuffer For Image Address In Memory   
        IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        GL11.glGenTextures(buf); // Create Texture In OpenGL   

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
        // Typical Texture Generation Using Data From The Image

        // Linear Filtering
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        // Linear Filtering
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        // Generate The Texture
        GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, 3, tex.getWidth(), tex.getHeight(), GL11.GL_RGB,
                GL11.GL_UNSIGNED_BYTE, scratch);
        //      GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tex.getWidth(), tex.getHeight(), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);

        E3DTexture texture = new E3DTexture(engine, textureName, buf.get(0));
        texture.setWidth(image.getWidth(null));
        texture.setHeight(image.getHeight(null));

        return texture; // Return Image Address In Memory       
    }

    private static void addTexture(HashMap textureSet, String textureName, E3DTexture texture) {
        textureSet.put(textureName, texture);
    }

    public static void unloadImageFromGL(int glTextureID) {
        IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        buf.put(glTextureID);
        GL11.glDeleteTextures(buf);
    }
}