You need to use the same context in the background thread that you use on the main. To do this, use setCurrentContext:. So, on the main topic, create a new thread (as an example, the easiest way) and pass the main context
[self performSelectorInBackground: @selector(loadTextureWithContext:) withObject: [EAGLContext currentContext]]
And the creation code:
-(void) loadTextureWithContext:(EAGLContext*) main_context { [EAGLContext setCurrentContext: main_context]; //Image size GLuint width = CGImageGetWidth(image.CGImage); GLuint height = CGImageGetHeight(image.CGImage); //Create context void *imageData = malloc(height * width * 4); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); //Prepare image CGContextClearRect(context, CGRectMake(0, 0, width, height)); CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage); //Bind texture glBindTexture(GL_TEXTURE_2D, name); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //Release CGContextRelease(context); free(imageData); [EAGLContext setCurrentContext: nil]; }
As an option, you can also create a new context and share the same EAGLSharegroup with the main one.