【问题标题】:A few Questions about implementing a render loop in Windows Forms关于在 Windows 窗体中实现渲染循环的几个问题
【发布时间】:2014-12-21 04:10:45
【问题描述】:

Guten Tag zusammen!(德语:大家好!

请原谅我的英语不是我的母语。由于我已经在这里找到了很多关于我的问题的好答案,所以我现在想问你一些。

在过去的几天里,我对“在 Windows 窗体中实现游戏循环的最佳方法是什么?”这个问题做了一些研究。。我从SlimDX team 中找到了一个很好的解释解决方案,它基于Tom Miller 的工作。

我的问题是:

首先:我们将此解决方案用于游戏循环,这是在渲染帧后重绘 From 的最佳方式?我经常发现的一种方法是调用 Invalidete(),但这对我来说似乎不是一个好主意。这不会在消息队列中添加一条消息并打破每一帧的while循环吗?

第二:据我了解,此循环将消耗整个 CPU 线程(核心)。有没有好的方法可以将其减慢到不消耗整个 CPU 线程的推荐帧速率?

第三: GDI+ 是否能够渲染简单的 2D 游戏?绘图何时变得如此复杂以至于建议使用带有一些 DirectX 或 OpenGL 包装器的硬件加速绘图?

【问题讨论】:

  • 这是三个不同的技术问题,但 SO 格式每个问题只允许一个问题。所以,你最好把你的第二点和第三点编辑出来,并将它们作为单独的问题发布。
  • 你打破了游戏代码中的所有规则。不要使用 Invalidate(),使用 CreateGraphics() 直接绘制到屏幕上。刻录核心是可以的,通常以垂直刷新为节奏,但在非 DirectX 代码中很难实现。 System.Drawing 适用于 2D 游戏,请务必缓存位图并注意像素格式(32bppPArgb 快 10 倍),GPU 渲染需要完全不同的代码。
  • 为什么不直接使用 XNA 而不必担心所有这些事情呢?微软已经停止支持它,但它仍然是一个可行的选择。当然,它会比 GDI 更有效率(尤其是对于游戏而言)。

标签: c# gdi+ game-engine message-queue


【解决方案1】:

我经常找到的一种方法是致电Invalidate(),但这对我来说似乎不是一个好主意。这不会在消息队列中添加一条消息并打破每一帧的while循环吗?

是的,这是个坏主意。您无法控制将消息传递到您的窗口的频率,这意味着您不应该依赖它。

据我了解,此循环将消耗整个 CPU 线程(核心)。有没有好的方法可以将其减慢到不消耗整个 CPU 线程的推荐帧速率?

您可以使用SpinWait structure (NOT Thread.SpinWait) 来等待很短的时间。等待时间基于当前帧的持续时间和所需的帧速率。

但通常情况下,占用整个核心的游戏循环不是问题。如果你想最大化你的帧率,它甚至可能是需要的。

GDI+ 是否能够渲染简单的 2D 游戏?

是的,虽然这将是一个非常简单的游戏。 GDI 。我建议您从一开始就使用硬件加速解决方案,这样如果 GDI 被证明是一个瓶颈,您就不必重写所有内容。

【讨论】:

  • 感谢您的快速回答。当我不应该使用 Invalidate() 重新绘制表单时。我该怎么做?
  • 链接的 SlimDX 文章解释得很好,我不会解释得更好。
  • “这不会在消息队列中添加一条消息并打破每帧的while循环吗?”这个问题的正确答案是no。窗口失效不像其他窗口消息那样处理;使窗口的一部分失效只是简单地标记窗口,然后当程序获取下一条消息时,Windows 会合成一条 WM_PAINT 消息。没有 WM_PAINT 消息实际上在消息队列中结束。也就是说,WM_PAINT 仅在没有其他消息需要处理时才返回,因此对于高帧率游戏来说并不理想。但它不会填满消息队列。
猜你喜欢
  • 1970-01-01
  • 2013-08-15
  • 1970-01-01
  • 2016-06-16
  • 1970-01-01
  • 2014-01-15
  • 1970-01-01
  • 2011-09-22
  • 2011-09-06
相关资源
最近更新 更多