Load large background image

Hi, this probably came up before, but I’m just wondering how are you guys dealing with loading large background images? I have a tile based map and my entire map is consist of 72 X 72 tiles, I have no problem building the map, just when it comes to loading a large background its lagging my game pretty badly. How would you guys load an 2363 X 1265 background image?

I’ve thought about chopping it into blocks, but that would be harder to do parallel scrolling, my idea is use the getSubImage method from the bufferImage to do the scrolling, but with large image lagging my game this doesn’t seem viable. Any tips welcome, thanks in advance. ;D

Solution: Don’t use Java2D. :wink:

getSubimage returns an image which just references a region of the larger image. While that’s good for memory it’s bad for performance. I’d suggest that at load time you load your huge image then carve it up into tiles of 256x256 (using getSubImage and then drawing those onto brand new 256x256 tile images). Then just draw the tiles of the background that are visible at any given time.

why dont you load the whole image ?
and then use drawImage(Image largeBackgroundImage,sx,sy,sx2,sy2,dx,dy,dx2,dy2,null) ?

with :
sx,sy,sx2,sy2 variing depending on your scroll (viewable area)
dx,dy,dx2,dy2 fixed to your game area => 0,0,gameWidth,gameHeight
largeBackgroundImage => your large background

or do you mean that each tile is an 2363 X 1265 image ?

As mentioned, this is horribly slow in J2D. I suspect that under the hood the whole image needs to be shuttled to the graphics card before the subsection can be drawn, regardless of how small the subsection is.

hum I did not really had any performance issue in java2d but, never try the above with such image, so if it is so slow you can do the following :

store you big image in a int array[2363 X 1265] and create a buffered image of the size of your display area then when requiere to render backgorund :
copye the viewable area to the buffered image with System.arrayCopy or a raw destInt[n]=sourceInt[n] and then display your buffered image

Not slow for me.

drawImage(Image largeBackgroundImage,sx,sy,sx2,sy2,dx,dy,dx2,dy2,null) is fast as long as the source/destination bounds require no scaling. I’ve been scrolling 4000*4000px with this, with a smooth framerate.

not for me too, hope it was clear that I was talking of non-scaled area, it was not ?

Drawing a sub-image in J2D was never slow for me, as far as I can remember.

Hmm, I wonder if it depends on the backend. On the DirectDraw backend it’s pretty bad, but I’ll admit to not testing it with the D3D backend.

Such is the difficulty of giving performance advice for a platform with three different backends across three different platforms. :S

Hi guys, thanks alot for the replies! I have loaded the background image into an array first( tiles are in a separate array). I’ll try the drawImage(Image largeBackgroundImage,sx,sy,sx2,sy2,dx,dy,dx2,dy2,null) method as soon as I get off work. I’m just curious, what’s better for performance:

  • drawImage(Image largeBackgroundImage,sx,sy,sx2,sy2,dx,dy,dx2,dy2,null)
  • getSubImage from bufferedImage(seems like this is really bad for performance)
  • store the image into an int array like suggested int array[2363 X 1265], althought I’m not quite sure how to do this one, do you mean store the pixels into the array?

Again, thanks alot for the help guys!

BufferedImage let you access their pixels using an int array, so you can create a bufferedimage of the same size as your rendering window and use it as a backbuffer

BufferedImage BIImage;
if(alpha)
	BIImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);
else
	BIImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
pixels=((DataBufferInt)(BIImage.getRaster().getDataBuffer())).getData(); 
image=(Image)BIImage

;

you fill the BI pixels with the portion of the big image that is visible and then call g.drawImage(image,0,0,null);

O that looks interesting, I’ll try it out and see how it goes ;D

Scrolling background causes no lag now thanks alot for the help guys!

Edit: It still causes minor lag when I try to load more parts of the same image, but I’ll try fix that.

Edit2: Load large background Image is making my graphics card’s fan pretty loud, why is that? I can play some pretty graphics intensive games like crysis, fallout3 and the fan would be abit loud, but aren’t 2D games less graphics intensive?

the difference is that in your case you are probably not using a lot your graphics card (or very few, probably your cpu fan , no ? ), 3d game like crysis and such perform most task on the GPU, you can also do that using opengl with java (lwjgl / jogl / gl4java ) but as long as you dont “requiere” them due to complexe/heavy 2D graphics and/or 3D, I would recommend you to stick with java2d wich is easier to use and offer a better compatibility. and then later when you will feel confortable with java & graphics you may try them.

[quote]Edit: It still causes minor lag when I try to load more parts of the same image, but I’ll try fix that.
[/quote]
you must use a different thread to asynchronously load other part of the image, this thread can set a flag once new parts of image are loaded and in your main thread you check this flag to know when new data are available

I’ve made my background image smaller (1600 * 765) and it is making things alot better, I guess I’ll have to load a couple smaller image this size and connect them through code to speed up performance, the parallel scrolling is working good and thanks for the help!