OpenGL ESレンダリングループは、私のiPhoneアプリケーションの別のスレッドに配置されています。 EAGLContextのpresentRenderbufferメソッドが失敗することを除いて、すべてがうまくいっています。結果は白い空白の画面になります。 メインスレッドで同じコードを実行すると、presentRenderbufferは成功し、グラフィックスが正しく表示されます。 別のスレッドでOpenGLを実行する正しい方法は何ですか?iphoneの別のスレッドでOpenGL ESを使用するには?
18
A
答えて
14
EAGLSharegroup
を作成する必要があります。
スレッド間のOpenGLコンテキストの共有については、this threadを参照してください。 iOS5を前へ
UPDATE
私は、ディスクからのテクスチャの非同期ロードを許可するようにスレッド間のOpenGLコンテキストを共有しました。しかし、iOS5のCVOpenGLESTextureCaches
は基本的にテクスチャのアップロードを無料にするので、shareGroupsはもう必要なく、私のコードはより簡単で高速になります。
2
別のスレッドでコンテキストをレンダリングしないでください。代わりに、すべての計算を別のスレッドで行い、レンダリングがメインの表示スレッドで行われるようにします。
+0
あなたは本当に簡単にGCDを使用していることを行うことができます。ここでは
は、定型的なコードです。 – Cthutu
13
ありがとう、Fistman。私はそれを動作させ、別のスレッドを使用して期待したパフォーマンスの向上を得ました。 EAGLSharegroupは問題を解決しました。
hereのように、2番目のスレッドのコンテキストを作成しました。
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
struct OpenGLContext
{
GLint Width;
GLint Height;
GLuint RenderBuffer;
GLuint FrameBuffer;
GLuint DepthBuffer;
UIView* View;
EAGLContext* MainContext;
EAGLContext* WorkingContext;
EAGLSharegroup* Sharegroup;
// Trivial constructor.
OpenGLContext();
// Call on the main thread before use.
// I call it in layoutSubviews.
// view must not be nil.
void MainInit(UIView* view);
// Call on the rendering thread before use, but
// after MainInit();
void InitOnSecondaryThread();
// Call before any OpenGL ES calls, at the
// beginning of each frame.
void PrepareBuffers();
// Present frame. Call at the end of each
// frame.
void SwapBuffers();
};
OpenGLContext::OpenGLContext()
{
Width = 0;
Height = 0;
RenderBuffer = 0;
FrameBuffer = 0;
DepthBuffer = 0;
View = 0;
MainContext = 0;
WorkingContext = 0;
Sharegroup = 0;
}
void OpenGLContext::InitOnSecondaryThread()
{
EAGLSharegroup* group = MainContext.sharegroup;
if (!group)
{
NSLog(@"Could not get sharegroup from the main context");
}
WorkingContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:group];
if (!WorkingContext || ![EAGLContext setCurrentContext:WorkingContext]) {
NSLog(@"Could not create WorkingContext");
}
}
void OpenGLContext::MainInit(UIView* view)
{
View = view;
MainContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!MainContext || ![EAGLContext setCurrentContext:MainContext]) {
NSLog(@"Could not create EAGLContext");
return;
}
NSLog(@"Main EAGLContext created");
glGenFramebuffersOES(1, &FrameBuffer);
glGenRenderbuffersOES(1, &RenderBuffer);
glGenRenderbuffersOES(1, &DepthBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, FrameBuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, RenderBuffer);
if (![MainContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)View.layer])
{
NSLog(@"error calling MainContext renderbufferStorage");
return;
}
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, RenderBuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &Width);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &Height);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, DepthBuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, Width, Height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, DepthBuffer);
glFlush();
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
}
WorkingContext = MainContext;
}
void OpenGLContext::PrepareBuffers()
{
if (!WorkingContext || [EAGLContext setCurrentContext:WorkingContext] == NO)
{
NSLog(@"PrepareBuffers: [EAGLContext setCurrentContext:WorkingContext] failed");
return;
}
glBindFramebufferOES(GL_FRAMEBUFFER_OES, FrameBuffer);
}
void OpenGLContext::SwapBuffers()
{
if (!WorkingContext || [EAGLContext setCurrentContext:WorkingContext] == NO)
{
NSLog(@"SwapBuffers: [EAGLContext setCurrentContext:WorkingContext] failed");
return;
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, RenderBuffer);
if([WorkingContext presentRenderbuffer:GL_RENDERBUFFER_OES] == NO)
{
NSLog(@"SwapBuffers: [WorkingContext presentRenderbuffer:GL_RENDERBUFFER_OES] failed");
}
}
関連する問題
- 1. iPhone用OpenGL ESでDepthBufferをリクエストする
- 2. iPhone OpenGL ESペイントアプリブラシエフェクト
- 3. 現在のスレッドにはOpenGL ESのコンテキスト・カレントはありません - OpenGL ES 3.0を使用しているLWJGL
- 4. iPhone/iPad、OpenGL ES、CADisplayLink
- 5. glScissor help(iPhone OpenGL ES)
- 6. iPhoneのOpenGL ES 1.1のOpenGLカラーインデックス?
- 7. OpenGL ESを使用したiPhoneでのアンチエイリアスの問題
- 8. iphone opengl es glDrawElementsの問題
- 9. glGetUniformLocationリターン-1のOpenGL ES(iPhone)
- 10. iPhone OSの2Dユーザーインターフェイスに使用できるOpenGL ESフレームワークはどれですか?
- 11. OpenGLコードをiPhoneのOpenGL ESに移植する際の問題
- 12. OpenGL ESを使用してiPhone上にタイル張りの背景
- 13. iPhone iOS 5.0 OpenGl ES 2.0
- 14. iPhone OpenGL ESテクスチャ2Dマスキング
- 15. レンダリング.h Blender OpenGL ES 1.1を使用してiPhoneにエクスポート
- 16. 可能OpenGL ES 2.0スレッドの問題
- 17. iPhone(OpenGL ES)上のglPolygonModeの代替?
- 18. iPhoneボードゲーム:OpenGL ESまたはCoreGraphics?
- 19. iPhone OpenGL ES 2dの背景テクスチャ
- 20. iPhone OpenGL ESの間違ったアルファブレンディング
- 21. iPhoneゲームアプリでOpenGL ESを使用してアニメーションで直線を描く方法は?
- 22. は、OpenGL ESオブジェクトのアルファ値を変更するiPhone
- 23. OpenGL ES for iPhoneでビデオを表示する方法は?
- 24. iPhone OpenGL es:ポイントについての行列を回転する
- 25. OpenGL ES:テクスチャテクスチャの色を使用して
- 26. iPhoneでOpenGL ESでイメージをコンボリューションする:可能ですか?
- 27. iPhoneでOpenGL ESを使用して直線を描画しますか?
- 28. OpenGL ESのクラッシュをデバッグするには?
- 29. 移調行列は - - のOpenGL ES - 垂直に水平iPhone
- 30. iPhone OpenGL ESのPNGファイルを作成する
「テクスチャアップロードを無料にする」とはどういう意味ですか?私はCVPixelBufferCreateWithBytes()からの結果でCVOpenGLESTextureCacheCreateTextureFromImage()を呼び出してみました。glTexImage2D()でテクスチャをアップロードするのと同じくらい時間がかかりました。 – MoDJ
glTexImage2Dはmemcpyと同じ機能をテクスチャに、TextureFromImageは画像のテクスチャをポイントします。コピーは必要ありません。多くのメモリ帯域幅を節約できます。 GLの多くが非同期であるため、タイミングだけでは明らかにならないでしょう。 GPU/CPU使用率とフレームレートを調べる必要があります。 –
http://stackoverflow.com/questions/12813442/cvopenglestexturecache-vs-gltexsubimage2d-on-iosを参照してください。ユーザーがバッファを渡したときに記述したようには動作しません。実際、この実行パスでは、glTexImage2Dで費やされるCPU時間が非常に多くなりました。 – MoDJ