2008-09-29 128 views
31

我正在编写Java 2D游戏。我正在使用内置的Java 2D绘图库,使用从JFrame中的Canvas获取的Graphics2D(有时会进行全屏筛选)。 BufferStrategy是双缓冲的。通过定时器主动完成重绘。尽管如此,我仍然遇到一些性能问题,特别是在Linux上。Java 2D绘图的最佳性能

Java2D有很多创建图形缓冲区和绘制图形的方法,我只是不知道自己做的是否正确。我一直在尝试使用graphics2d.getDeviceConfiguration()。createCompatibleVolatileImage,这看起来很有前途,但我没有真正的证据证明,如果我将绘图代码切换到该图形,速度会更快。

根据您的经验,在Java 1.5+中将2D图形渲染到屏幕上的最快方法是什么?请注意,这个游戏还有很长的路要走,所以我不想切换到完全不同的绘图方法,如OpenGL或游戏引擎。我基本上想知道如何获得使用Graphics2D对象在屏幕上绘制东西的最快方法。

+0

出于好奇,游戏是什么? :D – 2008-09-29 12:48:32

+0

回复:Mario Ortegon:http:// www。metalbeetle.com/spaceexploration/。我没有把链接放到主页上,因为那只是隐形广告。 – Zarkonnen 2008-09-29 12:53:10

+1

链接看起来有点奇怪(..但那是8年前) – 2016-03-31 13:51:11

回答

16

我遇到同样的问题,因为我认为。点击这里,查看我的帖子:

Java2D Performance Issues

它显示了性能下降,以及如何解决它的原因。尽管如此,并不能保证在所有平台上都能很好地工作。你会在帖子中看到为什么。

0

请确保您使用双缓冲,先将内存中的一个大缓冲区绘制出来,然后在完成所有绘制时将其刷新到屏幕。

1

我已经完成了一些使用Java的基本绘图应用程序。我没有对任何过于图形密集的工作做过工作,但我建议您对所有'repaint'调用都有很好的处理。对父容器进行额外的重绘调用可能会使您的操作量翻倍。

0

有几件事情你需要记住

1)是清爽this link展示了如何使用这可能是调用重绘一个不错的选择swingtimers。重新绘制出来(正如以前的海报所说的重要,所以你没有做太多的工作)。

2)确保你只在一个线程中绘图。从多线程更新UI可能导致令人讨厌的事情。

3)双缓冲。这使得渲染更平滑。 this site有一些更好的信息给你

1

我一直在看这个问题,希望有人会给你比我更好的答案。

与此同时,我发现以下Sun white paper这是在jdk 1.4的测试版后编写的。这里有上微调了一些有趣的建议,其中包括运行时的标志(在文章底部):

运行标志对于Solaris和Linux

与SDK的Beta 3的版本开始,版本1.4,当2DGA不可用时,无论您是在本地还是远程显示环境中,Java 2D都默认将图像存储在像素图中。您可以使用pmoffscreen标志覆盖此行为:

-Dsun.java2d.pmoffscreen =真/假

如果您将此标志设置为true,即使DGA可用,也可以启用离线pixmap支持。如果您将此标志设置为false,则禁用屏幕外像素图支持。 禁用屏幕外像素图支持可以解决一些渲染问题。

10

这里有一些提示我的头顶。如果你更具体,你想做什么,我可能会帮助更多。听起来像是一场游戏,但我不想假设。

只画出你需要什么!不要一直盲目地调用repaint(),尝试像repaint(Rect)或repaint(x,y,w,h)的兄弟姐妹。

要非常小心以阿尔法混合,因为它可以是一个昂贵的操作来混合图像/原语。

尝试预渲染/缓存尽可能。如果您发现自己以同样的方式绘制一个圆,反复考虑,可以考虑绘制成BufferedImage,然后绘制BufferedImage。你牺牲速度的内存(典型的游戏/高PERF图形)

考虑使用OpenGL,使用LWJGL的JOGL。 JOGL更像Java,而LWJGL在OpenGL访问的基础上提供更多的游戏功能。 OpenGL可以比Swing可以画出数量级(具有适当的硬件和驱动程序)。

26

的答案,这个帖子的合成,答案Consty's,和我自己的研究:

什么工作:

  • 使用GraphicsConfiguration.createCompatibleImage来创建你画什么兼容的影像。这是绝对必要的!
  • 通过Canvas.createBufferStrategy使用双缓冲绘图。
  • 使用-Dsun.java2d.opengl=True在哪里可以加快绘图。
  • 避免使用变换进行缩放。相反,缓存将要使用的图像的缩放版本。
  • 避免半透明的图像! Bitmasked图像很好,但是Java2D中的半透明代价非常高。

在我的测试中,使用这些方法,我得到了10倍的速度增长 - 15倍,使正确的Java 2D图形的可能性。

0

如果你不想去的纯Java 2D另一种方法是使用一个游戏库如GTGE或JGame(寻找他们在谷歌),然后提供方便地访问图形和还提供双缓冲和更简单绘图命令。

3

还有哪些尚未提及的重要一员,我想:尽你所能的缓存图片。如果您有一个物体在屏幕上移动,并且外观变化不大,请将其绘制到图像上,然后在每个帧的新位置将图像渲染到屏幕上。即使这个对象是一个非常简单的对象,你也许会惊讶于你节省了多少时间。渲染位图比渲染基元快得多。

您可能还需要明确设置渲染提示,并在质量考虑允许的情况下关闭抗锯齿等功能。