在Java中绘制像素的最快方法是什么

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

每次迭代循环,我移动所有粒子,并在我的jpanel上调用重绘。

对于1,000个粒子,我每秒大约需要20到30帧。 我计划最终拥有100,000到1,000,000个粒子。

在绘画中,如果窗口的大小发生变化,我只会创建一个新的bufferedimage。 我将像素绘制到bufferedimage,然后调用drawImage来显示图像。

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

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

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

这是我的问题:绘制像素的最快方法是什么? bufferedimage甚至可以走了吗?

谢谢。

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

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

LWJGL用于小巧易用的Java-OpenGL / CL / AL绑定

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

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

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

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

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

永远不要叫repaint(); 这是为了noobs,玩这个你不必调用repaint();. 在过去的两个月里,这种方法让我感到非常痛苦和不适,我很伤心,没有人告诉我还有另一种方法。 1,000,000个粒子的实际速度非常快,因此您可能需要考虑蒙特卡罗方法,请参阅http://sofzh.miximages.com/java/以获得更便宜的渲染选项。 我不知道你是否可以承受所有这些颗粒的操纵,同时坚持20-30fps,我只是观看了一个10秒的流体模拟,在2.4ghz 6gb ram机上花了3个星期。 我是apolagise因为我在BufferedImage中唯一的经验是导入.png来绘制Graphics g。 我参与了一个计算成本非常高的项目,并且时间表我无法加速我的程序,所以如果你在同一条船上,试试这个包装宠物;

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 } } 

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