我需要在OpenGL ES中的后台线程中加载纹理。但是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。 我应该如何在后台线程中加载纹理?
答案 0 :(得分:10)
这是一个常见错误,每个OpenGL上下文只能在一个线程中处于活动状态(当前),因此当您创建新线程时,它没有任何OpenGL上下文,并且所有GL调用都会失败。
解决方案:创建另一个OpenGL上下文,使其在后台线程中保持最新状态。要加载纹理,您还需要与主要上下文共享OpenGL名称(纹理ID等)。
答案 1 :(得分:-1)
在调用OpenGL之前,在后台线程中使用[EAGLContext setCurrentContext:]。
EAGLContext只能是单个线程中的当前上下文。所有OpenGL调用都需要当前上下文,因此需要在调用任何OpenGL函数之前从后台线程设置。
请注意,EAGLContexts 不是线程安全的。
来自Apple doc:
您应避免在多个线程上使相同的上下文变为当前。 OpenGL ES不提供线程安全性,因此如果要在多个线程上使用相同的上下文,则必须采用某种形式的线程同步来防止从多个线程同时访问相同的上下文。