2011-06-25 75 views
11

我想知道我將如何處理Java中最好的像素操作。我正在使用擺動,並繪製一個1乘1像素的矩形非常緩慢。我需要至少獲得60 fps,而不需要太多的資源。首先意味着這可能會成功實現嗎?或者,在Java中這樣做是否是一個糟糕的主意,我是否需要堅持C或其他選擇?Java快速像素操作

我正在寫一個raycaster,因爲我使用的openCL有一個Java包裝器,所以我更喜歡使用Java。

+1

我建議在中間圖像的概念讀了。這裏有一個例子 - http://www.java2s.com/Code/Java/Advanced-Graphics/IntermediateImages.htm – mre

+0

我認爲技術Intermidiate Images是沿着我描述的路線;傳送圖像。但是我不熟悉Java中的這個速度結果,這是我想知道的。 – RobotRock

+0

這種技術不會在Java中獲得60fps的結果,仍然太慢。 – RobotRock

回答

5

添加到@ camickr的建議:

創建一個BufferedImage(BI),在IconImage包裝它,將其設置爲一個JLabel的圖標。將更改繪製到BI上並調用JLabel的repaint()來刷新這些。改變到屏幕。在BI中緩存部分圖像減少了繪畫例程的工作量。它只需要使圖像閃爍,而不是渲染圖像。使用SwingWorkers部署後臺線程以運行計算並將結果傳回EDT以進行繪製。

只要你在談論靜態圖像,這將工作正常。如果您正在考慮更像視頻遊戲(某些固定圖像和其他動態圖像),請查看VolatileImage。這是一個很好的描述在這裏:http://gpwiki.org/index.php/Java:Tutorials:VolatileImage

更新:

下面讓我有點超過80個FPS:

public class Demo extends javax.swing.JPanel { 
    private Image src = null; 
    public Demo() { 
     new Worker().execute(); 
    } 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (src != null) g.drawImage(src, 0, 0, this); 
    } 
    private class Worker extends SwingWorker<Void, Image>{ 
     private final Color[] colors = { Color.red, Color.green, Color.blue }; 
     protected void process(List<Image> chunks){ 
      for (Image bufferedImage : chunks){ 
       src = bufferedImage; 
       repaint(); 
      } 
     } 
     protected Void doInBackground() throws Exception{ 
      int frames = 0; 
      int[] mem = new int[1024 * 768]; 
      long start = System.currentTimeMillis(); 
      long end = start + 15000; 
      long last = start; 
      while (last < end){ 
       int col = colors[frames % colors.length].getRGB(); 
       for (int y = 0; y < 768; y++) 
        for (int x = 0; x < 1024; x++) 
         mem[x + y * 1024] = col; 
       Image img = createImage(new MemoryImageSource(1024, 768, mem, 0, 1024)); 
       BufferedImage bi = new BufferedImage(1024, 768, BufferedImage.TYPE_INT_ARGB); 
       Graphics2D g2 = bi.createGraphics(); 
       g2.drawImage(img, 0, 0, null); 
       g2.dispose(); 
       publish(bi); 
       last = System.currentTimeMillis(); 
       frames++; 
      } 
      System.err.println("Frames = " + frames + ", fps = " + ((double) frames/(last - start) * 1000)); 
      return null; 
     } 
    } 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run(){ 
       JFrame jf = new JFrame(); 
       jf.getContentPane().add(new Demo(), BorderLayout.CENTER); 
       jf.setSize(1024, 768); 
       jf.setVisible(true); 
      } 
     }); 
    } 
} 
+0

我得到10fps 1024x768圖像上的像素填充屏幕。任何想法如何加快這一點?我正在使用你所說的技術,併爲渲染運行一段時間的真循環。 – RobotRock

+0

如果您只是渲染到BI並且實際上沒有將其繪製到屏幕上,您會得到什麼樣的性能?通常,光線追蹤中的瓶頸在計算中比屏幕更新更多。每次完成一個屏幕的計算值時,試着輸出System.currentTimeMillis()。 –

+0

我正在畫非計算的像素,所以只是簡單地逐個像素填充屏幕。在320x240我得到100 + fps,在1024x768它下降到10.如果我離開repaint(),它不會改變結果。 – RobotRock

4

使用BufferedImage和setRGB(...)方法。然後在繪畫例程中繪製整個圖像。

+0

我能以這種方式滿足要求(60 fps)嗎(分辨率爲1024x768)? – RobotRock