0

Android/OUYA および PC 用の Java でマルチプラットフォーム (ただし OpenGL を優先) ゲーム エンジンを作成中ですが、ゲームパッドの状態をすばやく確認するときに、PC プラットフォーム アダプターで問題が発生します。

私は現在 LWJGL/JInput を使用して PC アダプターを書き込んでおり、ゲームパッドの状態を 1 秒あたり約 30 回よりも速くポーリングすると (ポーリングを実行して状態を更新するのに約 33ms かかります)、ゲームパッドから取得した値は false です。スティックが右半分にある可能性があるという意味では False ですが、getAxisValue は 1f のうち 0.5f に近い値ではなく 0 を返します。その上、より頻繁に実行するように求められた場合、そうでなければ問題ない 33ms よりも長くかかるようです。何を与える?

簡単に言えば、典型的な update 呼び出しで何が起こるかというと、エンジンはアクティブなプレイヤーのコントローラーをスキャンして、ゲームで実際に使用される特定のボタンの状態をスキャンし、すべて事前に設定および登録します。現時点では、私のテスト アプリでは、2 つのボタンと軸で構成されています。つまり、3 つの入力の現在の状態をチェックするだけで、それ以上はありません。インターフェイスのいくつかのレイヤーを通過してスイッチブロックに渡された後、最終的にこれが呼び出されます。

return controller.isButtonPressed(map.A);

また

return controller.getAxisValue(map.LS_H);

map には、指定されたコントローラーの特定のインデックス値に名前をリンクする最終的な int が含まれます。

私自身のテストでわかったこと:

  • これはハードウェアの問題ではありません。1 秒あたりの更新が 30 ~ 35 未満の場合でもかなり正確なままです。
  • グラフィックス スレッドの 60 fps レートに合わせて 1 秒あたり約 60 更新まで速度を上げると、入力スレッドのみで大きな遅延が発生します。グラフィックス スレッドは影響を受けていないため、一般的なパフォーマンスの問題でもないと思います。
  • isButtonPressed または getAxisValue を任意のプリセット値に変更すると、更新の遅れの問題が解決されるため、断続的な停止の原因となっているのは私のコードではなく、間違いなく isButtonPressed と getAxisValue です。

ゲームパッド チェックの速度を改善する方法、または LWJGL/JInput を介した不要な入力ルーチンを無効にする、私が見逃した設定のどこかを改善する方法はありますか?

60 fps の一致は、パフォーマンスの点で要求するには多すぎますか?

4

2 に答える 2

0

私が経験していた視覚的な遅延の一部は、ループの delta-t 計算の問題によるものでした。これは、前のフレームの終了から新しいフレームの開始までの時間に基づいており、前のフレームで計算を実行するのにかかった時間を除外しています。これにより、フレームの視覚的なスタッターに時間がかかり、小さなパフォーマンスの問題が大きく見えるようになりました。これを修正すると、視覚的なカクつきは改善されましたが、ゲームパッドの遅延 (軸を動かしてから結果が表示されるまでの時間) や入力読み取りの精度 (軸は物理的に X にあるが、0 または X 以外の値として読み取られる) は改善されませんでした。


それを修正したもの:

時間の浪費の原因となっているいくつかの問題を絞り込みました。

  • Display.update()は自動的に入力をポーリングしますが、これは既にロジック スレッドで行われています。レンダリング スレッドから呼び出すと、スレッド間のロックの問題が発生し、レンダリング スレッドが入力オブジェクトを解放するまでロジック スレッドが待機する可能性があります。もう 1 つの考慮事項は、ポーリングが大幅に頻繁に行われるようになったことです。Display.update(false)を使用し、ロジック スレッドが独自にポーリングできるようにすることで、問題が大幅に減少しました。

  • Display.setVSyncEnabled(true)は、レンダリング スレッドが 60hz モニターで指定されたレンダリング時間 (60fps レートで 13ms) をすべて使用することを強制し、以前のロックの問題を悪化させた可能性があります。これを有効にすると、 Display.update()から入力ポーリングを削除する前に、常にロジック スレッドのスタッターが悪化しました。

  • オプションでDisplay.update(false)の代わりにDisplay.swapBuffers()を使用すると、パフォーマンスが最小限に改善されるようです。私のコードでは、後者は断続的なフレーム ラグを引き起こす傾向があります。

これらの変更を実装した後、ゲームパッドの読み取りに問題はなく、エンジンは軸の変更に非常に敏感です。私のハードウェアでビジュアル スタッターなしでテストした最高値は、ロジック/入力スレッドで 60 fps のレンダリングと 100 サイクル/秒です。


メンタリティ レベルの問題の一部は、レンダリング プロセスとは無関係に入力ハードウェアをポーリングしようとしていることにあると思います。LWJGL は、Display.update() が入力ポーリングとスクリーン バッファの両方に関連付けられているため、これを奨励していないようです。 . APIの実装上、表示を確立しないと使用できない入力デバイスがあります。

于 2014-08-05T23:59:16.287 に答える