2013-04-24 14 views
8

私はLibGDXを使ってゲームを作っています。私は必要に応じて即座に資産をロード/アンロードしたいと思っています。ただし、主スレッドでアセットが読み込まれるのを待つと、ラグが発生します。この問題を解決するために、ロードする必要があるアセット(テクスチャ、サウンドなど)を監視し、それらを適切にロード/アンロードするバックグラウンドスレッドを作成しました()。現在のスレッドでOpenGLコンテキストが見つかりません

残念ながら、そのスレッドからAssetManager.update()を呼び出すと、次のエラーが発生します。

com.badlogic.gdx.utils.GdxRuntimeException: java.lang.RuntimeException: No OpenGL context found in the current thread. 

私は初めにメインスレッドでバックグラウンドスレッドをすると、最初の数画面だけを扱うrun試してみた、とすべてが正常に動作します。私はアルゴリズムを変更して、同じスレッドの最初からすべてをメモリにロードするだけで、それも同様に機能します。しかし、いずれもバックグラウンドスレッドでは機能しません。

私は(奇妙な方法で柔軟性のある)のOpenGL ES 2.0ではなく、Windows上でAndroid上でこれを実行すると、すべてが正常に動作し、私も画像のピクセル寸法を得ることができます - が、テクスチャは黒をレンダリング。

これは、OpenGLコンテキストが単一のスレッドにバインドされているが、あまり多くはないことが判明しました。これは、私がメインスレッドで押したときにすべてが機能する理由を説明し、別のスレッドに入れたときではありません。このコンテキストの問題を解決するにはどうすればよいですか?

答えて

9

まず最初に、レンダリングスレッドの外側にあるOpenGLコンテキストにアクセスしないでください。

これはすでに見てきましたが、資産の非同期管理にAssetManagerを使用する方法については、AssetManager wiki articleをお読みください。 wikiの記事に加えて、それをよりよく理解するためにAssetManagerTestをチェックしてください。おそらく、資産管理者のテストは、資産を動的に読み込む方法を読み込む際の最良の方法です。

たくさんのものを読み込んでいる場合、ローディングバーを作成して大きなものを読み込むことができます。アセットなどを別のスレッドからチェックしてフラグを設定して更新を呼び出すこともできますが、その日の終わりにレンダリングスレッドでupdate()に電話する必要があります。

別のスレッドからupdate()を呼び出さなければならないことに留意して、別のスレッドが条件をチェックしてフラグを設定する理由がわかりません。おそらく、別のスレッドを使用してupdate()呼び出しを同期すると、レンダリングスレッドですべての処理を行うよりもオーバーヘッドが増えます。また、update()メソッドはファイルをインクリメンタルにロードするため、一度に数ミリ秒間だけ一時停止します。通常は、アセットにload()と電話し、アセットのisLoaded()にチェックを入れます。ロードされていない場合は、isLoaded()がtrueを返すまでフレームごとにupdate()を1回呼び出します。真を返すと、get()に電話して、ロードしている資産を取得できます。これは、アプリケーションの読み込み中にメインのレンダリングスレッドを介して行うことができます。

あなたが本当にあなたの他のスレッドが(更新を呼び出したい場合は)、あなたはRunnableオブジェクトを作成し、そのような彼らはそれがlibGDXとマルチスレッドにwiki articleに記述持っているどのようpostRunnable()を呼び出す必要があります。しかし、これは、postRunnableで使用するものがレンダリングスレッド上で同期して動作するため、他のスレッドの使用の全ポイントを奪います。

+0

-1複数のスレッドからOpenGLコンテキストを誤って記述できませんでした。あるスレッドからOpenGLコンテキストを切り離して別のスレッドに接続することは、完全に可能です。 – datenwolf

+0

マルチスレッドの意味で別のスレッドにコンテキストを切り離して接続する方法は?コンテキスト自体は、ロックを試行してそれを達成したい場合を除き、一度に1つのスレッドだけがアクセスできます。しかし、それは全体のポイントを破る。 – Jyro117

+0

あなたは、OpenGLコンテキストがレンダリングスレッドからのみ使用できると主張しました。これは、コンテキストを作成したスレッドだけがそれを使用できることを意味しています。 BTW:共有オブジェクトネームスペースを使用して同じdrawable上にいくつかのOpenGLコンテキストを作成し、それぞれを独自のスレッドにアタッチすることができます。これにより、マルチスレッド化が可能になります。 – datenwolf

関連する問題