7

私のアプリはGLKit、 で 3D シーンをレンダリングするために使用しますOpenGL ES

1つのことを除いて、すべて正常に動作します。iPad でアプリを起動し、バックグラウンド アプリ バーを表示し (「ホーム」ボタンを 2 回クリック)、デバイスの向きを変更すると、シーンが正しく更新されません (最後にレンダリングされた画像が新しい四角形を埋めるために単純に引き伸ばされます)。

理由がわかりました。バックグラウンド アプリ バーが表示されると、自動的GLKViewController's pausedに設定され(アプリケーション デリゲートが を受け取る)、このバーが閉じられるまでレンダリングは行われません。YES-applicationWillResignActive:

Apple ガイド ( OpenGL ES Programming Guide for iOS / Implementing a Multitasking-aware OpenGL ES Application ) で、アプリケーションを受け取った後、-applicationWillResignActive:GL レンダリングを停止するか終了する必要があることを発見しました。したがって、回転後のレンダリングが悪いことを除いて、すべて問題ないようです:)

いくつかの OpenGL ゲームをチェックしました。このバーが表示されたときにも「一時停止」になりましたが、デバイスの回転時に一時停止したシーンを何らかの形で正しく更新します。彼らはどのようにこれを達成しますか?

4

2 に答える 2

2

tl;dr: を に設定するだけでよい可能性がありGLKViewますcontentModeUIViewContentModeRedraw

まず、アプリケーションが実際にバックグラウンドに入るとは思いません。非アクティブになるだけだと思います。applicationWillResignActiveメソッドとapplicationDidEnterBackgroundデリゲート メソッドの違い。アプリケーションが非アクティブなだけであると仮定すると、実際にバックグラウンドに置かれる場合に備えて、以下を参照してください。

applicationWillResignActiveApple のドキュメントには、アプリケーションがバックグラウンドに入った後にのみ発生する OpenGL ES 呼び出しが許可されていないということではなく、呼び出されたときに「OpenGL ES フレームレートを下げる」必要があると記載されています。

これは、/がこの点で少し熱心すぎる可能性があることを意味しGLKitます。それを修正するには、次のことを確認する必要があります。GLKViewGLKViewController

  1. はに設定されていGLKViewますcontentModeUIViewContentModeRedraw
  2. のメソッド、アプリケーションが非アクティブでフレームが変更されている場合でもフレームを描画しGLKViewますが、アプリケーションがバックグラウンドにある場合はフレームを描画しません(つまり、OpenGL ES 呼び出しを使用します)。drawRect

ただし、drawRectアプリケーションがバックグラウンドにあるときはメソッドが呼び出されることさえないので、glkView:drawInRectデリゲート メソッドでの OpenGL ES 呼び出しについて実際に心配する必要はないと思います。ただし、この関数が状況で呼び出されない理由は、ビューが無効にならないためです。無効にされない理由は 2 つあります。

  1. GLKViewControllerビューを定期的に無効にするメイン フレーム ループは、pausedプロパティによって一時停止されます。
  2. おそらくデフォルトのGLKView contentMode「UIViewContetModeScaleToFill」です

GLKView drawRectメソッドはおそらくpausedプロパティを見ていないので、を変更するだけでcontentMode十分かもしれません。


アプリケーションが実際にバックグラウンドに移行する場合は、次の解決策を提案します。バックグラウンドでの実行中に OpenGL ES 呼び出しを使用することは許可されていないため、ソリューションは非常に簡単です。

バックグラウンドに入る前に、必要なものをサポートするために必要なすべての OpenGL ES 呼び出しを実行します。

つまりapplicationWillResignActive、次の手順を実行します。

  1. ゲーム ループを一時停止します ( を設定して実行しますGLKViewController) paused
  2. レンダリング ループを一時停止します (GLKViewControllerのを設定して行いますpaused) 。
  3. 現在の向きの状態の現在のフレーム バッファを取得します
  4. 回転した向きの状態に対応するフレームバッファとビューポートを使用して、現在のゲーム状態をもう一度レンダリングし、そのフレームバッファを取得します

さらに、方向の変更によってビューのフレームが変更された後にメソッドが実際に呼び出されるように、を に設定する必要がありますGLKViewcontentModeUIViewContentModeRedrawdrawRect

最後にGLKViewdrawRectメソッドで、 で保存されているフレームバッファの 1 つを取得し、通常の呼び出しでビューに描画するかどうかpausedを確認する必要があります。YESNONOYESapplicationWillResignActiveUIKit

このハックなソリューションが とどの程度うまく統合されるかはわかりませGLKitん。サブクラス化が必要になる場合があります。

于 2013-03-13T10:39:56.743 に答える
0

デリゲート メソッドを実装します (まだ行っていない場合)。

-(void)applicationWillEnterForegroundそこから一時停止を解除しGLKViewControllerます。

あなたの質問から私が理解したことから、ゲームを一時停止したままにすることができますが、このメソッドでも glView のサイズを変更できますが、コードが表示されないと、何が起こっているのかを実際に確認することも困難です。

于 2013-03-13T09:04:54.653 に答える