Сбой 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;
}
8 ответов
Я также получал
The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)
при загрузке текстуры в конце времени выполнения, когда несколько предыдущих текстур были успешно загружены ближе к запуску. Я смог решить эту проблему, вставив следующую строку кода перед GLKTextureLoader
вызов:
NSLog(@"GL Error = %u", glGetError());
Конечно, GL сообщал об ошибке, но мне не требовалось исправлять ее, чтобы GLKTextureLoader
работать. Достаточно просто получить ошибку GL.
Я получил это при включении текстур перед загрузкой текстуры. Просто переместил glEnable(GL_TEXTURE) после загрузки и проблема исчезла.
Может быть, вы решили эту проблему, но вы используете несколько контекстов? возможно, вам следует загружать текстуру асинхронно с помощью 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. GLKTextureLoader не удалось загрузить это и следующие изображения. Проверка glGetError() после каждой загрузки текстуры выявляла нарушителей:-).
Хорошо, я попробую еще раз, когда снова столкнулся с ошибкой. Похоже, что происходит, если есть еще один glError, который не был обработан, то у вас будут проблемы с загрузкой текстуры в первый раз.
Перед загрузкой текстуры, которая не работает, проверьте наличие glError, а затем отследите, где произошла эта ошибка. Или вы можете захватить фрейм opengl до того, где будет загружена текстура, и посмотреть, не было ли выброшено glError. Это случилось со мной оба раза, когда я столкнулся с ошибкой 8, и оба раза эта ошибка исчезла, как только я исправил ошибку, которая произошла ранее.
Я также обнаружил, что вы получаете эту ошибку при попытке создать 2D текстуру с изображением, размер которого превышает максимальный размер текстуры. Максимальный размер вы можете увидеть в заметках Apple OpenGLESPlatform, хотя они не выглядят корректными для более новых устройств, поэтому лучше всего получить значение напрямую.
Я столкнулся с той же проблемой. Я не совсем уверен, почему это произошло именно потому, что оказалось, что одновременно выполнялось несколько файловых операций. Например, выполнение загрузки файла (для данных модели) сразу ПОСЛЕ использования загрузчика текстур в первый раз вызовет ошибку 8. Я исправил это в своей программе, заставив некоторые другие операции выполняться после первого вызова загрузчика текстур.
У меня была очень похожая проблема, и она была решена путем вызова setCurrentContext.
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.context];