Быстрые пиксельные операции Java - PullRequest
11 голосов
/ 25 июня 2011

Я хотел бы знать, как бы я лучше справлялся с пиксельными операциями в Java.Я использую свинг и рисую прямоугольник размером 1 на 1 пиксель очень медленно.Мне нужно получить как минимум 60 кадров в секунду, не используя слишком много ресурсов.Означает ли вначале блеф для изображения, что его можно успешно архивировать?Или это вообще плохая идея делать это с Java, и мне нужно придерживаться C или другой альтернативы?

Я только начинаю писать raycaster и начиная с openCL, который я использую, имеет обертку для Java, я предпочитаю работать на Java.

Ответы [ 2 ]

5 голосов
/ 26 июня 2011

Добавление к предложению @ camickr:

Создайте BufferedImage (BI), оберните его в IconImage, установите в качестве значка для JLabel. Нарисуйте изменения в BI и вызовите JLabel repaint (), чтобы очистить их. изменения на экране. Кэширование частичного изображения в BI уменьшает объем работы для процедуры рисования. Нужно просто блитировать изображение, а не отображать его. Используйте SwingWorkers для развертывания фоновых потоков, чтобы выполнить вычисления и передать результаты обратно в EDT для рисования.

Пока вы говорите о статическом изображении, оно будет работать нормально. Если вы рассматриваете что-то более похожее на видеоигру (некоторые фиксированные изображения и другие движущиеся изображения), взгляните на VolatileImage. Здесь есть хорошее описание: http://gpwiki.org/index.php/Java:Tutorials:VolatileImage

Обновление:

Следующее дает мне чуть более 80 кадров в секунду:

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);
            }
        });
    }
}
4 голосов
/ 25 июня 2011

Используйте BufferedImage и метод setRGB (...).Затем вы рисуете все изображение в своей программе рисования.

...