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.