Java 2D绘图最佳性能

Java 2D绘图最佳性能,java,performance,graphics,java-2d,Java,Performance,Graphics,Java 2d,我正在编写一个Java 2D游戏。我正在使用内置的Java 2D绘图库,在图形2D上绘图,我从JFrame中的画布(有时是全屏)中的BufferStrategy获得。缓冲策略是双缓冲的。通过计时器主动完成重新喷漆。但是我有一些性能问题,特别是在Linux上 Java2D有很多创建图形缓冲区和绘制图形的方法,我不知道我做的是否正确。我一直在尝试graphics2d.getDeviceConfiguration().CreateCompatibleEvolatileImage,它看起来很有希望,但我

我正在编写一个Java 2D游戏。我正在使用内置的Java 2D绘图库,在图形2D上绘图,我从JFrame中的画布(有时是全屏)中的BufferStrategy获得。缓冲策略是双缓冲的。通过计时器主动完成重新喷漆。但是我有一些性能问题,特别是在Linux上

Java2D有很多创建图形缓冲区和绘制图形的方法,我不知道我做的是否正确。我一直在尝试graphics2d.getDeviceConfiguration().CreateCompatibleEvolatileImage,它看起来很有希望,但我没有真正的证据证明,如果我将绘图代码切换到这个位置,速度会更快


根据您的经验,在Java 1.5+中,在屏幕上渲染2D图形的最快方法是什么?请注意,这个游戏已经遥遥领先,所以我不想切换到完全不同的绘图方法,比如OpenGL或游戏引擎。我基本上想知道如何以最快的方式使用Graphics2D对象将内容绘制到屏幕上。

确保使用双缓冲,首先绘制到内存中的一个大缓冲区,然后在所有绘制完成后刷新到屏幕上。

我使用Java完成了一些基本的绘图应用程序。我没有做过太过图形化的工作,但我建议您对所有的“重新绘制”调用都有很好的处理能力。对父容器进行额外的重新绘制调用可能会使渲染量加倍。

有几件事需要记住

1) is refreshing显示了如何使用SwingTimer,这可能是调用repaint的一个好选项。重新油漆(正如之前的海报所说的,这很重要,所以你不会做太多的工作)

2) 确保你只画了一条线。从多线程更新UI可能会导致令人讨厌的事情


3) 双缓冲。这使渲染更加平滑。我一直在看这个问题,希望有人能给你一个比我更好的答案

同时,我发现以下内容是在JDK1.4的beta版之后编写的。这里有一些关于微调的有趣建议,包括运行时标志(在本文底部):

Solaris和Linux的运行时标志

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

-Dsun.java2d.pmoffscreen=true/false


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

以下是我的一些建议。如果你说得更具体些,你想做什么,我也许能帮上更多的忙。听起来像个游戏,但我不想假设

只画你需要的东西!不要总是盲目地调用repain(),尝试使用repaint(Rect)或repaint(x,y,w,h)等同级函数

使用alpha混合时要非常小心,因为混合图像/原语可能是一项昂贵的操作

尽可能多地尝试预渲染/缓存。如果你发现自己用同样的方式画一个圆,一遍又一遍,考虑画进一个缓冲区,然后画出缓冲区。您正在牺牲内存以换取速度(典型的游戏/高性能图形)


考虑使用OpenGL,使用LWJGL的JOGL。JOGL更像Java,而LWJGL在OpenGL访问之上提供了更多的游戏功能。OpenGL可以比Swing绘制数量级的图形(使用适当的硬件和驱动程序)。

我认为我和你有同样的问题。在这里查看我的帖子:


它显示了性能下降的原因以及如何修复。不过,它并不能保证在所有平台上都能正常工作。你会在这篇文章中看到原因。

这篇文章的答案、答案和我自己的研究的综合:

工作原理:

  • 使用
    GraphicsConfiguration.createCompatibleImage
    创建与所绘制内容兼容的图像。这是绝对必要的
  • 通过
    Canvas.createBufferStrategy
    使用双缓冲绘图
  • 在可用的地方使用
    -Dsun.java2d.opengl=True
    加速绘图
  • 避免使用变换进行缩放。相反,缓存要使用的图像的缩放版本
  • 避免半透明图像!位屏蔽图像很好,但在Java2D中半透明非常昂贵

在我的测试中,使用这些方法,我的速度提高了10-15倍,这使得正确的Java 2D图形成为可能。

如果你不想使用纯Java 2D,另一种选择是使用游戏库,如GTGE或JGame(在谷歌上搜索),然后提供对图形的轻松访问,还提供双缓冲和更简单的绘图命令。

有一个重要的问题尚未提到,我认为:尽可能缓存所有图像。如果有一个对象在屏幕上移动,且其外观变化不大,请将其绘制到图像,然后在每帧的新位置将图像渲染到屏幕上。即使对象非常简单,也要这样做——你可能会惊讶于节省了多少时间。渲染位图比渲染基本体快得多


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

目前,我使用myCanvas.createBufferStrategy(2)。但我不知道手动创建易失性缓冲区是否会更快。只是出于好奇,游戏是关于什么的德雷:马里奥·奥尔特冈: