GLKTextureLoader сбой при загрузке определенной текстуры в первый раз, но второй раз выполняется

Я делаю приложение iPhone с OpenGL ES 2.0, используя GLKit. Я использую GLKTextureLoader для синхронного загрузки текстур.

Проблема заключается в том, что для определенной текстуры она не загружается в первый раз. Он дает эту ошибку:

The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)

Для этого кода ошибки в документации на Apple указано следующее:


GLKTextureLoaderErrorUncompressedTextureUpload
An uncompressed texture could not be uploaded.
Available in iOS 5.0 and later.
Declared in GLKTextureLoader.h.

(не очень).

Могу ли я пытаться загрузить текстуру, в то время как контекст opengl находится в каком-то занятом состоянии или что-то в этом роде?

Примечания:

  • Прежде чем загружать эту текстуру, я загружаю другие текстуры, и они работают с первой попытки. Кроме того, тот же самый файл текстуры будет загружаться нормально во второй попытке.
  • Должно быть достаточно свободной видеопамяти, так как у меня есть только несколько текстур, загруженных до этого.
  • Текстура - это несжатый PNG с альфой, но я тоже не пытался с TGA (24 бит и 32 бит).

Любые идеи приветствуются, спасибо

ИЗМЕНИТЬ:

Дополнительная информация:

  • контекст opengl разделяется между всеми моими экранами. Я делаю это, чтобы мои шейдеры и текстуры загружались между экранами.

  • проблема выше, когда я перехожу на второй экран. На первом экране я рисую текстурированные вещи без проблем (другие текстуры).

  • Проблема выше, когда я загружаю свой контент (игровые сущности) в игровой мир. Каждый объект пытается загрузить текстуру. У меня есть простая система кэширования, которая загружает текстуру только один раз, а затем возвращает один и тот же идентификатор для всех других объектов. Я загружаю объекты синхронно одним способом. Первый объект не загружает текстуру, а затем второй и успешно, а затем третий получает кешированный идентификатор.

  • Я вызываю метод load objects в viewDidAppear, и я попытался добавить спать в течение 2 секунд, прежде чем загружать любые объекты, но ничего не изменилось.

EDIT:

Код загрузки текстуры:


- (GLKTextureInfo *)loadTextureAtPath:(NSString*)path ofType:(NSString*)type withKey:(NSString *)key 
{
    GLKTextureInfo* tex;

    tex = [self textureWithKey:key];
    if (tex)
        return tex;

    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithBool:NO],
                              GLKTextureLoaderOriginBottomLeft, 
                              nil];

    NSError * error;    
    NSString *bundlepath = [[NSBundle mainBundle] pathForResource:path ofType:type];

    tex = [GLKTextureLoader textureWithContentsOfFile:bundlepath options:options error:&error];
    if (tex == nil) 
        DLOG_LOCAL(@"Error loading texture: %@", [error localizedDescription]);                
    else
        [textures setObject:tex forKey:key];

    return tex;
}


Ответ 1

Я также получал

The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)

при загрузке текстуры в конце среды выполнения, в то время как несколько предыдущих текстур загрузились успешно ближе к запуску. Я смог решить проблему, вставив следующую строку кода до вызова GLKTextureLoader:

NSLog(@"GL Error = %u", glGetError());

Разумеется, GL сообщал об ошибке, но мне не потребовалось, чтобы я исправил ошибку, чтобы работать GLKTextureLoader. Простого получения ошибки GL было достаточно.

Ответ 2

Я получил это, когда добавляю текстуры перед загрузкой текстуры. Просто переместился glEnable (GL_TEXTURE) после загрузки и проблема исчезла.

Ответ 3

Возможно, вы решили это, но используете ли вы несколько контекстов? возможно, вы должны асинхронно загружать текстуру вместе с sharegroup.

поэтому вместо использования tex = [GLKTextureLoader textureWithContentsOfFile: опции пучка: параметры error: & ошибка];

используйте что-то вроде:

GLKTextureLoader *textureloader = [[GLKTextureLoader alloc] initWithSharegroup:self.eaglContext.sharegroup];
GLKTextureInfo *myTexture;
[textureloader textureWithCGImage:_currentForegroundImage.CGImage options:nil queue:nil completionHandler:^(GLKTextureInfo *textureInfo, NSError *error) {
        myTexture = textureInfo;
        if(error) {
            // log stuff
        }
        // do something
}];

Ответ 4

У меня была аналогичная проблема. Это было вызвано текстурой с шириной/высотой, не имеющей силы 2. Не удалось выполнить GLKTextureLoader при загрузке этого и следующих изображений. Проверка glGetError() после каждой загрузки текстуры выявила нарушителей спокойствия: -).

Ответ 5

Хорошо, я попробую это снова, когда снова столкнулся с ошибкой. Похоже, что если есть еще один glError, который не был обработан, тогда у вас возникнут проблемы с загрузкой текстуры в первый раз.

Прежде чем загружать эту текстуру, которая не работает, проверьте наличие glError и затем отследите, где произошла эта ошибка. Или вы можете захватить рамку opengl до того, где будет загружена текстура, и посмотреть, будет ли предшествовать glError. Это происходило со мной одновременно, когда я столкнулся с ошибкой 8, и оба раза эта ошибка исчезла, как только я исправил ошибку, которая произошла ранее.

Ответ 6

Я столкнулся с той же проблемой. Я не совсем уверен, почему это произошло точно так же, как оказалось, что одновременно происходит несколько файловых операций. Например, выполнение загрузки файла (для данных модели) прямо ПОСЛЕ использования загрузчика текстур в первый раз вызовет ошибку 8. Я исправил его в своей программе, выполнив некоторые другие операции после вызова загрузчика текстуры в первый раз.

Ответ 7

Я также обнаружил, что вы получаете эту ошибку при попытке создать 2D-текстуру с размером изображения, большим, чем максимальный размер текстуры. Для максимального размера вы можете увидеть Apple Open GL ES Platform Notes, хотя они не отображаются правильно для более новых устройств, поэтому лучше всего сделать получить значение напрямую.

Ответ 8

У меня была очень похожая проблема, и она была решена путем вызова setCurrentContext.

self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.context];