【发布时间】:2013-01-12 07:44:48
【问题描述】:
我今天和一群同学讨论了很多这个话题,他们每个人都有不同的想法来“滥用”Java2D API 来制作一个简单的 2D 游戏。
我正在使用扩展JComponent 的类并覆盖paintComponent() 方法来获取Graphics2D 对象并从那里定义我的渲染逻辑。修改后的JComponent 是我覆盖的JFrame 的contentPane。
我的问题来了:在JFrame 的后端调用paint(Graphics)、repaint() 和update(Graphics) 对我的屏幕有何不同?我提到,当从我的“帧计时器”调用除repaint() 之外的任何东西时(每秒调用有问题的方法 50 次)屏幕的某些部分有时会闪烁,我清楚地告诉它渲染的某些东西不可见(或闪烁迅速),一切都感觉不对。这里有什么区别?我试图深入了解 AWT 后端的源代码,直到 EventQueue 以某种方式管理 PaintEvent,但我停在那里以从极其丑陋的代码中拯救我的大脑。
在讨论整个repaint() 的事情时,我们谈到了仅重新绘制与模型中的明确变化相对应的屏幕位置的“策略”,从而节省了我们的 CPU/GPU 功率。虽然完成这些事情(以及动画)仍然需要逻辑,但下一个问题是我如何“访问”已绘制屏幕的FrameBuffer,以便我可以参考我的渲染已经完成的工作。
是的,我们已经经常听到 Java 可能不是以最佳方式支持我们正在寻找的所有操作的编程语言...
【问题讨论】:
-
操作系统或底层库处理为您节省一些 CPU 和 GPU。有一个优化可以在屏幕上重新绘制最小的正方形,并且只重新绘制该部分。所以我不会为这样的优化而烦恼(在某些情况下在 3D 渲染中除外)。
-
你知道这实际上是在哪个版本的 java 中实现的 - 我感觉在 1.6 中它没有这样做(升级到 1.7 不知何故将性能提高了 10 到 20 倍)
-
这通常由操作系统缓冲区处理来处理。 Java 1.7 总体上增加了代码改进,因此它可能不是绘图本身,而是总体上的性能改进。
-
忘了提到该技术称为位块传输。这意味着它将操作系统中的位图缓冲区合并在一起,并且可以快速确定包含所有更改的最小矩形,以仅重绘该部分。由于硬件限制,我认为您无法获得比这更精细的颗粒。
-
基本上我们可以忽略这里的任何优化,让操作系统做“正确”的事情? - 我不知道即使它看起来合乎逻辑,Graphics2D 对象的工作方式和从程序员那里获取指令的方式似乎我们告诉它做的所有工作都已经完成了,即使屏幕上“没有”发生,我们仍然执行代码...
标签: java swing awt backend graphics2d