ios – OpenGL ES异步纹理加载

简单的问题是,是否可以与iOS和OpenGL ES异步加载纹理?

这是我的加载方法,在一个单独的线程上调用:

//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);

如果我不在主线程上调度OpenGL调用,我的纹理将不会显示…

glDeleteTextures调用的同样问题……

任何的想法 ?

最佳答案
您需要在主要背景线程上使用相同的上下文.为此使用setCurrentContext:.
所以在主线程上创建新线程(作为一个例子,最简单的方法)并传递主上下文

[self performSelectorInBackground: @selector(loadTextureWithContext:) withObject: [EAGLContext currentContext]];

和创建代码:

-(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];
}

作为选项,您还可以创建新上下文并与主要上下文共享相同的EAGLSharegroup.

转载注明原文:ios – OpenGL ES异步纹理加载 - 代码日志