Doubt this would benefit much as it’s a memory-bound operation, passing the buffers around from thread to thread is likely to only exacerbate the problem. That’s how it works in my head anyway. As always, needs a benchmark to really be able know anything.
I load them only once on-demand, basically when the class needs an image, it searches to see if that sheet is loaded yet, if it isnt, it loads it. If it is, it grabs it and uses it.
The problem isn’t so much loading the sheet as it is using .getColor() 1024 times on a 32x32 sprite that’s located on a 1024x512 sheet. Basically I’m not working with a 32x32 image, I’m working with a 1024x512 one and java really doesn’t like that.
My new solution has eliminated the problem though, I now have it loading pixel perfect maps for over 200-300 sprites in under 2 seconds. Basically it looks to see if a properties file exists with the data, if it does it just fetches a binary string and uses that to build the map. If it doesn’t it’ll rebuild a new map using my old method. (<-- More a fail-safe, because once they file is generated there’s no reason to make a new one) But that only happens one time ever unless you delete the file or the program detects the date modified on the sprite sheet changes, suggesting a new .properties file should be generated. So from the player’s perspective, these one-time generations should in theory never have to happen, because the game will be distributed with those properties files already generated anyway unless they start making mods for my game and adding new sprite sheets.
Yeah, I attempted to multithread it a while back and ran into a problem; LWJGL’s Graphics can only be ran on one thread at a time, and .getColor needs Graphics to function. So the most critical laggy step was the one I couldnt move to the thread.
After looking at some of your ideas (Like getting the byte[] array and uses that instead) I could pass it to it’s own thread now though, but really at this point there’s not much reason to with my newer system in place.
good if it works for you now, but you for sure made a mistake somewhere, because a 1024x512 pixel image is peanuts… Also loading one bigger file is waaaaaaay faster than 300 small properties files - creating pixel-perfect maps for 512 sprites from a single sheet should be doable in millis, not in seconds…
Not when you’re loading 10~ of these sheets (depending on the spritesheet it needs to grab) about 300~ times and include the time you need to iterate through an entire 12 layer 64x64 TiledMap (aka 49152 tiles to check) looking for the ones you need to load in the first place.
For an image where the width and height are both less than 256, is using bytes faster than using ints when reading in pixel data? (Assuming that reading speeds are NOT negligible, and we’re probably going to optimize until we reach assembly instructions.)
(Bytes reading per byte) versus (Integers reading 4 bytes, and then bitmasking the values for specific byte values)?
Bytes are going to be faster because Slick (OpenGL) gives us the data prepackaged as a byte array.
Talking Java2D, BufferedImage.TYPE_4BYTE_ABGR, or 3_BYTE_BGR (using same method that I posted above, plus standard DataBuffer routine) is still faster than bitmasking an int[], I have tested it.
It’s not much faster, but it makes sense, as even though you are trading potentially more cache misses (more array lookups), you don’t do all the bitmasking and shifting, and the cache miss rate doesn’t really increase in practice as you are reading a continuous block of memory.
Java per se has no problem with handling 0.5 megapixel images.
Lets take a step back here. You’re loading images with LWJGL and then extracting their contents to process them. I’m going to guess two things: firstly, that these images serve only for collision testing, and secondly that LWJGL loads them into texture memory on the graphics card.
If I’m right then the solution is to skip the graphics card. If you load the images using javax.imageio.ImageIO then you get java.awt.image.BufferedImage instances and you can call getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) to extract your sprite from the image.
For completeness, there may also be a way in LWJGL to create a new 32x32 texture, paint the appropriate segment of your sprite sheet onto it, and then fetch just that back from the graphics card; but I can’t see any good reason to do that.
No, I’m reading 10 different sprite sheets 300 times.
Those are all made up numbers anyway, the real numbers are closer to 2 dozen sheets, and how many times is dependent on how many objects are on the map that need to be scanned.