如何在XNA中暂停重绘?

15

我制作了一个XNA图像查看器,但它总是重新绘制场景,即使没有变化,这让我的上网本发烫得厉害,所以我希望在没有变化时暂停绘制。

降低帧率到1是保持其冷却的一种方法,但会导致输出很卡顿。

如何在没有输入时防止重绘?


这个问题已经解决,但另一个问题被发现——当游戏窗口处于焦点状态时,游戏会消耗大量CPU,但当它没有焦点时,只需要约1%的CPU。有关如何解决这个问题的详细信息,请参见此问题:

如何在 XNA 游戏没有需要计算的内容时减少 CPU 使用率?


那是一个快速的负投票和关闭投票。愿意帮助改进这个问题吗? - user1306322
3
希望人们能够留下评论解释他们的反对意见。这似乎是一个完全合理的问题,有一个明确的答案。 - Cole Campbell
2个回答

11
你可以使用Game.SupressDraw方法来实现此目的。链接中的备注说明如下:

在更新期间调用此方法,以防止任何调用绘制方法,直到下一次更新后。如果显示器由于更新而不发生更改,则可以在小型设备上使用此方法以节省电池寿命。例如,如果屏幕是静态的,没有背景动画,可以在更新期间检查玩家输入以确定玩家是否执行任何操作。如果未检测到输入,则该方法允许游戏跳过绘制,直到下一次更新。

例如,以下代码仅调用Draw函数一次。在我测试时,我注意到没有SuppressDraw调用时CPU使用率很高(70%)。当使用SuppressDraw时,CPU使用率显著降低(不到15%)。你的数字可能会有所不同。
public class Game1 : Microsoft.Xna.Framework.Game
{
    ...
    private bool _drawn = false;
    protected override void Update(GameTime gameTime)
    {
        if (_drawn)
            SuppressDraw();
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        /* draw stuff here */
        spriteBatch.End();

        _drawn = true;
    }
    ...
}
请注意,SupressDraw 仅抑制一个 Draw 调用。要防止更多对 Draw 的调用,您必须在 Update 中不断调用 SupressDraw。希望这样说得清楚了。

这肯定是有效的,尽管它没有像我希望的那样节省CPU。性能分析显示,每个抑制绘制帧时,主更新方法会得到所有关注,但仍然会消耗与以前相同的CPU。我想问题已经得到了回答,但我仍然需要知道如何减少几乎不做任何事情的CPU成本。 - user1306322
@user1306322 - 没有看到你的代码,很难回答为什么你的CPU使用率没有降低。正如你可以从我上面的回答中看到的那样,它确实减少了我的示例程序的CPU时间 - 从70%的使用率降至约15%。 - chue x
就像你所说的——百分比是不固定的。我猜测绘制调用实际上并没有消耗任何重要的资源,而整个应用程序正在使用尽可能多的资源(现在仍然如此)。因此,基本上这成为了另一个问题——确定在除了等待输入和每秒绘制60帧之外,究竟是什么在消耗CPU。 - user1306322

0

正如被接受的答案所说,您可以使用SuppressDraw来避免绘制未更改的帧。然而,您的Update方法将仍然运行,这就是为什么它使用的CPU比您预期的要多的原因。为了避免使用太多的CPU,您需要以某种方式避免更新您知道自上一帧以来没有更改的内容。

我假设您会像知道何时抑制绘制一样知道这一点,因此您需要按照以下方式重新排列您的Update方法:

private void Update(GameTime gameTime)
{
    var frameHasChanges = DetectChanges(); //This method you need to figure out yourself
    if (!frameHasChanges)
    {
        SuppressDraw();
        base.Update(gameTime);
        return;
    }

    //Do the rest of normal Update

}

作为最后的说明;我从来没有在我制作的任何游戏中使用过这个。这让我感觉你可能有一些其他的性能问题。然而,我已经使用了许多技术来避免每帧渲染文本等(导致装箱/拆箱)。如果您想了解更多,请在评论中提问。

虽然通常这是正确的方法,但在这种特定情况下,正如我在问题中所说,更新方法非常简单,它不能独占所有CPU来检查输入状态是否有变化(它确实没有,我已经四倍检查过了)。解决方案是通过解决此问题中不重新绘制的问题后出现的不同问题的另一个问题找到的。有关详细信息,请参见问题脚注。 - user1306322

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接