Limits of drawing BufferedImages?

I am making a game with pure java, drawing BufferedImage objects to a Graphics2D object.

My game has a simple rendering system, namely it just draws a bunch of tiles.

However, I have found that when I draw too many images onto the screen in one frame (name 1/60th of a second), this number being around 1000, my fps drops to around 30.

Is there a better way to do this? How can I draw images faster?

Take this advice with a grain of salt but I think the only way to continue using pure java and take advantage of hardware acceleration is to use the VolatileImage class, but as far as I know the use of this class is discouraged and I’ve personally never been able to get it to work. Without that I think since Java2D runs entirely on the CPU you’re not going to be able to do much better than what you are. Are you using spritesheets? That might help a little.

If you can come up with ways to combine graphics so that fewer individual draws are made, that should help some. Hard to say how much though. That piece of advice originally came from what I thought was a very helpful post/tutorial overall:

Re VolatileImages, I was trying to understand them better a while back and found a couple interesting blog posts from the author of “Filthy Rich Clients”. Apparently Chet Haase was involved with their design and implementation. So he should know what he is writing about.

https://weblogs.java.net/blog/chet/archive/2003/09/volatileimage_n.html
https://weblogs.java.net/blog/chet/archive/2004/08/toolkitbuffered.html

Generally draw calls via g.drawstuff are your first bottle neck. However most systems can do 10k before suffering. My integrate chip laptop POS can get around 5-10k depending on image size.

What is the fillrate on the images? What can happen if the fillrate gets to high I found is that the frame rate will hit around 30 but not drop lower until the draw calls hit that magic cap on most systems.

To confirm this baseless theory I just suggested. Once it drops to 30, does it stay there even when you add more draw calls?

What you could do if you have say a platformer/tile/grid system. On start up render all of the background or foreground or tiles to a volatile image and then render that each frame. This would seriously reduce draw calls and the fill rate will not take a hit either. I was going to do something similar in my Retro project which is all done in java2D.

I was achieving 200 FPS in Java2D, JRE6 with 10K sprites with an average size of 256x256.

Hardware: AMD A10 APU + Nvidia GTX 630

With my new hardware Intel Core i7 4770K + Nvidia GTX 780 I can achieve 2K FPS with the same set up, what hardware are you testing on?

Also make sure you are not using getRGB, setRGB, getDataBuffer or anything like that, those calls will cause Java2D to unaccelerate the image.

I use those calls to load some BufferedImage instances initially, but I only do these things once at the start and not every frame. I’ve made my game so all images are in on a grayscale and “colorized” by taking the RGB array using getRGB from image files, doing some math on all the pixels, and then making a new BufferedImage using setRGB

using setRGB even ONCE will cause Java2D to deaccelerate the image. If you want to draw on an image and keep it accelerated, use Graphics2D.