2013-05-15 9 views
14

私はXNAイメージビューアを作ったが、それが変わらない場合でも常にシーンを再描画し、ネットブックが地獄のように燃え尽きるので、何も変わっていないときに描画を一時停止したい。XNAで再描画を一時停止するにはどうすればよいですか?

フレームレートを1に減らすことは、冷却を保つための1つの方法ですが、出力が遅くなります。

入力がないときに再描画を防止するにはどうすればよいですか?


この問題は解決したが、別の問題が発見された - そのウィンドウがフォーカスされているが、それがないとき、それが唯一のCPUの約1%を取るときゲームはCPUを大量に消費します。この他の問題を解決する方法の詳細については、この質問を参照してください:あなたは、この目的のためにGame.SupressDraw方法を使用することができます

How to reduce XNA game CPU usage while nothing worth computing is happening?

+0

これは、迅速なdownvoteとクローズ投票でした。質問を改善するためのケア? – user1306322

+3

人々が彼らのdownvotesを説明するためにコメントを残すなら、それはいいだろう。これは完全に合法的な質問のようです。 –

答えて

10

更新中にこのメソッドを呼び出して、次回のUpdate呼び出しの呼び出しまで描画を禁止します。アップデートの結果ディスプレイが変わらない場合、この方法を小型デバイスで使用してバッテリ寿命を節約することができます。たとえば、画面が背景アニメーションなしで静的である場合、プレーヤーの入力を確認して、プレーヤーがアクションを実行しているかどうかを判断できます。入力が検出されない場合、このメソッドは次の更新までゲームをスキップできます。

例として、次のコードはDraw関数を1回だけ呼び出します。これをテストしたところ、SuppressDrawコールがないと、CPU使用率が高い(70%)ことに気付きました。 SupressDrawを使用すると、CPU使用率が大幅に低下しました(15%未満)。あなたの番号は異なる場合があります。 SupressDrawは一つだけDrawコールを抑制することを

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; 
    } 
    ... 
} 

は注意してください。 Drawへの呼び出しを防止するには、SupressDrawUpdateに継続して呼び出す必要があります。うまくいけばそれは理にかなっている。

+0

これは間違いなく動作しますが、私が望むほどのCPUを節約できません。パフォーマンス分析では、各描画フレームが抑制された状態で、メインの更新方法がすべて注目を集めていますが、以前と同じくらい多くのCPUが必要です。質問された質問には答えがあると思いますが、ほとんど何もしないCPUコストを削減する方法を知る必要があります。 – user1306322

+0

@ user1306322 - あなたのコードを見ることなく、CPU使用率が低下しなかった理由を回答するのは難しいです。上記の私の答えでわかるように、サンプルプログラムのCPU使用時間を70%から15%に減らすことができました。 –

+0

あなたが言ったように、パーセンテージは異なります。 Draw呼び出しは実際には相当量のリソースを消費していなかったと思いますが、アプリケーション全体が使用できる限り多くのリソースを使用していました。だから基本的にこれは別の問題になった。入力を待ってフレームを1秒間に60回描画するのではなく、何も特別なことが起こっていない間にCPUを正確に消費するものを決める。 – user1306322

0

承認された回答によれば、SuppressDrawを使用して、変更されていないフレームを描画しないようにすることができます。しかし、あなたのUpdateメソッドは、あなたが期待している以上のCPUを使い続けているのにかかわらず、実行されます。多くのCPUを使用しないようにするには、最後のフレーム以降変更されていないことを何らかの形で更新しないでください。

私は何をする必要が、このようなあなたのアップデート方式再編成され、引き分けを抑制するとき、あなたが知っているのと同じ方法でこのことを知っているだろうと仮定します。最後の注意点として

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 

} 

を。私は今までに作ったゲームでこれを使う必要はなかった。私が感じることは、あなたがパフォーマンスに関して根本的な問題を抱えているかもしれないことを示唆しています。しかし、私はテキストをレンダリングするのを避けるために、フレームごとに(ボクシング/アンボクシングを引き起こす)多くのテクニックを使用しました。あなたがもっと知りたいのであれば、この点についてコメントしてください。

+0

これは一般的な方法ですが、この特定のケースでは、私が質問したように、更新方法は非常に簡単で、入力状態の変化があったかどうかをチェックするためにすべてのCPUを馬鹿にすることはできませんそれは、私はそれを四倍にチェックしなかった)。解決策は、この質問の中で再描画しないことを解決した後に現れる問題とは異なる質問によって見つけられました。詳細は質問脚注を参照してください。 – user1306322

関連する問題