6

ランダムな位置でパーティクルを生成し、ランダムな方向と速度で移動するコードがいくつかあります。

ループを繰り返すたびに、すべてのパーティクルを移動し、jpanelでrepaintを呼び出します。

1,000個のパーティクルの場合、1秒あたり約20〜30フレームを取得しています。最終的には100,000から1,000,000のパーティクルを使用する予定です。

ペイントでは、ウィンドウのサイズが変更された場合にのみ、新しいバッファイメージを作成します。バッファリングされた画像にピクセルを描画し、drawImageを呼び出して画像を表示します。

各パーティクルは1つのピクセルであり、実際にピクセルを描画するのに時間がかかると判断しました。したがって、パーティクルの数を増やすと、フレームレートが大幅に低下します。

g.drawline(x、y、x + 1、y)、img.setRGB(x、y、color)を試し、img.getRaster()。getDataBuffer()。getData()を呼び出してピクセルの配列を取得しました、次にpixelData [y * width + x]=colorを設定します。

ピクセルを描画するこれらのさまざまな方法では、フレームレートにわずかな違いしかありません。

これが私の質問です:ピクセルを描く最も速い方法は何ですか?bufferedimageは行く方法でさえありますか?

ありがとう。

4

5 に答える 5

1

java.awt.image.VolatileImageを使用してみてください。CPUレンダリングなしで、完全なハードウェアアクセラレーションで使用できる可能性があります。

于 2012-12-04T10:07:18.020 に答える
1

I think the direct pixelmanipulation via the databuffer of the bufferedimage is the fastest way to draw something with the standard-library because you reduce the graphics object overhead to a minimum.

But as Perception said if you want to display 100'000 particles or more you should consider the GPU programming with OpenCl.

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

于 2012-12-04T09:50:33.917 に答える
1

img.getRaster().getDataBuffer().getData() を使用すると、標準のコンピューターでより高速なフレーム レートが得られるはずです。画面全体を毎秒 20 ~ 30 フレームでペイントでき、画面の合計ピクセル数は 1,000,000 であるため、これは事実です。レンダリング ルーチンを 2 つに分割し、2 つのスレッドを使用することで、この速度を実現しました。私のCPUは1.5GHzです。

このため、ピクセルの移動でコーディング エラーが発生した可能性があると思います。覚えておいてください: 新しいオブジェクトの作成は、追加よりも 100 倍長い操作です。また、if ステートメントを削除できるかどうかも確認してください。

また、これはばかげているかもしれませんが、フレームごとに一度だけ img.getRaster().getDataBuffer().getData() を呼び出していると思いますか?

関連する注意事項として、マルチピクセル パーティクルの描画には当然時間がかかります。

于 2012-12-14T23:19:56.707 に答える
1

バイトを BufferedImage のデータに設定する際に大幅な改善が見られます。これを行うには、BufferedImage からデータを取得し、それをバイト配列に変換し、各バイトを設定する必要があります (画像の種類に応じて、バイト配置は異なります。たとえば、ARGB にはアルファ用に 1 バイトがあります。 、赤に 1 つ、緑に 1 つ、青に 1 つ。1 つのピクセルは 4 つの連続したバイトのブロックになります。) データの取得について詳しくは、こちらをご覧ください。

于 2016-05-07T19:26:18.580 に答える
-2

repaint() を呼び出さないでください。これは初心者向けです。repaint(); を呼び出す必要がない場所でこれを試してみてください。その方法は、過去 2 か月間、私に多くの痛みと不快感をもたらしました。別の方法があることを誰も教えてくれなかったのは残念です。1,000,000 個の粒子はすぐに高価になるため、モンテカルロ法を検討することをお勧めします。http://raytracey.blogspot.com/を参照してください。安価なレンダリング オプションの場合。20 ~ 30 fps に準拠しながら、これらすべてのパーティクルを操作する余裕があるかどうかはわかりませんが、2.4 GHz 6 GB RAM マシンで 3 週間かかった 10 秒間の流体シミュレーションを見ただけです。BufferedImage での私の唯一の経験は、.png をインポートして Graphics g で描画することであるため、お詫び申し上げます。私は最近、非常に計算コストの高いプロジェクトに取り組みましたが、タイムラインではプログラムを gpu 高速化できませんでした。同じボートに乗っている場合は、このパッケージ pet を試してください。

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

}
}
于 2016-01-27T03:04:47.710 に答える