Iphone GLKTextureLoader在第一次加载特定纹理时失败,但第二次成功

Iphone GLKTextureLoader在第一次加载特定纹理时失败,但第二次成功,iphone,opengl-es,ios5,opengl-es-2.0,glkit,Iphone,Opengl Es,Ios5,Opengl Es 2.0,Glkit,我正在使用GLKit用OpenGLES2.0制作一个iPhone应用程序。我正在使用GLKTextureLoader同步加载纹理 问题是,对于某个纹理,它无法在第一次加载它。它给出了以下错误: 无法完成该操作。(GLKTextureLoaderErrorDomain错误8。) 对于此错误代码,苹果的文档说明如下: GLKTextureLoaderErrorUncompressedTextureUpload An uncompressed texture could not be uploade

我正在使用GLKit用OpenGLES2.0制作一个iPhone应用程序。我正在使用GLKTextureLoader同步加载纹理

问题是,对于某个纹理,它无法在第一次加载它。它给出了以下错误:

无法完成该操作。(GLKTextureLoaderErrorDomain错误8。)

对于此错误代码,苹果的文档说明如下:


GLKTextureLoaderErrorUncompressedTextureUpload
An uncompressed texture could not be uploaded.
Available in iOS 5.0 and later.
Declared in GLKTextureLoader.h.
(不太多)

我可以在opengl上下文处于繁忙状态或类似状态时加载纹理吗

注:

  • 在开始加载这个纹理之前,我先加载其他纹理和第一次尝试使用的纹理。 另外,在第二次尝试时,完全相同的纹理文件将加载ok
  • 应该有足够的免费视频内存,因为在此之前我只加载了几个纹理
  • 纹理是带有alpha的未压缩PNG,但我也尝试了TGA(24位和32位),但运气不佳
欢迎任何意见,谢谢

编辑:

更多信息:

  • opengl上下文在我的所有屏幕之间共享。我这样做是为了在屏幕之间加载着色器和纹理

  • 当我转到第二个屏幕时,上面的问题发生了。在第一个屏幕中,我毫无问题地绘制了有纹理的东西(尽管是其他纹理)

  • 当我在游戏世界中加载我的内容(游戏实体)时,就会出现上述问题。每个实体都尝试加载纹理。我有一个简单的缓存系统,它只加载纹理一次,然后为所有其他实体返回相同的id。我用一种方法同步加载实体。第一个实体加载纹理失败,第二个实体加载成功,第三个实体获取缓存id

  • 我正在调用
    viewdideappear
    中的load entities方法,在加载任何实体之前,我尝试添加睡眠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。我在程序中修复了这个问题,在第一次调用纹理加载程序之后,我进行了一些其他操作

我是在加载纹理之前启用纹理时得到的。加载后只需移动glEnable(GL_纹理),问题就消失了。

好的,我将再次尝试此操作,因为我再次遇到错误。似乎发生的情况是,如果有其他一些glError尚未处理,那么您将在第一次加载纹理时遇到问题


在加载失败的纹理之前,请检查是否存在glError,然后跟踪错误发生的位置。或者,您可以在加载纹理之前捕获opengl帧,并查看之前是否抛出了glError。当我遇到错误8时,这两次都发生在我身上,并且在我修复之前发生的错误后,这两次错误都消失了。

我遇到了非常类似的问题,通过调用setCurrentContext解决了这个问题

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

也许您已经解决了这个问题,但是您是否使用了多个上下文?也许你应该用sharegroup异步加载你的纹理

因此,不要使用tex=[GLKTextureLoader textureWithContentsOfFile:bundlepath选项:选项错误:&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
}];

我还发现,当试图创建一个图像大于最大纹理大小的2D纹理时,会出现此错误。对于您可以看到的最大大小,尽管这些对于较新的设备来说并不正确,所以最好的选择是

The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)
当在运行后期加载纹理时,而之前的几个纹理已在接近启动时成功加载。我能够通过在
GLKTextureLoader
调用之前插入以下代码行来解决问题:

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

果不其然,GL报告了一个错误,但它并不要求我解决该错误以使
GLKTextureLoader
正常工作。仅仅得到GL错误就足够了。

我也有类似的问题。是由宽度/高度不是2的幂的纹理引起的。GLKTextureLoader在加载此图像和以下图像时失败。每次加载纹理后检查glGetError()都会发现问题制造者:-)。

你说在加载有问题的纹理之前加载其他纹理很好-所有这些(包括失败的纹理)都是用相同的方法吗?如果没有,很可能是当前总账上下文尚未设置。谢谢您的评论。我已经在问题中添加了更多信息。嗯,您正在同步加载纹理(不仅仅是实体),例如:+(GLKTextureInfo*)textureWithContentsOfFile:(NSString*)文件名选项:(NSDictionary*)textureOperations error:(NSError**)outError?完全正确。我已经在上面发布了我的纹理加载代码,您是否尝试在viewDidLoad中加载实体而不是ViewDidDisplay?谢谢。我会调查的。现在我在度假。。。但我会在1月1日之后尝试:)我已经研究了这个解决方案。我确保没有任何并发文件读取,但问题仍然存在。谢谢你,谢谢。肯定会尝试:)我刚刚意识到作为一个OpenGL ES 2.0项目,我不会在任何地方启用GL_纹理,所以我不知道你的答案是否相关。在这种情况下,这完全取决于着色器来确定我是否在绘制纹理三角形。是的,这是苹果代码中的一个主要错误。有人没有正确思考,他们决定在全局总账状态有任何错误时返回“failure”,而不是在其方法的条目中写入1行以检查是否已设置:(.谢谢!我已经花了几天时间处理此问题的随机mis。)