2011-08-01 123 views
7

簡單的問題,是否有可能與iOS和OpenGL ES異步加載紋理?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調用...

任何想法?

回答

4

您需要在後臺線程上使用與主線程上使用的上下文相同的上下文。爲此使用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

+0

我不知道用glBindTexture()調用來創建紋理不會中斷任何您可能會在主線程中執行的繪圖嗎?我想共享組(=單獨的gl語境)是否要走? –

+0

@ranReloaded如果您正在銷燬當前用於渲染的紋理,它可能會中斷繪圖。 – Max

+1

不,我的意思是這樣的:當你在紋理創建過程中調用glBindTexture()在後臺線程(加載紋理的那一刻)的那一刻,當前用於繪製的任何(以前創建的,完全加載的)紋理在主線程中)取消綁定(一次只能綁定一個紋理到任何給定的上下文,對吧?) –