[java] Fastest way to draw to the screen

Started by
12 comments, last by Glass_Knife 16 years, 4 months ago
I'm trying to create a cellular automaton, with each cell 1 pixel in size. What is the best way to update the screen? My current implementation works like this: a buffer generated by Canvas.createImage() the graphics object is obtained from the image buffer. The graphics object is modified by each cell with a call to Graphics.fillRect(). The paint and update meathods use Graphics.drawImage() to draw the image buffer to the screen. However, as implemented my program is very slow. Is there a better way to update the screen? I've heard that BufferedImage has faster methods than Graphics.fillRect() to update individual pictures. Java also seems to have a lot of tools for "image generator" objects. What are my options? Which is the best in my case? [Edited by - King Mir on December 5, 2007 2:15:52 PM]
Advertisement
4 days and no response.
Doesn't anyone know how to paint an image to the screen?

What part of my post is scarring people away?
Here are some guidelines for using BufferedImages and modifying individual pixels (You especially need to look at #3):

1. Create your BufferedImage using

java.awt.GraphicsConfiguration.createCompatableImage(int width, int height, int transparency).

2. Use

BufferedImage.getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)

if you want to get the contents of a BufferedImage in an array. It sounds like you would not need to use this, though.

3. Use

BufferedImage.setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)

to set the contents of a BufferedImage.

If you do everything correctly, the image should stay hardware accelerated (at least for the BufferedImage data in memory, not the data that you are modifying).

One problem is that using the graphics that can be returned by BufferedImage.getGraphics() may cause the image to stop being hardware accelerated.

Greggles

[edit](forgot something)
If the image is of the image type RGB or ARGB, then you should use the following:

(int [])image.getRaster().getDataElements(int x, int y, int width, int height, int[] rgb );

image.getRaster().setDataElements(int x, int y, int width, int height, int[] rgb);

Also, I'm not sure about that BufferedImage.getGraphics() thing. I think it may only apply in certain situations and it may not be because of the Graphics but the way the data is set in the image. So, if you do want to use it then try it out and see if it slows down the app.
[/edit]
Thanks. That seems to have helped. And since its supposed to be hardware accelerated, that should be about as optimal as it can be. Right?
Here's a good article on rendering from within Java.

If you look at the associated forum thread you'll find my code that is very fast.

Regards
elFarto
Must you use "pure" Java? OpenGL seems more suitable to the task at hand. Either write a simple JNI function to update a JPanel, or use a OGL binding, such as JOGL or LWJGL.

Although, as of JDK 6, usage of hardware accelerated images isn't the pain it used to be ;)

Rodrigo
a.k.a javabeats at yahoo.ca
Quote:Original post by Son of Cain
Must you use "pure" Java? OpenGL seems more suitable to the task at hand. Either write a simple JNI function to update a JPanel, or use a OGL binding, such as JOGL or LWJGL.

Although, as of JDK 6, usage of hardware accelerated images isn't the pain it used to be ;)

Rodrigo
I want this to be a web applet, but If there's some way to get OpenGL to work with that I am open to the idea. I haven't ever worked with OpenGL, so pure Java has the advantage of being slightly more familiar. But what's most important is speed, not ease of use.

@elFarto
Thanks I'll take a look.
Which is faster, using bufferedImages with setRGB(m_xpos, m_ypos,color) or BufferStrategy.getDrawGraphics()with fillRect(m_xpos, m_ypos, 1, 1)?
My guess: setRGB() is faster, because it deals with an image that is hardware accelerated. Buffer strategy is used mainly for double buffering.
a.k.a javabeats at yahoo.ca
the fastest way to draw to the screen is to draw a volatileImage. Its much faster than draw bufferedImage. I get up to 600 fps at a GeForce 6600GT with volatileImage. With bufferedImage i had around 30 fps and with Image about 120 fps. I had test this in a little 2D-Invaders-Game (look at http://www.hs-merseburg.de/~meck/projekte/invaders/invaders.html).

Both, Image and VolatileImage, are much faster than BufferedImage. For Browser-Games is the Image the best. For OpenGL-Rendering the VolatileImage. BufferedImage is only good for Stills.

[Edited by - keenha on December 15, 2007 4:13:08 PM]

This topic is closed to new replies.

Advertisement