Texture color problem and pixel exact display questions

Started by Appelmoes123, January 14, 2010, 15:53:41

Previous topic - Next topic

Appelmoes123

Hello again,

I hoped you could help me again with a problem and a couple of questions bothering me.

First the problem, this code:
private int loadTexture(String path) {
	try {
		BufferedImage bufferedImage = ImageIO.read(new File("1024x768.jpg"));
		int width = bufferedImage.getWidth();
		int height = bufferedImage.getHeight();
		
		DataBuffer dataBuffer = bufferedImage.getRaster().getDataBuffer();
		byte[] byteArray = ((DataBufferByte)dataBuffer).getData();
		
		ByteBuffer byteBuffer = BufferUtils.createByteBuffer(byteArray.length);
		byteBuffer.put(byteArray);
		byteBuffer.flip();
		
		IntBuffer intBuffer = BufferUtils.createIntBuffer(1);

		GL11.glGenTextures(intBuffer);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, intBuffer.get(0x0));
		
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0x0, GL11.GL_RGB, width, height, 0x0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, byteBuffer);
		
		return intBuffer.get(0x0);
		
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	return 0;
}


For some (to me unknown) reason does not display the colors properly, the bits seem to be reversed or something.
At first I thought it was the flip function but it does the same if I use "byteBuffer.position(0);". What is going wrong here?

As for the questions, this loads an image of 1024x768 for 2D display (using OpenGL offcourse). Are images/textures of this size a problem? I have read about certain limitations of 512x512 and also that textures should also be a power of 2 for better performance.
Quality, simplicity and stability go above performance in my case, so losing a couple of FPS is not a problem.

Apart from the colors the image loads and displays fine on my development machine, however will this big texture also work on different machines?
And if I would want an image to be displayed on the screen exactly as it is (offcource taking into account the screen resolution/the quad's vertex positions and image size to be equal), what would be the best approach?

Kai

QuoteFor some (to me unknown) reason does not display the colors properly, the bits seem to be reversed or something.
That's right. The bytes are shuffled and do not follow RGB, but instead BGR layout.

You can reformat the buffer by yourself (of course by copying the buffer data into a new temporary buffer) or you could check if the extension "EXTBgra" is available, which allows you to set EXTBgra.GL_BGR_EXT as texture format in the glTexImage2D call.

QuoteApart from the colors the image loads and displays fine on my development machine, however will this big texture also work on different machines?
Don't know that for sure, but 1024x768 is not THAT huge.

QuoteAnd if I would want an image to be displayed on the screen exactly as it is ..., what would be the best approach?
Well, build yourself an orthogonal projection that transforms each texel to each pixel and apply this transformation to a quad that you then render with the texture applied to it. Read about the coordinate transformations applied in OpenGL to a primitive and the corresponding coordinate systems (model, world, camera/eye, clipping, normalized device coordinates, pixels).

Appelmoes123

QuoteYou can reformat the buffer by yourself (of course by copying the buffer data into a new temporary buffer)

Copying would mean another step in the image loading process, is it not possible to load an image in RGB instead of BGR directly?
I mean assuming that (apparantly) it is for some reason stored in (or decoded from) the JPG file in the BGR format, you could read through the file backwards?

Quoteyou could check if the extension "EXTBgra" is available, which allows you to set EXTBgra.GL_BGR_EXT as texture format in the glTexImage2D call.
I understand but that would mean another dependency so I would rather not do that, tnx for the hint though.

QuoteWell, build yourself an orthogonal projection that transforms each texel to each pixel and apply this transformation to a quad that you then render with the texture applied to it. Read about the coordinate transformations applied in OpenGL to a primitive and the corresponding coordinate systems (model, world, camera/eye, clipping, normalized device coordinates, pixels).

So I already did :) But I have noticed that this works on some machines but not on all in a pixel-perfect fashion.

Rene

Quote from: Appelmoes123 on January 14, 2010, 20:06:55
So I already did :) But I have noticed that this works on some machines but not on all in a pixel-perfect fashion.

Did you set texture filtering to nearest neighbor? That's probably the best way to filter in this case.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain

Appelmoes123

QuoteDid you set texture filtering to nearest neighbor? That's probably the best way to filter in this case.

Yes, see code snippet. Really strange no? It should just render the image to the screen 1 to 1 everywhere..