2010-08-12 35 views
6

我需要在OpenGL ES的后台线程中加载纹理。但在后台线程中调用glGenTextures时总是返回零。glGenTextures在后台线程中返回零

-(void) someMethodInMainThread { 
    [self performSelectorInBackground:@selector(load) withObject:nil]; 
} 

-(void) load { 
    GLuint textureID = 0; 
    glGenTextures(1, &textureID);   
} 

textureID为零。 如果我将代码更改为[self performSelector:@selector(tmp)withObject:nil];它会正常工作,并返回1. 我应该如何加载后台线程纹理?

回答

9

这是一个常见错误,每个OpenGL上下文只能在一个线程中处于活动状态(当前),因此当您创建新线程时,它不具有任何OpenGL上下文,并且所有GL调用都会失败。

解决方案:创建另一个OpenGL上下文,使其在后台线程中处于当前状态。要加载纹理,您还希望与主要上下文共享OpenGL名称(纹理ID等)。

+0

我必须使用EAGLSharegroup? – Division 2010-08-12 13:48:13

+0

看起来像,我不是iPhone的专家,但通过谷歌搜索,我看到这是在GL环境之间共享资源的句柄。 – 2010-08-12 13:55:43

-1

在调用OpenGL之前,在后台线程中使用[EAGLContext setCurrentContext:]

EAGLContext只能是单个线程中的当前上下文。所有OpenGL调用都需要当前上下文,因此需要在调用任何OpenGL函数之前从后台线程设置。

请注意,EAGLContexts是而不是线程安全。

从Apple DOC:

应该避免使多个线程在同一背景下的电流。 OpenGL ES不提供线程安全性,因此如果要在多个线程上使用相同的上下文,则必须采用某种形式的线程同步来防止从多个线程同时访问相同的上下文。