2

ゲームで 1 秒あたりのフレーム数を追跡しようとしています。fpsを平均として表示したくありません。キーを押したり、モデルを追加したりしたときにフレームレートがどのように影響されるかを確認したいので、変数を使用して現在の時刻と前回の時刻を保存し、それらが 1 秒異なるときに fps を更新します。

私の問題は、約 33 fps を表示していることですが、マウスを非常に速く動かすと、fps が 49 fps に跳ね上がります。また、フレーム カウンターに関係のない単純なコード行を変更したり、プロジェクトを閉じて後で開いたりすると、fps は約 60 になります。垂直同期がオンになっているため、マウスがまだ有効かどうかわかりません。 fps。

フレームごとに発生する更新関数にある私のコードは次のとおりです。

FrameCount++;
currentTime = timeGetTime ();
static unsigned long prevTime = currentTime;
TimeDelta = (currentTime - prevTime) / 1000;
if (TimeDelta > 1.0f)
{
 fps = FrameCount / TimeDelta;
 prevTime = currentTime;
 FrameCount = 0;
    TimeDelta = 0;
}

変数宣言は次のとおりです。

int FrameCount;
double fps, currentTime, prevTime, TimeDelta, TimeElapsed;

ここで何が問題なのか、それを修正する方法、または fps をカウントするより良い方法があれば教えてください。ありがとう!!!!!!

私はDirectX 9を使用していますが、それが関連しているとは思えず、PeekMessageを使用しています。代わりに if else ステートメントを使用する必要がありますか? これが私のメッセージ処理ループです:

MSG msg;
ZeroMemory (&msg, sizeof (MSG));

while (msg.message != WM_QUIT)
{
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }

    Update ();
    RenderFrame ();
}
4

5 に答える 5

1

これは、メッセージ処理ループがピークまたはポーリングではなくブロックしていることを示しています。これは、マウス メッセージを受信するにつれて fps が増加するためです。PeekMessageの代わりに使用することを検討する必要がありGetMessageます。

編集: また、CPU を占有したい場合はPM_NOYIELD、システムが実行中に他のスレッドの実行を許可しないように追加することもできますPeekMessageのドキュメントからPeekMessage

オプションで、値 PM_NOYIELD を PM_NOREMOVE または PM_REMOVE と組み合わせることができます。このフラグは、呼び出し元がアイドル状態になるのを待っているスレッドをシステムが解放するのを防ぎます (WaitForInputIdle を参照)。

于 2010-02-14T17:12:16.627 に答える
0

メッセージループについて-メッセージが表示されなくなるまでメッセージを確認してから、フレームをレンダリングすることをお勧めします。

擬似:

bool renderFrame = true; if(PeekMessage(...)){//処理します。renderFrame = false; }

if(renderFrame)フレームをレンダリングする

それ以外の場合は、メッセージループ関数を終了します(そして、もう一度入力するか、しばらくして解決します。これは、メインループの残りの部分をどのように構成したかに少し依存します。

于 2010-05-23T00:52:58.090 に答える
0

メッセージ処理ループに関しては、はい、if-else ステートメントを使用する必要があります。

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
    TranslateMessage (&msg);
    DispatchMessage (&msg);
} 
else
{
    Update ();
    RenderFrame ();
}

そうしないと、フレームごとに 1 つのメッセージしか処理されず、フレームのレンダリングに時間がかかる場合に重大な入力遅延が発生します。

FPS の測定値に関しては、それほど多くはありません。さまざまなことが影響を与える可能性があります。fps カウンター コードは、目的を果たしているように見えます (ただし、精度がいくらか失われます)。

マウスはカメラを制御していますか? もしそうなら、あなたが向いている方向ではなく、fpsの増加を引き起こすのはマウス入力であると確信していますか?

fps コードがフレームごとに 1 回だけ実行されることを絶対に確信していますか?

どこかで入力を処理しますか? もしそうなら、そのコードを無効にしてマウスを速く動かすとどうなりますか? まだ同じ?

于 2010-02-16T01:44:15.730 に答える
0

あなたの問題への答えというよりも補足ですが、フレームレートを平均したくないと言っていますが、そのように計算することで、1秒間で効果的に平均しています。フレームレートをフレームごとに更新したい場合は、次のようなことを試してみてください。

currentTime = timeGetTime();
fps = 1000.0f / (currentTime - prevTime);
prevTime = currentTime;

timeGetTime は、数値が小さい可能性が高いため、この時点で少し不正確になり始めます。QueryPerformanceCounter は、使用するより良いタイマーかもしれません。

于 2010-02-14T17:23:22.877 に答える