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

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

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

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

ИЗМЕНИТЬ:

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


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



person Andrei Stanescu    schedule 23.12.2011    source источник
comment
Вы говорите, что загружаете другие текстуры нормально, а не проблемную - все ли они (включая ту, которая не работает) одним и тем же методом? в противном случае вполне может быть, что текущий контекст gl не был установлен.   -  person Mike K    schedule 23.12.2011
comment
Спасибо за комментарий. Я добавил больше информации к вопросу   -  person Andrei Stanescu    schedule 23.12.2011
comment
хм, вы загружаете текстуры (не только объекты) синхронно с чем-то вроде: + (GLKTextureInfo *) textureWithContentsOfFile: (NSString *) fileName options: (NSDictionary *) textureOperations error: (NSError **) outError?   -  person Mike K    schedule 23.12.2011
comment
точно. Я разместил свой код загрузки текстуры выше   -  person Andrei Stanescu    schedule 23.12.2011
comment
Вы пробовали загружать объекты в viewDidLoad вместо viewDidAppear?   -  person Johnmph    schedule 23.12.2011
comment
да. проблема все еще существует   -  person Andrei Stanescu    schedule 23.12.2011
comment
У Бретта есть ответ ниже - не включайте GL_TEXTURE, пока не загрузитесь.   -  person Cthutu    schedule 24.07.2012
comment
@Chutu, как я сказал Бретту, я нигде не включаю GL_TEXTURE. Я использую OpenGL ES 2.0, и включать GL_TEXTURE просто не нужно.   -  person Andrei Stanescu    schedule 25.07.2012
comment
Кроме того, я только что снова протестировал проект, и проблема исчезла. Проект остался в том же состоянии, в каком я задал вопрос, поэтому я думаю, может быть, это произошло из-за ошибки в SDK?   -  person Andrei Stanescu    schedule 25.07.2012


Ответы (8)


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

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

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

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

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

person Newman    schedule 19.12.2012
comment
Да, это серьезная ошибка в коде Apple. Кто-то не думал должным образом, и они решили вернуть ошибку, если в глобальном состоянии GL были какие-либо ошибки, вместо того, чтобы писать 1-строку, чтобы проверить, была ли она уже установлена ​​при входе в их метод :(. - person Adam; 21.07.2013
comment
Спасибо! Я потратил несколько дней на эту проблему со случайными отсутствующими текстурами. - person shelll; 01.11.2013
comment
+1! У меня тоже сработало. Я разрабатываю Xcode5 на устройстве 6.1. Похоже, что если в OpenGL есть какая-либо существующая ошибка, это просто заставит GLKTextureLoader не пытаться загрузить текстуру (что ... ну ... я в порядке). - person Steven Lu; 06.12.2013
comment
Мне тоже помогло использование xCode 7.0 на устройстве iOS 9.0. - person CryingHippo; 15.10.2015

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

person Brett    schedule 08.02.2012
comment
Спасибо. Обязательно попробую :) - person Andrei Stanescu; 09.02.2012
comment
Я только что понял, что будучи проектом OpenGL ES 2.0, я нигде не включаю GL_TEXTURE, поэтому не знаю, актуален ли ваш ответ. В этом случае все зависит от шейдера, чтобы определить, рисую ли я текстурированные треугольники или нет. - person Andrei Stanescu; 10.02.2012

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

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

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

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
}];
person lzl    schedule 12.09.2012

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

person Christoph K.    schedule 27.03.2013

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

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

person John Stricker    schedule 09.03.2012

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

person John Stricker    schedule 29.12.2011
comment
Спасибо. Я исследую это. Сейчас я в отпуске ... но попробую после 1 января :) - person Andrei Stanescu; 30.12.2011
comment
Я изучил это решение. Я убедился, что у меня нет одновременного чтения файлов, но проблема все еще существовала. Спасибо, в любом случае. - person Andrei Stanescu; 09.01.2012

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

person brett    schedule 18.09.2012

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

self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.context];
person Kiril    schedule 25.03.2012