Сбой GLKTextureLoader при первой загрузке определенной текстуры, но во второй раз - PullRequest
10 голосов
/ 23 декабря 2011

Я делаю приложение для 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-битный), но безуспешно.

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

EDIT

Подробнее:

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

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

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

  • Я вызываю метод загрузки сущностей в 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;
}


Ответы [ 8 ]

31 голосов
/ 19 декабря 2012

я тоже получаю

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

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

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

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

4 голосов
/ 09 февраля 2012

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

3 голосов
/ 27 марта 2013

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

3 голосов
/ 12 сентября 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
}];
2 голосов
/ 09 марта 2012

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

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

1 голос
/ 18 сентября 2012

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

1 голос
/ 30 декабря 2011

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

0 голосов
/ 26 марта 2012

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

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