Create OpenGL Texture from ByteBuffer

So, is there a quick-and-easy way to go about this?

Here’s what I have so far:


public TextureSheet(String path, int id, int tw, int th) {
		try {
			sheet = ImageIO.read(TextureSheet.class.getClassLoader().getResourceAsStream(path));
			
			int rows = sheet.getHeight() / th;
			int cols = sheet.getWidth() / tw;
			
			BufferedImage[] sprites = new BufferedImage[rows * cols];
			
			for (int x = 0; x < rows; x++) {
				for (int y = 0; y < cols; y++) {
					sprites[x * y] = sheet.getSubimage(x * tw, y * th, tw, th);
				}
			}
			
			for (int i = 0; i < sprites.length; i++) {
				BufferedImage image = sprites[i];
				int[] pixels = new int[image.getWidth() * image.getHeight()];
				image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
				
				ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
				
				for (int y = 0; y < image.getHeight(); y++) {
					for (int x = 0; x < image.getWidth(); x++) {
						int pixel = pixels[y * image.getWidth() + x];
						buffer.put((byte) ((pixel >> 24) & 0xFF)); // alpha
						buffer.put((byte) ((pixel >> 16) & 0xFF)); // red
		                buffer.put((byte) ((pixel >> 8) & 0xFF));  // green
		                buffer.put((byte) (pixel & 0xFF));         // blue
					}
				}
				
				buffer.flip();
				
				//TODO Add code to convert ByteBuffer to OpenGL Texture
				
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

I’ll keep looking into this on my own and will update this thread with the solution if I find one.

Thanks in advance,

| Nathan

p.s. For some reason the formatting gets messed up when I paste in from Eclipse; it looks perfect in there. Oh well.

This is probably the easiest/best technique; the thread also outlines a few other suggestions.

(Not sure why GL_ALPHA_BIAS is necessary there…)

EDIT:
This assumes you already know how to set up an OpenGL texture, e.g. wrap mode, filtering, etc.

If you don’t yet know these things, I’d suggest using Matthias Mann’s texture loader instead of relying on AWT. Slick also has a texture loader, although not quite as powerful.

If you’d rather get to the nitty gritty and reinvent the wheel, here is an example:

Further reading for texturing in OpenGL:
http://www.gamedev.net/page/resources/_/technical/opengl/opengl-texture-mapping-an-introduction-r947
http://www.flipcode.com/archives/Advanced_OpenGL_Texture_Mapping.shtml

Modern approaches:
http://open.gl/textures
http://www.arcsynthesis.org/gltut/


    GL11.glTexImage2D(target, 0, dstPixelFormat, image.getWidth(), image.getHeight(), 0, srcPixelFormat, GL11.GL_UNSIGNED_BYTE, buffer); 

Just be sure the image dimensions are an power of 2 number.
ex: 2 4 8 16 32… etc

It’s there if you’re using a BufferedImage of type INT_RGB, and grabbing the data array directly - ie.


int[] data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData()

This is faster then using getRGB(), but the data will have a zero alpha channel, hence using alpha bias to correct it. Minor use case which I should probably have explained a bit more. In some cases you could also just flag the texture and be careful about how you use blending when drawing it, or just upload to an opaque texture (assuming the alpha channel is ignored in this case?).

Or have an OpenGL 2+ capable card?! :wink: