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

在Java中绘制像素的最快方法是什么,java,performance,pixel,bufferedimage,Java,Performance,Pixel,Bufferedimage,我有一些代码可以在随机位置生成粒子,并以随机的方向和速度移动 通过循环的每次迭代,我移动所有粒子,并在我的jpanel上调用repaint 对于1000个粒子,我得到每秒20到30帧。我计划最终有100000到1000000个粒子 在paint中,我仅在窗口大小更改时创建新的BuffereImage。我将像素绘制到BuffereImage,然后调用drawImage来显示图像 每一个粒子都是一个像素,我已经确定所有的时间都是用来画像素的。因此,增加粒子数将大大降低帧速率 我尝试过g.drawli

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

通过循环的每次迭代,我移动所有粒子,并在我的jpanel上调用repaint

对于1000个粒子,我得到每秒20到30帧。我计划最终有100000到1000000个粒子

在paint中,我仅在窗口大小更改时创建新的BuffereImage。我将像素绘制到BuffereImage,然后调用drawImage来显示图像

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

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

我用这些不同的方法绘制像素,在帧速率上只得到一个小的差别

我的问题是:画像素最快的方法是什么?BuffereImage是一个不错的选择吗


谢谢。

我认为通过BuffereImage的databuffer直接进行像素操作是使用标准库绘制图形的最快方法,因为可以将图形对象的开销降至最低

但是,如果你想显示100万个或更多的粒子,你应该考虑使用OpenCL。
尝试使用。它可以在没有任何CPU渲染的情况下与全硬件加速一起使用。

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

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

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

另一方面,绘制多像素粒子自然需要很长时间。

永远不要调用repaint();这是针对noob的,在不需要调用repaint()的地方使用它;。在过去的两个月里,这种方法给我带来了如此多的痛苦和不适,我很难过,没有人告诉我还有别的方法。1000000个粒子会变得很贵,所以你可能想考虑一个蒙特卡洛方法,看看更便宜的渲染选项。我不知道你是否负担得起在20-30fps的速度下操纵所有这些粒子,我只是在2.4ghz 6gb内存机器上观看了一个10秒的流体模拟,耗时3周。我对此表示歉意,因为我在BuffereImage中的唯一经验是导入.png以使用图形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

}
}

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

尽管可能与您的想法有点相左,但您可能希望尝试一些GPU编程技术。您可以阅读使用OpenCL改编的百万粒子示例。