1

我正在使用 GLKit 开发一个 iPhone OpenGL 应用程序,并使用以下代码创建纹理:

NSRange dotRange = [textureFileName rangeOfString:@"." options:NSCaseInsensitiveSearch];
        if (dotRange.location == NSNotFound){
            NSLog(@"OpenGLDRawMaterial:createTextureFromFileName, incorrect file name given in inputs");
            return nil;
        }   

   GLKTextureInfo *newTexture;

        NSError *error = nil;   // stores the error message if we mess up
        NSString *bundlepath = [[NSBundle mainBundle] pathForResource:[textureFileName substringToIndex:dotRange.location] 
                                                               ofType:[textureFileName substringFromIndex:(dotRange.location+1)]];

newTexture = [GLKTextureLoader textureWithContentsOfFile:bundlepath options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderOriginBottomLeft] error:&error];

该代码运行良好,只要它在主线程中运行。每次我尝试让它在工作线程中工作时,我都会收到以下消息:

“2013-03-04 02:09:01.528 Puppeteer[7063:1503] 从图像加载纹理时出错:错误域=GLKTextureLoaderErrorDomain Code=17”操作无法完成。(GLKTextureLoaderErrorDomain 错误 17。)“UserInfo=0x1c5977e0”

我用于大型中央调度队列的代码是:

dispatch_queue_t backgroundQueue = dispatch_queue_create("loadPlayViewBackgroundTexture", 0);

    dispatch_async(backgroundQueue, ^{
       [self createTexturesForPlayView]; // method calling texture creation

        dispatch_async(dispatch_get_main_queue(), ^{
                  });
             });
             dispatch_release(backgroundQueue);

如果您有任何见解或想法如何解决此问题并在后台加载纹理,我将非常感激 :) 干杯,Stéphane

4

1 回答 1

2

请注意,在文档中+textureWithContentsOfFile:options:error:包含此声明:在此处查看

This class method loads the texture into the sharegroup attached to the current context for the thread this method is called on.

当您-textureWithContentsOfFile:从后台线程调用时,该线程没有设置 OpenGL 上下文(当前 GL 上下文是每个线程的状态),因此 GLKit 不知道要将纹理加载到哪个共享组。

但是,你让这变得比它需要的更难。GLKit 已经可以自己管理异步纹理加载。看看变种-textureWithContentsOfFile:options:queue:completionHandler:。您根本不必创建自己的队列:您只需传入主队列即可在加载完成时接收通知。

于 2013-03-04T03:29:45.107 回答