我試圖用Canvas創建一個粒子系統。有趣的是,drawImage方法非常快。即使使用drawImage,我也能以60 fps達到90.000個粒子。但是,那只是相同的圖像。當我爲粒子使用不同的圖像時,性能顯着下降。然後我改變了圖像的順序,這樣e。 G。首先繪製image1的所有粒子,然後繪製所有image2等,並且性能再次良好。
問題
有誰知道這是爲什麼?人們必須考慮drawImage中是否有一些內部緩存機制?
代碼
這裏的示例代碼:
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class CanvasExample extends Application {
GraphicsContext gc;
double width = 800;
double height = 600;
Image[] images;
@Override
public void start(Stage primaryStage) {
Canvas canvas = new Canvas(width, height);
gc = canvas.getGraphicsContext2D();
BorderPane root = new BorderPane();
root.setCenter(canvas);
Scene scene = new Scene(root, width, height);
scene.setFill(Color.BEIGE);
primaryStage.setScene(scene);
primaryStage.show();
createImages(255);
AnimationTimer loop = new AnimationTimer() {
double prev = 0;
double frameCount = 0;
double fps = 0;
@Override
public void handle(long now) {
// very basic frame counter
if(now - prev > 1_000_000_000) {
System.out.println("FPS: " + frameCount);
fps = frameCount;
prev = now;
frameCount = 0;
} else {
frameCount++;
}
// clear canvas
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, width, height);
// paint images
int numIterations = 90000;
for(int i=0; i < numIterations; i++) {
int index = i % 2; // <==== change here: i % 1 is fast, i % 2 is slow
gc.drawImage(images[ index], 100, 100);
}
gc.setFill(Color.WHITE);
gc.fillText("fps: " + fps, 0, 10);
}
};
loop.start();
}
public void createImages(int count) {
Rectangle rect = new Rectangle(10,10);
rect.setFill(Color.RED);
images = new Image[count];
for(int i=0; i < count; i++) {
images[i] = createImage(rect);
}
}
/**
* Snapshot an image out of a node, consider transparency.
*
* @param node
* @return
*/
public Image createImage(Node node) {
WritableImage wi;
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
int imageWidth = (int) node.getBoundsInLocal().getWidth();
int imageHeight = (int) node.getBoundsInLocal().getHeight();
wi = new WritableImage(imageWidth, imageHeight);
node.snapshot(parameters, wi);
return wi;
}
public static void main(String[] args) {
launch(args);
}
}
這是非常基本的。圖像是從一個矩形創建的,然後放入一個數組中,並在AnimationTimer循環中,圖像在畫布上繪製numIterations-times。
當您使用index = i % 1
,我。即一遍又一遍的相同圖像,然後在我的系統上的fps是60幀/秒。如果您使用index = i % 2
,我。即交替的圖像,那麼我的系統上的fps是14 fps。這是相當大的差異。
非常感謝您的幫助!