【发布时间】:2011-12-19 02:47:00
【问题描述】:
他!
我正在写一个游戏。因为随着时间的推移没有太大的变化,我转而缓冲棋盘的某些部分(在其上进行游戏)并不时复制它。我在前台更改了内容,所以我仍然需要高 fps。我还想放大,这就是有趣的开始:为了节省内存,我重用了缓冲区。每当我缩放应用程序滞后,然后正常运行。
分析后,我发现了两个性能杀手:
清除后台缓冲区(4000x4000 像素,大约需要 29 毫秒。为了保持透明度,我使用 g.fillRect)
将缓冲区复制回真实图像(这当然不是实时的,但同样来自 getBufferStrategy())。这需要 300 毫秒,下一次大约 150 毫秒,然后从第三帧开始它运行顺利。
澄清问题可能出在一些代码上。我通过以下方式创建自己的缓冲区:
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
GraphicsConfiguration config = device.getDefaultConfiguration();
image = config.createCompatibleImage(width, height,Transparency.TRANSLUCENT);
现在是我将缓冲区复制回图像的部分。请注意,我需要切掉缓冲区的某些部分,这就是我选择最大参数调用的原因。
g.drawImage(image, vs.boardOffsetX, vs.boardOffsetY, targetWidth, targetHeight, 0, 0, sourceWidth, sourceHeight, null);
最后,对于我的另一个问题:我清除图像如下:
Graphics2D g = (Graphics2D) image.getGraphics();
Color transparent = new Color(0, 0, 0, 0);
g.setColor(transparent);
g.setComposite(AlphaComposite.Src);
g.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
非常感谢!被困了很长一段时间。不要害羞就我的方法给我风格建议:这是我第一次诚实地尝试图形。
谢谢!
edit:我真正不明白的部分是完全相同的操作需要非常不同的时间。除了我的线程之外,只有 AWT-Thread 运行,我得到两次〜300ms,然后下降到像 10µs !!!!这对于复制 1600 万像素来说非常快。 有人了解这种效果吗?并且可能知道“预优化”这种行为的方法?
【问题讨论】:
-
我看到的第一个危险信号是你有一个 4000x4000 像素的后台缓冲区。为什么需要这么大的?
-
另外,您是否需要使用
image的宽度和高度清除您的g实例?这将是一个 4000x4000 的矩形来填充,透明度不低于。似乎没有必要,只需清除当时屏幕上的任何矩形即可。此外,将 alpha 设置为 0,您将获得完全不透明的颜色。也许放弃透明度。 -
我需要缓冲区,因为在最大缩放中,需要显示的板就是那么大。我同意,它肯定会很慢,但是在每一帧或至少每次滚动时重新渲染完整的内容会更慢。所以是的,我需要它。只删除部分听起来不错,但很复杂……稍后会研究。不过谢谢!
标签: java performance awt