この記事では、パフォーマンスの問題に直面してゲームの分析をする必要がある場合に便利な、お役立ちツールとユーティリティについて説明します。
FPSLoggerは毎秒ごとに実行されるフレーム数をログ出力する、シンプルなお役立ちクラスです。 描写メソッド内で log() メソッドを実行するだけです。1秒ごとに1回ログが出力されます。
PerformanceCounterは、特定のタスク処理でかかる時間と負荷(時間全体におけるの割合)を追跡し続けます。
追跡対象のタスクを開始する直前にstart()を実行し、タスクの直後にstop()を実行します。
これは必要であれば複数回実行できます。
全ての描写イベントや更新 イベントでは、tick()を実行してこの値を更新しています。
time FloatCounter を使用すると、対象のタスク処理にかかった最小時間、最大時間、平均時間、合計時間、現在の時間を取得できます。
load値(時間全体におけるの割合)も取得できます。
ゲームが動作している間に発生する実際のOpenGL呼び出しを分析するのは簡単なことではありません。
libGDX がそういったOpenGLのローレベル部分を抽象化しているためです。
これらの情報を収集するために、GLProfilerがあります。
これを有効にするには、静的メソッドGLProfiler.enable()を実行する必要があります。 GLProfiler内部では、GL20インスタンスと GL30インスタンス(Gdx.gl など) が使用されています。
GLProfilerは、有効になるとあなたに代わって実際のGLコールとGLエラー(下記参照)の監視を開始します。
負荷が高くてゲームをスローダウンさせる可能性のある、テクスチャバインドの発生回数などは、あなた知りたい情報ではないでしょうか。
テクスチャバインドの処理を最適化するには、TextureAtlasを使用すると良いでしょう。
テクスチャバインド処理が減ったことを数値上から明確にするには、このプロファイラーの静的フィールドGLProfiler.textureBindingsを参照します。
画面上に表示されるものだけを描写する視錐台カリングのような機能を実装することもできます。
静的フィールド GLProfiler.drawCallsでこれら最適化の結果を表示できます。
現在、このプロファイラーでは以下の情報が取得できます:
GLProfiler.vertexCount は実際は FloatCounterです。
GLProfiler.vertexCount.total以外にも、個別のdrawcallに基づいた GLProfiler.vertexCount.min, GLProfiler.vertexCount.max or GLProfiler.vertexCount.averageのような情報も持っています。
読み込んで表示した後にこれらの情報を全てリセットするには (おそらくフレームごとに1回)、GLProfiler.reset() メソッドを実行する必要があります。
このプロファイラーを完全に無効化して元のGL20インスタンスと GL30インスタンスを使用するには、GLProfiler.disable()を使用します。
Gdx.graphics.getGL20() や Gdx.graphics.getGL30() を使用すると、情報がプロファイラーを経由しなくなってしまうので注意してください。そのため、Gdx.gl20 や Gdx.gl30 を直接使用したほうが良いでしょう。
これの使い方についてはBenchmark3DTestを参照してください。
GLProfiler にはもう一つエラーチェックという便利な機能があります。
ほとんど全ての GL コールは、ある状況でエラーを発生させます。
これらエラーはJavaエラーのように例外を投げたりログに出力されてたりせずGdx.gl.getError()を使って明示的に確認する必要があるので、見つけるのが困難です。
GLProfiler を有効にすると(有効にする方法は上記を参照)自動的に全てのGLコール後に GL エラーを確認して報告してくれるので、あなたがエラー確認を行う必要はありません。
既定では、発生したエラーは( Gdx.app.errorを使って)コンソールに出力されます。
ですが、GLProfiler.listener内で別のエラーリスナーを設定することで、これをカスタマイズすることができます(例えば、あなた独自のログ/クラッシュレポートシステム)。
コード上でエラーが発生した場所を正確に知りたい場合は、GL エラーで例外を投げる GLErrorListener.THROWING_LISTENERを使用します。
エラーリスナーのコールバックは GLコール内で呼び出されているので、スタックトレースでエラーが発生した正確な場所を明らかにできます。
(エラーが発生した場合にGL エラーで例外を投げるとアプリケーションがクラッシュしてしまうことが多いので、既定では使用されていません。)
使用方法やテスト方法の例については、GLProfilerErrorTestにあります。