代码之家  ›  专栏  ›  技术社区  ›  Zarkonnen

J2D绘图优化性能

  •  31
  • Zarkonnen  · 技术社区  · 17 年前

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

    Java2d有很多创建图形缓冲区和绘制图形的方法,我只是不知道我是否在做正确的事情。我一直在用graphics2d.getDeviceConfiguration().createCompatibleVolatileImage进行试验,这看起来很有希望,但我没有真正的证据证明如果我将绘图代码切换到它会更快。

    根据您的经验,在Java 1.5 +中,以2D图形最快的方式呈现在屏幕上?请注意,游戏还远远领先,所以我不想切换到完全不同的绘图方法,比如OpenGL或游戏引擎。我基本上想知道如何使用一个graphics2d对象将东西绘制到屏幕上的最快方法。

    9 回复  |  直到 10 年前
        1
  •  15
  •   Community Mohan Dere    8 年前

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

    Java2D Performance Issues

    它说明了性能下降的原因以及如何修复性能下降。但是,它并不能保证在所有平台上都能很好地工作。你会在帖子里看到原因的。

        2
  •  29
  •   Community Mohan Dere    8 年前

    综合本帖的答案 Consty's 以及我自己的研究:

    什么工作:

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

    在我的测试中,使用这些方法,我得到了10x-15x的速度增加,使得适当的Java 2D图形成为可能。

        3
  •  10
  •   basszero    17 年前

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

    只画你需要的!不要总是盲目地调用repartt(),尝试一些兄弟姐妹,比如repartt(rect)或repartt(x,y,w,h)。

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

    尽量预渲染/缓存。如果你发现自己以同样的方式一次又一次地画一个圆,考虑画一个BufferedImage,然后只画一个BufferedImage。你牺牲了内存来提高速度(典型的游戏/高性能图形)

    考虑使用OpenGL,使用lwjgl的jogl。JOGL更像Java,而LWJGL在OpenGL Access之上提供更多的游戏功能。OpenGL可以画出比Swing可以大的数量级(使用适当的硬件和驱动程序)。

        4
  •  3
  •   DJClayworth    16 年前

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

    您可能还希望看到显式设置渲染提示,以及在质量考虑允许的情况下关闭反锯齿等功能。

        5
  •  1
  •   Brendan Cashman    17 年前

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

        6
  •  1
  •   Nick Dandoulakis    10 年前

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

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

    Solaris和Linux的运行时标志

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

    -dsun.java2d.pmoffscreen=真/假

    如果将此标志设置为“真”,则即使DGA可用,也会启用屏幕外像素映射支持。如果将此标志设置为false,则禁用屏幕外PixMap支持。 禁用屏幕外的pixmap支持可以解决一些渲染问题。

        7
  •  0
  •   Tom    17 年前

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

        8
  •  0
  •   Steve g    17 年前

    你需要记住以下几点

    1)令人耳目一新 this link 显示如何使用转速表,这可能是调用重新绘制的一个好选项。重新粉刷(如前几张海报所说,这很重要,所以你不会做太多的工作)。

    2)确保只画一条线。从多线程更新用户界面可能会导致讨厌的事情。

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

        9
  •  0
  •   Paul Sagor    17 年前

    如果你不想去纯Java 2D,可以使用GTGE或JGame等游戏库(在谷歌上搜索它们),然后提供对图形的简单访问,并提供双缓冲和更简单的绘图命令。