18

OpenGL レンダリング コードを変換して、 のいくつかの機能GLKit(つまり、非同期テクスチャの読み込みと によって提供される自動化GLKView/Controller) を利用することを検討しています。ただし、クラスは主にアニメーション ループを使用してレンダリングする人々に対応するように設計されているようですが、私はオンデマンド レンダリングを使用しています。さらに、一部のレンダリングは GLKView のフレームバッファではなくテクスチャに対して行われるため、GLKView をサブクラス化して FBO を追加するだけでよいのでしょうか?

このタイプのセットアップに推奨されるアプローチはありますか? 私は次のようなものを期待しています:

  • ビュー コントローラpreferredFramesPerSecondを に設定0するか、フレームの更新を一時停止しますか?
  • glkViewControllerUpdateまたはメソッドを無視して、glkView:drawInRect:必要なときに必要なものだけを描画します。
  • フレームを表示するには、ビューsetNeedsDisplayを法線と同様に使用します (テクスチャにもレンダリングするUIViewので、呼び出す必要がありますか?)。bindDrawable

これが新しい API の設計目的ではない場合、努力する価値がないのではないでしょうか? ドキュメントがもう少し完全であることを望みます。おそらく、API が少し「成熟」したときに、より多くのサンプルが提供されるでしょう...

ありがとう

4

3 に答える 3

24

私が最終的に使用したアプローチは、を気にせず、サブクラスの下で直接GLKViewController使用することでした。GLKViewUIViewController

明らかに、GLKViewControllerは、ゲームなどのアプリで一貫したレンダリング ループを必要とするユーザーを対象としています。それがなければ、 への描画GLKViewは を呼び出すのと同じくらい簡単[glkView setNeedsDisplay]です。この動作を有効にするには、必ず に設定enableSetNeedsDisplayしてください。YES

それでも を利用したい場合は、次のようGLKViewControllerにアニメーション レンダリング ループを無効にすることができます。viewWillAppear

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];    // setPaused automatically set to NO in super's implementation

    [self setPaused:YES];
}

また、View Controller が再び自動的に再開されないようにするには、 に設定resumeOnDidBecomeActiveします。NO

ただし、 a でプレーンUIViewControllerを使用することGLKViewは完全に許容されます。Apple のエンジニアが、オンデマンド描画を実行する適切な方法として推奨しているのを見てきました。

于 2011-11-08T03:59:58.590 に答える
3

コードを EAGLContext マネージャーの使用から GLKit クラスの使用に変換しました。

「..glkView:drawInRect:メソッドを無視して、必要なときに必要なものだけを描画する」ことをお勧めします。これは、パフォーマンス面で賢明なオプションのようです。私は(試したことはありませんが)単純に を指定しないか、定義済みGLKViewDelegateのサブクラスGLKViewを提供しないとdrawInRect:、アニメーション ループのレンダリングは発生しないと思います。これを試みましたか?

別の方法は、何かすることがある場合にのみ更新するクラス@property (assign, nonatomic) BOOL shouldUpdate;を単純に作成することです。MyController : GLKViewController <GLKViewDelegate>

[self setDelegate:self]; // in init or awakeFromNib or other..

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    if ([self shouldUpdate]) { ...

私はあなたがアイデアを得ると確信しています、それはほとんど複雑ではありません.

言及する価値のあることの 1 つは、 GL の初期設定viewDidLoadに使用する公式 API ドキュメントの状態です。GLKViewControllerこれには問題がありました。何らかの理由で、私のglCreateShader呼び出しは常にゼロを返しました。これは、EAGLContext初期化後の設定が原因である可能性があります。initStoryboard でコントローラーを作成したため、パラメーターとして渡すことができませんでした。ただし、コードには論理的な問題はありませんでした。そのため、同様の問題が発生した場合に備えて、このフレンドリーな警告を提供します。私の解決策は、drawInRect に以下を含めることです。

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    if ([self initialGLSetupDone] == NO) {
        [self beforeFirstRender];
        [self setInitialGLSetupDone:YES];
    }
    // .. rest of render code goes here.
}

不必要に IF を入れるのは明らかに理想的ではありませんが、簡単な解決策でした。

GLKit を使用するように更新しようとするとどうなるか教えてください。

于 2011-10-22T16:53:11.157 に答える
1

GLKView を作成したら、次の行を追加します。

glkView.enableSetNeedsDisplay = TRUE;

(このため、誰もビューを自動的に再描画しません)

再描画が必要な場合は、次の行を挿入します。

[glkView setNeedsDisplay];

...その後、drawInRectルーチンは一度だけ呼び出されます。

それが役に立てば幸い。

于 2011-11-07T22:41:24.210 に答える