2013-10-12 78 views
1

我是遊戲編程的相對新手。我知道如何使用setPixel()將像素繪製到BufferedImage。在較大的格式下速度非常慢,所以我繼續前進,發現VolatileImage(花了我一個星期左右的時間)。繪製線條,字符串,矩形等相當容易,但我無法繪製單個像素。我已經嘗試過使用drawLine(x,y,x,y),但我在800x600圖像上獲得3-4 FPS。 java在VolatileImage中沒有包含setPixel()setRGB()的事實讓我非常生氣和困惑。爲什麼VolatileImage沒有set/getPixel()方法

我有4個問題:

  1. 有沒有辦法畫上一個VolatileImage,個別像素? (關於1440格式的FPS> 40)

  2. 能否繪製像素與更快的方法一個BufferedImage? (同1440,FPS> 40)

  3. 是否有任何其他的方式來繪製像素足夠快的3D遊戲?

  4. 我可以讓我的BufferedImage的硬件加速(使用setAccelerationPriority(1F)嘗試,但它不工作)

請,如果您有任何想法告訴我。我無法繼續讓我的遊戲沒有這個信息。我已經制作了3D渲染算法,但我需要能夠繪製快速像素。我對這個遊戲有很好的感覺。

下面的代碼,如果它可以幫助你來幫助我

public static void drawImageRendered (int x, int y, int w, int h) { // This is just a method to test the performance 

    int a[] = new int[3]; // The array containing R, G and B value for each pixel 
    bImg = Launcher.contObj.getGraphicsConfiguration().createCompatibleImage(800, 600); // Creates a compatible image for the JPanel object i am working with (800x600) 
    bImg.setAccelerationPriority(1F); // I am trying to get this image accelerated 
    WritableRaster wr = bImg.getRaster(); // The image's writable raster 
    for (int i = 0; i < bImg.getWidth(); i++) { 
     for (int j = 0; j < bImg.getHeight(); j++) { 
      a[0] = i % 256; 
      a[2] = j % 256; 
      a[1] = (j * i) % 256; 
      wr.setPixel(i, j, a); // Sets the pixels (You get a nice pattern) 
     } 
    } 
    g.drawImage(bImg, x, y, w, h, null); 
} 

我更希望不使用的OpenGL 任何其他外部庫,只是普通的Java。

+1

良好的工作夥計,以及我不知道你將如何繪製目標圖像,但我沒有刷新時間緩衝的圖像和繪畫問題(完全用純像素setRGB()),[this例如](http://arashmd.blogspot.com/2013/07/java-thread-example.html#lc)可能會有所幫助,它是關於屏幕保護程序,我已經超過60 FPS只有CPU,超過500 FPS與GPU – 2013-10-12 19:33:25

+0

仍然沒有找到任何可以幫助我的東西 –

+0

那麼您是否以平行方式繪製圖像?你如何管理目標圖像/畫框花花公子? – 2013-10-12 19:58:23

回答

1

那麼你正在使用的CPU基本繪製等後一個像素。這是無法加速的,因此這樣的方法對於VolatileImage根本沒有任何意義。由於每個像素繪圖操作都發送到圖形卡(顏色位置爲&),所花的時間比修改3或4個字節的RAM花費的時間要長,所以您得到的FPS較低意味着這會導致很大的開銷。

我建議是停止單獨繪製每個像素或找出一種方法,使直接在顯卡(其最有可能需要比Java的另一種語言)上運行您的繪圖算法。

0

自從這篇文章得到答案已經4年多了。我也在尋找這個問題的答案,並偶然發現這篇文章。經過一些更多的搜索,我得到它的工作。在下面,我將把源代碼發佈到使用VolatileImage渲染像素。

看起來Java隱藏了我們將像素直接繪製到VolatileImage的能力,但我們可以將緩衝圖像繪製到它上面。有充分的理由。使用該軟件繪製像素並不能真正幫助加速(看起來像Java)。如果您可以將像素繪製到BufferedImage上,然後將其渲染到VolatileImage上,那麼您可能會獲得速度獎勵,因爲從這一點開始硬件加速。

下面的源代碼是一個獨立的示例。您可以將麪食幾乎全部複製到您的項目中並運行。

https://github.com/Miekpeeps/JavaSnippets-repo/blob/master/src/graphics_rendering/pixels_03/PlottingVolatile.java

在構造函數中我保存的應用程序/遊戲的圖形環境。

private GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
private GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); 

然後,當我調用一個方法,使硬件,我們創建一個緩衝區。我將透明度設置爲不透明。在我的小引擎中,我處理流水線中另一個線程上的透明度/ alpha混合。

public void setHardwareAcceleration(Boolean hw) 
{ 
    useHW = hw; 
    if (hw) 
    { 
     vbuffer = gc.createCompatibleVolatileImage(width, height, Transparency.OPAQUE); 
     System.setProperty("sun.java2d.opengl", hw.toString()); // may not be needed. 
    } 
} 

對於我更新的每一幀,我從VolatileImage獲取圖形,並在那裏渲染我的緩衝區。如果我沒有flush(),沒有任何東西會被渲染。

@Override 
public void paintComponent(Graphics g) 
{ 
    if(useHW) 
    { 
     g = vbuffer.getGraphics(); 
     g.drawImage(buffer, 0, 0, null); 
     vbuffer.flush(); 
    } 
    else 
    { 
     g.drawImage(buffer, 0, 0, null); 
     buffer.flush(); 
    } 
} 

調用繪製BufferedImage可寫光柵上的像素時仍有一點點開銷。但是當我們更新屏幕時,當使用易失性圖像而不是使用緩衝圖像時,我們會獲得速度提升。

希望這可以幫助一些人。乾杯。

相關問題