Friday, July 19, 2019

java - fast java2d translucency


I'm trying to draw a bunch of translucent circles on a Swing JComponent. This isn't exactly fast, and I was wondering if there is a way to speed it up. My custom JComponent has the following paintComponent method:


public void paintComponent(Graphics g) {
Rectangle view = g.getClipBounds();


VolatileImage image = createVolatileImage(view.width, view.height);
Graphics2D buffer = image.createGraphics();
// translate to camera location
buffer.translate(-cx, -cy);
// renderables contains all currently visible objects
for(Renderable r : renderables) {
r.paint(buffer);
}
g.drawImage(image.getSnapshot(), view.x, view.y, this);

}

The paint method of my circles is as follows:


public void paint(Graphics2D graphics) {
graphics.setPaint(paint);
graphics.fillOval(x, y, radius, radius);
}

The paint is just an rgba color with a < 255:


Color(int r, int g, int b, int a)


It works fast enough for opaque objects, but is there a simple way to speed this up for translucent ones?



Answer



The immediate potential performance problems I see in your code are:



  1. You are recreating the volatile image in every paintComponent

  2. Calling image.getSnapshot() to convert the VolatileImage to BufferedImage.


There is a good example in the beginning of VolatileImage documentation on how to deal with both of the problems.


In the comments you say that 2. is required so that you can later use BufferedImageOp to filter the rendered image. I think this is a mistake, because as far as I know, BufferedImageOp processes each individual pixel of the image on CPU. This operation alone is likely much slower than any problems regarding image creation or conversion.



I recommend you to take a look at AlphaComposite and the related tutorial. Alternatively depending on what exactly you want to achieve, you could just fill another semi-transparent rectangle on top of everything. With a TexturePaint you can probably create the noise filter you are looking for.


In addition instead of using VolatileImages, you could try GraphicsConfiguration.createCompatibleImage to create accelerated BufferedImages. Benchmark if this has the same performance as VolatileImage. If it does, it will be easier to manage than VolatileImage.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...