【问题标题】:GLKTextureLoader fails when loading a certain texture the first time, but succeeds the second timeGLKTextureLoader 第一次加载某个纹理时失败,但第二次成功
【发布时间】:2012-01-26 12:27:09
【问题描述】:

我正在使用 GLKit 使用 OpenGL ES 2.0 制作 iPhone 应用程序。我正在使用 GLKTextureLoader 同步加载纹理。

问题是对于某个纹理,第一次加载失败。它给出了这个错误:

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

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


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

(不是很多)。

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

注意事项:

  • 在加载此纹理之前,我会加载其他纹理,这些纹理在第一次尝试时就可以使用。 此外,完全相同的纹理文件将在第二次尝试时正常加载。
  • 应该有足够的可用视频内存,因为在此之前我只加载了几个纹理。
  • 纹理是带有 alpha 的未压缩 PNG,但我也尝试过使用 TGA(24 位和 32 位),但没有成功。

欢迎任何想法,谢谢

编辑

更多信息:

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

  • 当我进入第二个屏幕时会出现上述问题。在第一个屏幕中,我毫无问题地绘制了带纹理的东西(不过其他纹理)。

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

  • 我在 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;
}


【问题讨论】:

  • 你说你在有问题的纹理之前加载了其他纹理 - 所有这些(包括失败的纹理)都是用相同的方法吗?如果不是,很可能是当前的 gl 上下文尚未设置。
  • 感谢您的评论。我在问题中添加了更多信息
  • 嗯,您正在同步加载纹理(不仅仅是实体),例如:+ (GLKTextureInfo *)textureWithContentsOfFile:(NSString *)fileName options:(NSDictionary *)textureOperations error:(NSError ** )outError ?
  • 完全正确。我已经在上面发布了我的纹理加载代码
  • 您是否尝试在 viewDidLoad 中加载实体而不是 viewDidAppear ?

标签: iphone opengl-es ios5 opengl-es-2.0 glkit


【解决方案1】:

我遇到了类似的问题。是由宽度/高度不是 2 次方的纹理引起的。GLKTextureLoader 无法加载此图像和以下图像。在每次纹理加载后检查 glGetError() 会发现麻烦制造者:-)。

【讨论】:

    【解决方案2】:

    我也得到了

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

    在运行时加载纹理较晚,而之前的几个纹理在接近启动时已成功加载。我能够通过在GLKTextureLoader 调用之前插入以下代码行来解决问题:

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

    果然,GL 报告了一个错误,但它不需要我解决该错误,GLKTextureLoader 就可以工作。仅仅得到 GL 错误就足够了。

    【讨论】:

    • 是的,这是 Apple 代码中的一个主要错误。有人没有正确思考,如果全局 GL 状态有任何错误,他们决定返回“失败”,而不是编写 1 行来检查它是否已经在进入他们的方法时设置:(。
    • 谢谢!我花了好几天的时间来解决随机丢失纹理的问题。
    • +1!也为我工作。我正在开发部署在 6.1 设备上的 Xcode5。看起来如果 OpenGL 有任何现有的错误,它只会导致 GLKTextureLoader 不尝试加载纹理(这是......好吧......我没关系。)
    • 它对我也有帮助,在 iOS 9.0 设备上使用 xCode 7.0。
    【解决方案3】:

    我还发现,当您尝试使用大于最大纹理大小的图像创建 2D 纹理时,您会收到此错误。对于最大尺寸,您可以查看 Apple's Open GL ES Platform Notes,尽管这些对于较新的设备似乎不正确,因此最好的选择是 get the value directly

    【讨论】:

      【解决方案4】:

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

      所以不要使用 tex = [GLKTextureLoader textureWithContentsOfFile:bundlepath options:options error:&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
      }];
      

      【讨论】:

        【解决方案5】:

        我遇到了非常相似的问题,已经通过调用 setCurrentContext 解决了。

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            我在加载纹理之前启用纹理时得到了这个。加载后只需移动 glEnable(GL_TEXTURE) 即可解决问题。

            【讨论】:

            • 谢谢。一定会尝试:)
            • 我刚刚意识到作为一个 OpenGL ES 2.0 项目我没有在任何地方启用 GL_TEXTURE 所以我不知道你的答案是否相关。在这种情况下,这完全取决于着色器来确定我是否正在绘制带纹理的三角形。
            【解决方案8】:

            我遇到了同样的问题。除了似乎同时进行多个文件操作之外,我不完全确定它为什么会发生。例如,在第一次使用纹理加载器之后立即执行文件加载(用于模型数据)会导致错误 8 弹出。我在我的程序中通过在第一次调用纹理加载器后发生一些其他操作来修复它。

            【讨论】:

            • 谢谢。我会对此进行调查。现在我正在度假......但我会在 1 月 1 日之后尝试这个:)
            • 我已经研究过这个解决方案。我确保我没有任何并发​​文件读取,但问题仍然存在。还是谢谢。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-28
            • 2020-09-13
            • 2012-07-31
            • 2022-08-15
            • 2016-08-25
            • 2020-08-31
            相关资源
            最近更新 更多