JavaFX - 游戏循环画布高 CPU 使用率
Posted
技术标签:
【中文标题】JavaFX - 游戏循环画布高 CPU 使用率【英文标题】:JavaFX - Game loop canvas high CPU usage 【发布时间】:2020-02-09 22:30:16 【问题描述】:我正在开发一个简单的 JavaFX 2D 游戏,但遇到了性能问题。
我正在将我的游戏渲染到每帧更新的画布中。 但是以 60 FPS 更新画布会大大增加我的 CPU 使用率,当然还有我的 GPU 使用率。
它不是来自大计算,因为我尝试在画布中进行非常基本的操作,如下所示,问题仍然存在。
根据我所做的研究,我使用TimeLine
来实现我的游戏循环。这似乎是以我想要的帧速率更新画布的最佳方式:
private void initGameLoop()
final Duration oneFrameAmt = Duration.millis(1000/60);
final KeyFrame oneFrame = new KeyFrame(oneFrameAmt, actionEvent ->
gameView.getRenderer().render();
);
gameLoop = new Timeline();
gameLoop.setCycleCount(Animation.INDEFINITE);
gameLoop.getKeyFrames().add(oneFrame);
在此配置中,我以 60 FPS 运行我的游戏循环,并且更改在 FX 应用程序线程上运行。
我的渲染函数很简单:
public void render()
gc.clearRect(0, 0, 50, 50);
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, 50, 50);
gc
是我画布的 graphicsContext2D。
我的画布在我的应用程序的窗口大小上进行缩放,但我只是在每帧重绘一个 50x50 黑色矩形,在 60 FPS 时,我的 CPU 使用率在默认窗口大小上增加了 8-10%,但在全屏时,我的 CPU 使用率增加了 25% 到 30%,这太疯狂了。
正在运行硬件加速,除了我的 CPU 使用率,我的 GPU 使用率在 30% 左右。
当游戏中没有任何事情发生时,我不能停止渲染画布,因为我需要渲染我的动画。
基本上只重绘画布的局部区域并没有改变任何东西,因为我的基本测试(如上所示)只在画布的左上角重绘了一个 50x50 像素的矩形,它仍然使用 25%+ CPU。
我在网上找到的所有使用 JavaFX 制作的游戏循环或动画示例都使用相同的技术,但到目前为止我尝试过的每一个都具有很高的 CPU 使用率。
我的渲染非常流畅和流畅,但 CPU 使用率对于它所做的来说太高了。我似乎无法找到为什么做这么少会占用我的 CPU 和 GPU 这么多资源,也找不到如何提高我的游戏性能的解决方案。根据我的研究发现,画布似乎是在 JavaFX 中渲染游戏的最佳方式。
我的问题是:有没有办法使用画布来提高性能?我应该使用具有多个元素的场景图吗?或者有什么我还没有想到的解决方案?
感谢您的帮助!
【问题讨论】:
【参考方案1】:从概念上讲,JavaFX 渲染始终具有 CPU 和 GPU 部分。在 CPU 部分准备渲染几何图形,GPU 部分最终进行渲染。画布渲染是最慢的选项,因为当您想要更改某些内容时,API 会强制您始终在每一帧中创建新对象,这意味着您总是会遭受渲染的缓慢 CPU 部分的困扰。另一方面,如果您应用于场景的更改只是平移变换(可以通过适当的渲染提示扩展到旋转和缩放),场景图渲染可能会更快,因为这样您只会遭受一次缓慢的 CPU 部分,但不会在每一帧。如果您也必须经常更改几何图形,那么您会迷失这两种方法,唯一的选择是通过三角形网格进行 3D 渲染(这就是我所做的)。好消息是,在 JavaFX 中,3D 渲染可以很容易地与 2D 渲染相结合,以获得两全其美的效果。
【讨论】:
“画布渲染是最慢的选项,因为当你想改变某些东西时,API 会强制你总是在每一帧中创建新对象……”我不确定这是真的。动画帧不需要新对象。移动和转换不需要新的对象。并且可以预先创建许多对象,例如形状和图像。 您说的是场景图渲染而不是 Canvas 渲染。你不能在 Canvas 上制作动画。 你说得对,我把其中一些弄糊涂了。但仔细查看 GraphicsContext API,我发现大多数方法都需要字符串和枚举值。除此之外,还有图像、绘画、字体和变换,它们可能可以被程序缓存。以上是关于JavaFX - 游戏循环画布高 CPU 使用率的主要内容,如果未能解决你的问题,请参考以下文章