LWJGL: Loading a texture, the imperative way.

Please ignore this post, if you really care about code design. This piece of code isn’t really cleaned up.


import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.imageio.ImageIO;

//I only use LWJGL, nothing more.
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;

public class TextureLoader {
	
	public static class TempTexture {
		public ByteBuffer buffer;
		public int width;
		public int height;
		public int id;
	}
	
	public static TempTexture test = loadTexture("/icon.png");
	
	public static TempTexture loadTexture(String filename) {
		//Just to make sure I don't hog my laptop computer's memory and stick to an old Intel's graphics card.
		if (test != null) {
			GL11.glDeleteTextures(test.id);
			test.buffer.clear();
			test.buffer = null;
			test = null;
		}
		
		
		TempTexture result = null;
		try {
			BufferedImage img = ImageIO.read(TextureLoader.class.getResource(filename));
			int[] imgData = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());
			result = new TempTexture();
			result.width = img.getWidth();
			result.height = img.getHeight();
			int size = Math.max(result.width, result.height);
			result.buffer = BufferUtils.createByteBuffer(size * size * 4);
			result.buffer.order(ByteOrder.nativeOrder());
			result.buffer.position(0);
			for (int y = 0; y < result.height; y++) {
				for (int x = 0; x < result.width; x++) {
					int pixel = imgData[x + y * result.width];
					//RGBA is the preferred OpenGL format for loading texture.
					//Source:		http://www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads
					
					result.buffer.put((byte) ((pixel >> 16) & 0xFF));
					result.buffer.put((byte) ((pixel >> 8) & 0xFF));
					result.buffer.put((byte) ((pixel) & 0xFF));
					result.buffer.put((byte) ((pixel >> 24) & 0xFF));
					
					//Do note the bitwise shift signs. Please do experiment and see for yourself.					
					//Green hue
					/*result.buffer.put((byte) ((pixel << 16) & 0xFF));
					result.buffer.put((byte) ((pixel) & 0xFF));
					result.buffer.put((byte) ((pixel << 8) & 0xFF));
					result.buffer.put((byte) ((pixel << 24) & 0xFF));*/
					
					//Blue hue
					/*result.buffer.put((byte) ((pixel << 16) & 0xFF));
					result.buffer.put((byte) ((pixel << 8) & 0xFF));
					result.buffer.put((byte) ((pixel) & 0xFF));
					result.buffer.put((byte) ((pixel << 24) & 0xFF));*/
					
					//Red hue
					/*result.buffer.put((byte) ((pixel) & 0xFF));
					result.buffer.put((byte) ((pixel << 16) & 0xFF));
					result.buffer.put((byte) ((pixel << 8) & 0xFF));
					result.buffer.put((byte) ((pixel << 24) & 0xFF));*/
					
					//Blackness
					/*result.buffer.put((byte) ((pixel << 24) & 0xFF));
					result.buffer.put((byte) ((pixel << 16) & 0xFF));
					result.buffer.put((byte) ((pixel << 8) & 0xFF));
					result.buffer.put((byte) ((pixel) & 0xFF));*/
					
					//Normal
					/*result.buffer.put((byte) ((pixel >> 16) & 0xFF));
					result.buffer.put((byte) ((pixel >> 8) & 0xFF));
					result.buffer.put((byte) ((pixel) & 0xFF));
					result.buffer.put((byte) ((pixel >> 24) & 0xFF));*/
				}
			}
			result.buffer.position(0);
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
}

So, to load a texture in a simple program:


import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public class Program {
	
	public Program() {
		try {
			Display.setDisplayMode(new DisplayMode(640, 480));
			Display.create();
		}
		catch (LWJGLException e) {
			e.printStackTrace();
			Display.destroy();
			System.exit(-1);
		}
		initialize();
	}
	
	public void initialize() {
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, 640, 480, 0, 1, -1);
		
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glClearColor(1f, 1f, 1f, 1f);
		
	}
	
	public void start() {
		while (!Display.isCloseRequested()) {
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
			
			if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
				TextureLoader.test = TextureLoader.loadTexture("/icon.png");
			}
			
			GL11.glEnable(GL11.GL_TEXTURE_2D);
			TextureLoader.test.id = GL11.glGenTextures();
			GL11.glBindTexture(GL11.GL_TEXTURE_2D, TextureLoader.test.id);
			GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
			GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
			GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, TextureLoader.test.width, TextureLoader.test.height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, TextureLoader.test.buffer);
			GL11.glBegin(GL11.GL_QUADS);
			{
				//Matching coordinate positive/negative signs is a must, in order to create directionally specific textures.
				//Texture coordinates (s, t) ranges from -1 to 1, with -1 being the lowest (analogous to 0 on the number line).
				GL11.glTexCoord2f(1f, -1f);
				GL11.glVertex2i(200, -200);
				GL11.glTexCoord2f(1f, 1f);
				GL11.glVertex2i(200, 200);
				GL11.glTexCoord2f(-1f, 1f);
				GL11.glVertex2i(-200, 200);
				GL11.glTexCoord2f(-1f, 1f);
				GL11.glVertex2i(-200, 200);
			}
			GL11.glEnd();
			GL11.glDisable(GL11.GL_TEXTURE_2D);
			Display.update();
			Display.sync(60);
		}
		Display.destroy();
		System.exit(0);
	}
	
	public static void main(String[] arg) {
		new Program().start();
	}
}

Created this piece of code using a laptop running Windows XP with an old Intel graphics card. And yes, it did not support shaders.