2016-10-13 6 views
0

私はiOS用のopengl esアプリを作成しています。私はEAGLContext用のスレッドを作成し、このスレッド上のすべてのOpenGLを実行し、完了したらperformSelectorOnMainThreadpresentRenderbufferを使用してレンダリングバッファを画面に表示します。ios opengles present UIView描画がアプリクラッシュの原因となったときに表示するレンダーバッファ

私のopenglビューの上に他のUIViewがない場合は、すべてが問題ありませんが、私のopenglビューの上にビューを追加すると、物事が不安定になり始めます。時々UIViewがアニメーション化されていると、openglコールクラッシュが発生し、時にはglClear、時にはpresentRenderbufferにクラッシュすることがあります。アイフォーン6プラスでは特に問題があります。スクリーン解像度が高いためです。

私は間違ったことをやっているのですか?UIViewでアニメーションがクラッシュするのを防ぐために、OpenGLレンダリングを停止することができますか?

答えて

0

必要最低限​​の提示する前に、メインスレッド上で、現在のようコンテキストを設定することがあるので

コンテキストをスレッドにバインドされている...あなたは間違ってここにいくつかのことをやっているが、私はそれが動作する必要がありますねレンダリングバッファ

あなたがここで直面している主な問題は、別のスレッドにバッファを提示している場合、バックグラウンドスレッドがすでに描画を継続している可能性があります。たとえば、最初の呼び出しでバッファをクリアするバッファはすでにメインスレッド上でクリアされている可能性があります。

したがって、何らかの種類のロック機構やダブルバッファリングが必要です。あなたは、OpenGLのためのあなたのメインスレッドであり、むしろそのスレッド上のコンテキストを作成し、それを最新のものに設定することを考慮する必要があります。次に、セカンダリスレッドで使用される共有コンテキストを持つ別のスレッドを作成します(実際には違いはありません。他の共有コンテキストを作成できる「マスタ」として定義するだけです)。描画スレッドでバッファを描画するときに、メインスレッドがバッファを提示できることを通知する必要があります(performSelectorOnMainThreadを呼び出す必要があります)、メインスレッドはそのバッファを取り出して提示します。それが完了した後、新しいバッファを収集する準備ができていることを描画スレッドに通知する必要があります。

  • 描画スレッドがバッファ報告が終わった描画描画1
  • をバッファリングするために描画し、描画バッファを交換し、バッファに描画し続けて:あなたはダブルバッファリングを作成した場合

    それではパイプラインはそのようなものになるだろう2

  • スレッドを提示するとバッファ1が取り込まれ、提示され始めます
  • バッファ2は既に終了しているかもしれませんが、バッファ1はまだロックされているので、バッファ2の内容を破棄するか次のサイクルでバッファー1のロックが解除されることを希望して再びそれを描く。しかし、いずれの場合でも、バッファをスワップすることはできません。
  • バッファ1が提示スレッドでバッファ1に通知(アンロック)され、描画スレッドにロック解除を報告した後。(バッファを再描画することを選択した場合は、レポートは必要ありません)
  • バッファ1のロックが解除され、バッファ2の内容がすでに描画されていることが通知されたら、バッファをスワップして、
  • (OR)バッファ2に再び描画を完了したら、バッファ1がロック解除されているかどうかを確認し、バッファをスワップして再び提示スレッドに通知します2
  • バッファ1に描画するサイクルを繰り返します。 ..
+0

ワウ!アドバイスマンに感謝!私はこのダブルバッファメソッドを実装しようとし、それがどのように動作するかを教えてくれるでしょう –

+0

メインのレンダーバッファ上で '[EAGLContext renderbufferStorage]'を呼び出す必要があります。私はダブルバッファを実装するときに、私は描画のための2バッファを作成する場合、私はそれらの両方で 'renderbufferStorage'を呼び出す必要があります。今私がやっていることは、レンダリングスレッドで2つの完全なfboを作成することです。描画する前に、フロントfboをバインドし、レンダーバッファに 'renderbufferStorage'を呼び出してから描画します。描画を終えた後、私はfboを切り替え、古いfronバッファをメインスレッドにプッシュし、プレゼンテーションを行います。だから、フレームごとに 'renderbufferStorage'を呼び出す必要があります。これはあなたのところにぴったりですか? –

+0

いいえ、私はあなたができるだけ積み込み時間に2回呼び出すべきだと思います。私はそれがうまくいくかどうかはわかりません。 renderbufferStorageは実際にレンダリングバッファを生成するので、前のものを削除する必要があります。最初のメインスレッドで両方を初期化してみてください。 –

関連する問題