我是游戏编程的新手。我知道如何使用BufferedImage
将像素绘制到setPixel()
。在较大的格式上速度非常慢,所以我继续前进并找到VolatileImage
(花了我一个星期左右)。绘制线条,字符串,rects等相当容易,但我无法绘制单个像素。我已经尝试使用drawLine(x,y,x,y)
但是我在800x600图像上获得了3-4 FPS。
java setPixel()
中不包含setRGB()
或VolatileImage
的事实让我非常生气和困惑。
我有4个问题:
有没有办法在VolatileImage上绘制单个像素? (1440x900格式,FPS> 40)
我可以用更快的方法在BufferedImage中绘制像素吗? (相同的1440x900,FPS> 40)
还有其他方法可以快速为3D游戏绘制像素吗?
我可以加速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。
答案 0 :(得分:1)
你基本上用另一个使用CPU 绘制一个像素。这种方法无法加速,因此这种方法对VolatileImage没有任何意义。您获得的低FPS表明这甚至会导致显着的开销,因为每个像素绘制操作都会发送到图形卡(使用位置和颜色等信息),这比修改3或4个字节的RAM需要更长的时间。 / p>
我建议要么单独停止绘制每个像素,要么想办法让你的绘图算法直接在图形卡上运行(很可能需要另一种语言而不是Java)。
答案 1 :(得分:1)
这篇文章得到答案已经超过4年了。我也在寻找这个问题的答案,偶然发现了这篇文章。经过一番搜索,我得到了它的工作。下面我将使用VolatileImage将源发布到渲染像素。
似乎Java隐藏了我们将像素直接绘制到VolatileImage的能力,但我们可以将缓冲图像绘制到它。有充分的理由。使用该软件绘制像素并不能真正帮助加速(在Java看来)。如果您可以将像素绘制到BufferedImage,然后在VolatileImage上渲染它,那么您可以获得速度加值,因为从那时起它的硬件加速了。
下面的来源是一个独立的例子。您可以将几乎所有的面食复制到您的项目中并运行它。
在构造函数中,我保存了app / game的Graphics环境。
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获取Graphics并在那里渲染我的缓冲区。如果我不冲洗(),则不会渲染任何内容。
@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可写光栅上绘制像素时,仍有一点开销。但是当我们更新屏幕时,我们会在使用易失性图像而不是使用缓冲图像时获得速度提升。
希望这可以帮助一些人。欢呼声。