开发者

Java fast pixel operations

开发者 https://www.devze.com 2023-03-15 14:46 出处:网络
I would like to know how I would handle pixel operations best in Java. I\'m using swing and drawing a rectangle of 1 by 1 pixel is terribly slow. I need to get 60 fps at least, without using too much

I would like to know how I would handle pixel operations best in Java. I'm using swing and drawing a rectangle of 1 by 1 pixel is terribly slow. I need to get 60 fps at least, without using too much resources. Would blitting to an image first mean this could be archieved succesfully? Or is it a bad idea in general开发者_如何转开发 to do this with Java and do I need to stick to C or another alternative?

I'm in the beginning of writing a raycaster and since openCL, which I'm using, has a wrapper for Java, I prefer working in Java.


Adding to @camickr's suggestion:

Create a BufferedImage (BI), wrap it in a IconImage, set it as the icon for a JLabel. Paint changes onto the BI and call JLabel's repaint() to flush those. changes to the screen. Caching the partial image in a BI lessens the amount of work for the paint routine. It just needs to blit the image, not render the image. Use SwingWorkers to deploy background threads to run the calculations and pass the results back to the EDT for painting.

As long as you're talking about a static image, that will work fine. If you are considering something more like a video game (some fixed images and other moving images) take a look at VolatileImage. There is a good description here: http://gpwiki.org/index.php/Java:Tutorials:VolatileImage

Update:

The following gives me a bit over 80 fps:

public class Demo extends javax.swing.JPanel {
    private Image src = null;
    public Demo() {
        new Worker().execute();
    }
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (src != null) g.drawImage(src, 0, 0, this);
    }
    private class Worker extends SwingWorker<Void, Image>{
        private final Color[] colors = { Color.red, Color.green, Color.blue };
        protected void process(List<Image> chunks){
            for (Image bufferedImage : chunks){
                src = bufferedImage;
                repaint();
            }
        }
        protected Void doInBackground() throws Exception{
            int frames = 0;
            int[] mem = new int[1024 * 768];
            long start = System.currentTimeMillis();
            long end = start + 15000;
            long last = start;
            while (last < end){
                int col = colors[frames % colors.length].getRGB();
                for (int y = 0; y < 768; y++)
                    for (int x = 0; x < 1024; x++)
                        mem[x + y * 1024] = col;
                Image img = createImage(new MemoryImageSource(1024, 768, mem, 0, 1024));
                BufferedImage bi = new BufferedImage(1024, 768, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2 = bi.createGraphics();
                g2.drawImage(img, 0, 0, null);
                g2.dispose();
                publish(bi);
                last = System.currentTimeMillis();
                frames++;
            }
            System.err.println("Frames = " + frames + ", fps = " + ((double) frames / (last - start) * 1000));
            return null;
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run(){
                JFrame jf = new JFrame();
                jf.getContentPane().add(new Demo(), BorderLayout.CENTER);
                jf.setSize(1024, 768);
                jf.setVisible(true);
            }
        });
    }
}


Use a BufferedImage and the setRGB(...) method. Then you draw the entire image in your paint routine.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号