【问题标题】:What is the fastest way to draw pixels in Java在Java中绘制像素的最快方法是什么
【发布时间】:2012-11-18 07:04:12
【问题描述】:

我有一些代码可以在随机位置生成粒子,并以随机方向和速度移动。

循环中的每次迭代,我都会移动所有粒子,并在我的 jpanel 上调用 repaint。

对于 1,000 个粒子,我的速度约为每秒 20 到 30 帧。我计划最终拥有 100,000 到 1,000,000 个粒子。

在绘画中,我只在窗口大小改变时创建一个新的缓冲图像。我将像素绘制到bufferedimage,然后调用drawImage来显示图像。

每个粒子都是一个像素,我已经确定所有时间都用于实际绘制像素。因此,增加粒子数量会大大降低帧速率。

我试过g.drawline(x,y,x+1,y),img.setRGB(x,y,color),通过调用img.getRaster().getDataBuffer()得到一个像素数组。 getData(),然后设置pixelData[y*width+x] = color。

通过这些不同的像素绘制方式,我在帧速率上只得到了很小的差异。

这是我的问题:绘制像素最快的方法是什么? bufferedimage 是否可行?

谢谢。

【问题讨论】:

  • 虽然可能与您的想法略有不同,但您可能想尝试一些 GPU 编程技术。您可以阅读here,了解使用 OpenCL 改编的百万粒子示例。

标签: java performance pixel bufferedimage


【解决方案1】:

我认为通过缓冲图像的数据缓冲区直接进行像素操作是使用标准库绘制内容的最快方法,因为您可以将图形对象开销降至最低。

但正如 Perception 所说,如果你想显示 100'000 个或更多粒子,你应该考虑使用 OpenCl 进行 GPU 编程。

LWJGL for a small and easy to use Java-OpenGL/CL/AL binding

【讨论】:

    【解决方案2】:

    尝试使用java.awt.image.VolatileImage。它可以在没有任何 CPU 渲染的情况下与完全硬件加速一起使用。

    【讨论】:

      【解决方案3】:

      在使用 img.getRaster().getDataBuffer().getData() 时,您应该在标准计算机上获得更快的帧速率。我知道这是一个事实,因为我可以以每秒 20-30 帧的速度绘制整个屏幕,并且屏幕总共有 1,000,000 像素。我通过将渲染例程一分为二并使用两个线程来获得这种速度。我的 CPU 是 1.5GHz。

      因此,我认为您在移动像素时可能出现了编码错误。请记住:创建新对象的操作比添加操作长 100 倍。还要看看你是否可以删掉任何 if 语句。

      另外,这可能很愚蠢,但我假设您每帧只调用一次 img.getRaster().getDataBuffer().getData()?

      在相关说明中,绘制多像素粒子自然需要很长时间。

      【讨论】:

        【解决方案4】:

        我看到在设置 BufferedImage 数据的字节方面有了巨大的改进。为此,您需要从 BufferedImage 获取数据,将其转换为字节数组,设置每个字节(取决于图像的类型,字节排列会有所不同。例如:ARGB 将有一个字节用于 alpha ,一个红色,一个绿色,一个蓝色。一个像素将是一个连续 4 个字节的块。) 阅读更多关于获取数据的信息here

        【讨论】:

          【解决方案5】:

          永远不要调用 repaint();那是给新手的,在你不必调用 repaint(); 的地方玩这个。在过去的两个月里,这种方法给我带来了如此多的痛苦和不适,我很难过没有人告诉我还有另一种方法。 1,000,000 个粒子会很快变得昂贵,因此您可能需要考虑蒙特卡洛方法,请参阅http://raytracey.blogspot.com/ 以获得更便宜的渲染选项。我不知道在坚持 20-30fps 的情况下你是否能负担得起所有这些粒子的操作,我刚刚观看了一个 10 秒的流体模拟,在 2.4ghz 6gb ram 机器上花了 3 周时间。我道歉是因为我在 BufferedImage 中的唯一经验是导入 .png 以使用 Graphics g 进行绘制。我最近参与了一个计算成本非常高的项目,并且由于时间线我无法使用 gpu 加速我的程序,所以如果你在同一条船上,试试这个 包装宠物;

          import java.awt.Color;
          import java.awt.Dimension;
          import java.awt.Graphics;
          import java.awt.event.MouseEvent;
          import java.awt.event.MouseListener;
          import java.io.IOException;
          import javax.swing.*;
          
          
          public class pet extends JPanel implements MouseListener{
          public static JFrame frame = new JFrame("frame");
          public pet() throws IOException{
           setPreferredSize(new Dimension(870, 675));         //configuring panel
           addMouseListener(this);
          }
          public static void main(String[] args) throws IOException{
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              JComponent newContentPane = new pet();
              newContentPane.setOpaque(true);
              frame.setContentPane(newContentPane);
              frame.pack();
              frame.setVisible(true);
              frame.addMouseListener(new pet());
          }
          public void paintRectangleAtPoint(Graphics g, int x, int y){
          g.setColor(Color.BLACK);
          g.drawRect(x, y, 100,100);
          }
          public void paintStuff(Graphics g, int x, int y){
          g.setColor(Color.BLACK);
          g.drawRect(x, y, 100,100);
          }
          @Override
          public void mouseClicked(MouseEvent e) {
          paintStuff(frame.getGraphics(),e.getX(), e.getY());
          
          }
          @Override
          public void mousePressed(MouseEvent e) {
          // TODO Auto-generated method stub
          
          }
          @Override
          public void mouseReleased(MouseEvent e) {
          // TODO Auto-generated method stub
          
          }
          @Override
          public void mouseEntered(MouseEvent e) {
          // TODO Auto-generated method stub
          
          }
          @Override
          public void mouseExited(MouseEvent e) {
          // TODO Auto-generated method stub
          
          }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-30
            • 1970-01-01
            • 2015-12-02
            • 1970-01-01
            • 1970-01-01
            • 2011-01-24
            相关资源
            最近更新 更多