IPhone: GLKTextureInfo не работает с Grand Central Dispatch?

Я разрабатываю приложение OpengGL для iPhone с использованием GLKit и использую следующий код для создания текстур:

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] Ошибка при загрузке текстуры с изображения: Error Domain=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);

Если у вас есть какие-либо идеи или идеи, как решить эту проблему и загрузить текстуры в фоновом режиме, я был бы очень признателен :) Ура, Стефан


person stephane    schedule 04.03.2013    source источник
comment
Вы не можете одновременно получить доступ к одному и тому же контексту OpenGL ES из нескольких потоков, поэтому правильно ли вы блокируете, чтобы убедиться, что операции рендеринга и т. д. не выполняются одновременно с загрузкой текстуры? Кроме того, вам нужно будет назначить контекст OpenGL ES потоку вашего блока GCD с помощью -setCurrentContext:, иначе при попытке загрузить текстуру может отсутствовать допустимый контекст OpenGL ES.   -  person Brad Larson    schedule 04.03.2013


Ответы (1)


Обратите внимание, что в документацию для +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:. Вам вообще не нужно создавать свою собственную очередь: вы можете просто пройти в основную очередь, чтобы получить уведомление о завершении загрузки.

person Frogblast    schedule 04.03.2013