Since bytebuffers are what opengl uses, and I am needing this for opengl, I figured I'd post here. I've seen many pre-made texture loaders and things that convert from bufferedimage to bytebuffer that I could use, but I they're kind of daunting. What are the absolute basics for what you need changing a bufferedimage to bytebuffer?

For starters, what information does the bytebuffer need to get from bufferedimage and how is it gotten? I know this is a difficult question, sorry. To really understand the question, I feel like starting from the basics would be best.

For starters, what information does the bytebuffer need to get from bufferedimage and how is it gotten? I know this is a difficult question, sorry. To really understand the question, I feel like starting from the basics would be best.

You are not wrong, although you are focusing too much on the code. You should start by investigating the wonderful world of images, computer monitors and pixels and how a BufferedImage stores them. Pixel formats, bit depths, alpha channels, scanlines, all that jazz.

You are not wrong, although you are focusing too much on the code. You should start by investigating the wonderful world of images, computer monitors and pixels and how a BufferedImage stores them. Pixel formats, bit depths, alpha channels, scanlines, all that jazz.

Sounds like a good idea. Are there any references or java wiki pages that have something like that I could read, or is it not that straightforward?

Images are rectangular, made up of width * height number of pixels. Each pixel has 3 or 4 components, R(ed) G(reen) B(lue) are the essential ones and A(lpha) (transparency) if you need it. Most of the time, each component is 1 byte = 256 values (0 to 255), where 0 is none of it and 255 is all of it. When all of them are 0 = the pixel is black, when all of them are 255 = the pixel is white.

There may also be different bit depths, aka the number of bits used to store 1 pixel. The bit depth that I talked about above is 4 components * 8 bits each = 32-bit. There may also be 3 components (no alpha channel) * 8 bits each = 24-bit. Or 4 components * 4 bits each = 16-bit.

You probably already know that an 'int' is 32-bits, so.....they are mostly used to store pixel data You can also use bytes, with every 4 bytes = 1 pixel.

Image file formats, such as PNG, JGP, BMP, etc.., can support different combinations of the components. For example, JPG is a lossy (meaning that the compression algorithm it uses loses data to save space) format that only supports RGB. PNG, however, is a lossless format that supports RGB and A so it is the format most preferred for game textures (however it produces larger files than JPG).

Thank you for typing that. So if images are made of length, width, and the color components, you just transfer that info from the bufferedimage to the bytebuffer and you're done?

I actually don't know the difference between a bufferedimage and a bytebuffer, other than OpenGL needs bytebuffers and can't use bufferedimage. Are there any complications to transfering the length, width, and RGBA?

I didn't know that ByteBuffers were arrays. I looked back at the link that Stranger posted and compared it to a resource and I think I've got some of it. Looking at the loadTexture method, I now understand it up to the for-loop.

I've never heard of some of these things in this loop before. Anyone care to explain it like I'm five? Thank you everybody for your help so far.Just to show that I'm actually trying to comprehend this and not sitting back and letting you all to do the work, I'll type what I understand in the loop below.

Say getWidth and getHeight both return 16. The first two lines make x and y go from 0 to 16 in every iteration. The third line is sort of confusing. I think pixel is equal to the certain spot for a pixel in the array that was created earlier? I don't know how "[y * image.getWidth() + x]" does that though. Then the next 4 lines are just putting data into that pixel? "((byte) ((pixel >> 16) & 0xFF))" is really a piece for me. The reference I was looking at had a ton of different parameter options for put(), and I can't figure out which one is being used here, so I don't know what's happening in there. I've seen 0xFF in a book I read a few weeks back but the 0xFF was the reason I put the book down, I have no idea what it is. I don't know if this is making zero sense at all, I have no idea what's going on in the bottom 5 lines, just a vague idea not based on the code itself but on context clues.

The pixels array holds pixels in a 1D array, meaning every WIDTH number of indices is 1 scanline, or 1 row of pixels.

1

pixels[y * image.getWidth() + x]

That gets the pixel at (x,y) by finding the Y'th row and then X'th pixel on that row.

0xFF - this is hex for 255, aka 1 byte: 11111111. I advise you learn the hexadecimal system

& - that is the AND command. This takes 2 values and outputs an AND'ed value. Basically, it tests each bit in the first value against each bit in the same position in the second value. Both bits have to be 1 to get a 1, otherwise you get 0. For example:

There is also the OR command using | : int o = v1 | v2; This tests for at least 1 of the 2 bits to be a 1 to get a 1.And lastly there is the XOR command using ^ : int o = v1 ^ v2; This tests for at MOST 1 of the 2 bits to be a 1 to get a 1. If both are 1 or 0 then you get 0.

V >> X - this is the right bit shift command. This shifts all the bits in value V to the right X number of times. For example:

Since an int is made up of 4 bytes and each color component is 1 byte, you want to separate out those 4 bytes into 4 separate variables.The first line shifts the bits to the right 16 times to put the 2nd byte from the left in the rightmost byte position and makes sure only those rightmost 8 bits are left by doing "& 0xFF".Second line gets the 3rd byte from the left.Third line just gets the rightmost byte.Fourth line gets the leftmost byte.

I apologize, it seems like each of your responses are making me ask even more questions. I'm learning a whole lot, though, so thank you again.

Quote from: ra4king

The pixels array holds pixels in a 1D array, meaning every WIDTH number of indices is 1 scanline, or 1 row of pixels.

1

pixels[y * image.getWidth() + x]

That gets the pixel at (x,y) by finding the Y'th row and then X'th pixel on that row.

If getWidth and getHeight return 4 for the example,on the first iteration it would be 0*4 + 0, so it would get the 0th int in the pixels array.on the second iteration it would be 1*4 + 1, so it would get the 5th int in the pixels array.on the third iteration it would be 2*4 + 2, so it would get the 10th int in the pixels array.on the fourth iteration it would be 3*4 + 3, so it would get the 15th int in the pixels array.Then y wouldn't be less than width anymore so it would stop.

Maybe it's because I don't understand 1D arrays, but the array was defined with getWidth * getHeight amount of numbers in it, which would be 16. But only the 0th, 5th, 10th, and 15th of them are being used? What about 1-4, 6-9, 11-14?

Quote from: ra4king

0xFF - this is hex for 255, aka 1 byte: 11111111. I advise you learn the hexadecimal system

I went and did just that. Also I found out that the 0x was just the prefix used for hex.

Quote from: ra4king

& - that is the AND command. This takes 2 values and outputs an AND'ed value. Basically, it tests each bit in the first value against each bit in the same position in the second value. Both bits have to be 1 to get a 1, otherwise you get 0. For example:

1 2 3

intv1 = 18; //0001010intv2 = 20; //0001100into = v1 & v2; //0001000

There is also the OR command using | : int o = v1 | v2; This tests for at least 1 of the 2 bits to be a 1 to get a 1.And lastly there is the XOR command using ^ : int o = v1 ^ v2; This tests for at MOST 1 of the 2 bits to be a 1 to get a 1. If both are 1 or 0 then you get 0.

Alright, I think I see what you mean. Using OR in the example you posted would get 0001110, and using XOR would get 0000110.

Quote from: ra4king

V >> X - this is the right bit shift command. This shifts all the bits in value V to the right X number of times. For example:

Since an int is made up of 4 bytes and each color component is 1 byte, you want to separate out those 4 bytes into 4 separate variables.The first line shifts the bits to the right 16 times to put the 2nd byte from the left in the rightmost byte position and makes sure only those rightmost 8 bits are left by doing "& 0xFF".Second line gets the 3rd byte from the left.Third line just gets the rightmost byte.Fourth line gets the leftmost byte.

Oh I get it. It's stored like AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB, so moving it to the right 16 times would make it AAAAAAAARRRRRRRR, right? And the reason that RRRRRRRR remains and not AAAAAAAARRRRRRRR, is because you 'AND' 'd 0xFF, which is 0000000011111111(which, when and'd with something, would make it only use the last 8. )?

If getWidth and getHeight return 4 for the example,on the first iteration it would be 0*4 + 0, so it would get the 0th int in the pixels array.on the second iteration it would be 1*4 + 1, so it would get the 5th int in the pixels array.on the third iteration it would be 2*4 + 2, so it would get the 10th int in the pixels array.on the fourth iteration it would be 3*4 + 3, so it would get the 15th int in the pixels array.

What do you mean by iteration? What you actually did here was stepping through your image diagonally.Remember that the pixel at (x,y) is found at data[y*w+x], so if you lookup data[2*4+2] it will be visible at (2,2)

Quote

If getWidth and getHeight return 4 for the example,...Then y wouldn't be less than width anymore so it would stop.

'y' has nothing to do with 'width', you made it confusing for yourself by stating that both width and height were 4. Let's say w=4 and h=7, then y can be greater than w, it just must be less than h.

Everything else is correct

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org