Issue with Texture.overrideTexelData

Started by Jakes, January 19, 2021, 02:43:01 AM

Previous topic - Next topic

Jakes

Hello,

I'm using the method Texture.overrideTexelData, but it seems that its data is not being used correctly in the texture.
my example below shows the problem with it.

Im using this simples code to change texture data on the fly:


public void update() {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
int size = w * h * 4;
ByteBuffer buffer = ByteBuffer.allocateDirect(size);
buffer.order(ByteOrder.LITTLE_ENDIAN);

<Draw on Image> -> img.getGraphics().drawImage(spr, 0, 0, null);

DataBuffer dataBuffer = img.getRaster().getDataBuffer();
byte[] pixelData = ((DataBufferByte) dataBuffer).getData();
buffer.put(pixelData);
tex.overrideTexelData(buffer);
}


Results:

Original Image:


Drawn Image:


so, it sems that the color params are being swapped when uploading them to the buffer somewhere

AGP

It does look horizontally flipped, but obviously there's more to it than that. Try ORing the prixel data with the appropriate value (255?) to make sure it's opaque.

EgonOlsen


Jakes

Yes, and it doesn't look like it, mainly because it's not only channel flipping but channel mixing,

i've tried this: img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

and this is the result:



the weird part is that I'm not using alpha channel, the original resulting image doesn't have any kind of transparency

Jakes

here is a clearer example:

Original image:


Resulting Image when using ARGB:


Resulting Image when using ABGR: Note that this one is the format the comes from ImageIO.read

EgonOlsen

As the docs say:

Quote...the buffer with the texel data in RGBA-format.

Your issue is most likely, that the data from the DataBuffer isn't in that order. jPCT itself does a conversion from loaded BufferedImages into RGBA.

It does something similar to this to each texel:
int rgba = (texel & 0x0000ff00) | ((texel & 0x000000ff) << 16) | ((texel & 0x00ff0000) >> 16) | (texel>>24);

ATM, I fail to see how this converts from ARGB to RGBA, because something seems off with the handling of G here, but it works this way in the engine. It might not in your case, but the basic idea remains the same. Just the values might be different.


Jakes

#6
Yep, it worked, changing the channel order worked.

But, is there any way to set the image format to that order from the start, without having to iterate every pixel and rearrange it to the RGBA order? do you know any way besides using image type that could set the RGBA order correcly from the start?

regards

EgonOlsen

This might be possible by implementing your own ColorModel and use that to create a BufferedImage. But I doubt that it's worth it...

Jakes

It was way better. Iterating millions of times had its cost

MichaelJPCT

i use overrideTexelData at low frequency so it's not a problem for me.
but with FrameBuffer.getPixel i have to convert color format, and at high frequency (to output thousands of jpg files).
so i wish getPixel outputs the correct color format directly.
i mean in jpct-ae .

EgonOlsen

getPixels() requests the data in GL_RGBA, the texture upload again expects them to be in GL_RGBA as well. So actually, it should fit. Most likely it doesn't, because the frame buffer returns no alpha values, because there is no buffer in GPU memory to store these. Anyway, not much I can do about it, I suppose.