Download OpenGL ES Async Texture

A simple question: is it possible to load texture asynchronously with iOS and OpenGL ES?

Here is my boot method called by a separate thread:

//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); //Dispatch OpenGL stuff on main thread dispatch_sync(dispatch_get_main_queue(), ^{ //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); 

If I do not send OpenGL calls in the main thread, my textures will not be displayed ...

The same question for calling glDeleteTextures ...

Any idea?

+7
source share
1 answer

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.

+4
source

All Articles