[java] Fastest Pixel Drawing in Java?

Started by
2 comments, last by cnauroth 20 years, 6 months ago
Hello, I am currently converting an old project written in C++ to Java, and I am trying to find the fastest way to construct images pixel by pixel. The project is a rudimentary ray caster. I will eventually incorporate texture mapping, so I need to perform my own rasterization logic rather than using something like the Java 2D API to draw a series of primitive shapes. First, I tried creating a BufferedImage object. I performed all of my rendering by using a call to BufferedImage.setRGB for each pixel. This worked well for an image size of 320 x 200, but when I expanded it to 640 x 480, the frame rate dropped to 10 frames per second. A quick run with hprof seemed to indicate that the bottleneck was all of those calls to setRGB rather than the logic of my ray caster. Second, I tried working with a WritableRaster. I accomplished rendering via multiple calls to setPixel. Then, I fed the WritableRaster into the constructor for BufferedImage to create the desired image. This approach was even slower, reducing to 7 frames per second at 640 x 480. I see that the WritableRaster also offers a setPixels method for bulk operations. Maybe I should have the ray caster build an array of all of the samples for the image, then feed that into the bulk setPixels method. Does anyone else have any other suggestions? Please feel free to recommend references, tutorials, or code samples if you think it would offer a better explanation. Thank you. --Chris Nauroth
Advertisement
Creating a new BufferedImage each time isn''t necessary. You can create a blank BI to begin with, pull its WritableRaster out with getRaster(), and any change to the raster is immediately reflected in the BI.

I''m no expert on the inners of Java 2D, but it does look like WritableRaster.setPixel() is more direct than BufferedImage.setRGB(), based on peaking at their source.
public class BufferedSurface{  BufferedImage image ;  DataBufferInt data ;  Component parent;  int width, height;  public BufferedSurface( int w, int h, Component parent )  {    this.parent = parent ;    width = w ;    height = h ;    image = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB);    data = (DataBufferInt)image.getRaster().getDataBuffer() ;    buffer = data.getData() ;  }  public Image getImage()  {    return image ;  }} 


Then you just add methods to operate on your int array.
I had been going about this all backwards, trying to create my own SampleModel, WritableRaster, and ColorModel, and then trying to construct a BufferedImage based on all of that. Thank you both for the help.

This topic is closed to new replies.

Advertisement