2011-10-12 17 views
18

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

このタイプのセットアップでは、推奨される方法はありますか?

  • は、View ControllerのpreferredFramesPerSecond0に設定するか、単にフレームの更新を一時停止 :私はの線に沿って何かを期待しますか?
  • glkViewControllerUpdateまたはglkView:drawInRect:の方法 を無視し、必要なときに必要なものを描画します。
  • (私は私 が同様にテクスチャにレンダリングされることを考えるとbindDrawableを呼び出すために必要なのですか?)フレームを表示するため にビューのsetNeedsDisplay通常UIViewと同様に使用します。

新しいAPIが設計されていないのであれば、おそらくそれほどの労力はありません。私はドキュメントがそれより少し徹底していればいいと思う。 APIはちょっと...

おかげ

+0

でも、GLKitと連動してセカンダリFBOにレンダリングすることはできます。 http://mickyd.wordpress.com/2012/05/20/creating-render-to-texture-secondary-framebuffer-objects-on-ios-using-opengl-es-2/ – MickyD

答えて

22

最後に、GLKViewControllerを気にすることなく、UIViewControllerのサブクラスの下に直接GLKViewを使用しました。

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

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

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

    [self setPaused:YES]; 
} 

はまた、自動的に再び再開からビューコントローラを防ぐためにNOからresumeOnDidBecomeActiveを設定。

のプレーンUIViewControllerを使用しても問題はありませんが、オンデマンド描画を実行するのに適切な方法としてアップルのエンジニアが推奨しています。

+0

enableSetNeedsDisplayメソッドとresumeOnDidBecomeActiveメソッドをviewWillAppear(BOOL)アニメーション化されていないので、前述のように設定する必要があるメソッドを明確にすることができれば助かります。ありがとう。 –

+0

ビュー/ビューコントローラの作成時にこれらのプロパティを設定します。たとえば、コードで 'GLKViewController'を作成する場合は、おそらく' alloc'/'init'の後の行に設定します。インターフェースビルダーで作成した場合は、ビューコントローラーに '-awakeFromNib'メソッドを実装するのが良いかもしれません。一般的に、このようなプロパティは、オブジェクトが作成されてから、使用される前に/の後に設定する必要があります。 – Stuart

+0

これのサンプルを示すオープンソースコードがありますか?ありがとう – aehlke

3

私はちょうど私がGLKitクラスを使用して自分自身をロールEAGLContextマネージャを使用してから私のコードを変換してきたが「成熟」したときに、おそらくより多くのサンプルが提供されます。

あなたは「.. glkView:drawInRect:メソッドを無視して、必要なときに必要なものを描画する」ことをお勧めします。これはパフォーマンス上の賢明なオプションのようです。 GLKViewDelegateを指定しないか、またはサブクラス化したGLKViewdrawInRect:を定義してアニメーションループのレンダリングが行われない場合、私は(試していませんが)仮定します。あなたはこれを試みましたか?

代替は、単に何かがある場合にのみ更新しますあなたのMyController : GLKViewController <GLKViewDelegate>クラスでいくつかの@property (assign, nonatomic) BOOL shouldUpdate;を作成するには、次のようになります。

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

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

私はあなたのアイデアを得ると確信している、それはほとんど複雑です。

1つの言及に値するもの:公式のAPIドキュメントの状態GLKViewControllerの初期GL設定にはviewDidLoadを使用する必要があります。私はこれに問題があった。何らかの理由で私のglCreateShader呼び出しは常にゼロを返しました。これは私がEAGLContextを初期化したことによるものかもしれません。ストーリーボードにコントローラを作成してから、initパラメータとして渡すことができませんでした。しかし、コードには論理的に間違ったものはありませんでした。同様の問題が発生した場合に備えて、この警告を提供します。私のソリューションは、私の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を使用するように更新するとどうなるか教えてください。あなたが再描画したい

(これにより、誰もが自動的にビューを再描画しませんので)

glkView.enableSetNeedsDisplay = TRUE;

、この行を挿入します:あなたはGLKViewを作成した後

+0

「viewDidLoad」に関しては、あなたが気づいたように、シェイダーを作成する前に 'EAGLContext'を設定する必要があります。 GLコードの残りの部分を設定する直前に、 'viewDidLoad'でもこれを行うことに害はありません。このセットアップを実行する方法の良い例については、Xcodeで 'OpenGL Game'テンプレートプロジェクトを見てください。 – Stuart

+0

ラッチの先端ありがとう。 CAEAGLLayerやその他の回避策を手動で描画するよりも簡単です。 –

1

、この行を追加します

[glkView setNeedsDisplay]; 

... then drawInRectルーチンは1回だけ呼び出されます。

希望します。

+1

-1。これは間違っています - 'enableSetNeedsDisplay'を' NO'に設定すると** 'GLKView'の' setNeedsDisplay'メソッドが無効になります。このプロパティは、 'GLKViewController'を使用すると自動的に' NO'に設定されます。したがって、setNeedsDisplay "mode"で描画するときは手動で 'YES'に設定する必要があります。 – Stuart

+1

この返信を修正しました... – rodamn

関連する問題