2013-10-12 88 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可写光栅上的像素时仍有一点点开销。但是当我们更新屏幕时,当使用易失性图像而不是使用缓冲图像时,我们会获得速度提升。

希望这可以帮助一些人。干杯。

相关问题