2017-01-20 10 views
0

私は、OpenGL ESのものをレンダリングするいくつかのC++コードを持っているとしましょう。このコードには、すべてのプラットフォームで同じレンダリングループがあります。 OSに依存し、各プラットフォームごとに別々に記述されなければならないものの1つは、描画に使用されるOpenGLコンテキストにリンクされたウィンドウを作成することです。 UIWindowのサブビューに配置されたGLKViewを使用しましたが、何も結果をレンダリングしようとしなかったことに気がつきましたが、しばらく表示されているすべてが黒い画面です。GLKViewへの即時レンダリング

しかし、ループの次の反復はうまくいく。

EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; 
assert(context); 

GLKView *glView = [[GLKView alloc] initWithFrame:[[self window] frame] context:context]; 
[[self window] addSubview:glView]; 

[EAGLContext setCurrentContext:context]; 

prepareOpengl(); 
drawTriangle(); //GL_INVALID_FRAMEBUFFER_OPERATION 

[self performSelector:@selector(drawTriangleWithContext:) withObject:context afterDelay:1.0]; //nice triangle 

prepareOpengl()機能を頂点とその他もろもろのためのバッファを作成し、drawTraingle()はバッファをクリアし、traingleを描画します。ここではより明確に問題を参照するには、同じように動作し、最小限のコードです。最初の呼び出しではGL_INVALID_FRAMEBUFFER_OPERATIONとなり、performSelector:afterDelay:で呼び出された呼び出しでは問題ありません。これはおそらく、GLKViewがレンダリングバッファの作成を延期することを意味します。

最初のレンダリングを待つ必要はなく、代わりに作成されたコンテキストにすぐに描画することができます。 Hereはこの問題を示すデモプロジェクト全体です。

+1

GLKView、この場合には最高のアイデアではないかもしれません。

これはどのようにすべきです。これをアプリケーション全体に注入しているので、別のスレッド上の別のコンテキストに全体を移動し、FBOに描画し、メインスレッドでメインバッファに描画し直すことをお勧めします。また、アプリケーションがすでにいくつかのコンテキストを使用しているかどうかを調べるので、現在のコンテキストが何であるかを確認し、現在のものを設定し、作業を行い、前のコンテキストを最新のものに設定する必要があります。しかし、ここで私はバッファがまだ生成されていないと思います。これらのいずれかが問題を解決する場合は、setNeedsDisplay、displayIfNeededおよびglFlushを試してください。 –

+0

@MaticOblakこの例では、動作を反映しています。実際のコードははるかに異なっていますが、バッファはしばらくしてから生成されるという事実に悩まされます。あなたが提案したソリューションは行動を変えませんでした。 – riodoro1

答えて

0

私はそれを持っていると思います。トリックは、bindDrawableGLKViewに明示的に呼び出すことです。これにより、レンダバッファの作成が強制されます。

GLKView *glView = [[GLKView alloc] initWithFrame:[[self window] frame] context:context]; 
[glView bindDrawable]; 
[[self window] addSubview:glView]; 

[EAGLContext setCurrentContext:context] 
prepareOpengl(); 
drawTriangle(); 
[context presentRenderbuffer:GL_RENDERBUFFER];