GLKTextureLoader 第一次加载某个纹理失败,但第二次成功

发布于 2024-12-22 19:40:48 字数 1988 浏览 1 评论 0原文

我正在使用 GLKit 使用 OpenGL ES 2.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 上下文处于某种繁忙状态或类似状态时尝试加载纹理?

注意:

  • 在加载此纹理之前,我会加载其他纹理,并且这些纹理在第一次尝试时即可工作。 此外,完全相同的纹理文件将在第二次尝试时加载正常。
  • 应该有足够的可用视频内存,因为在此之前我只加载了几个纹理。
  • 纹理是带有 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;
}


I'm making an iPhone application with OpenGL ES 2.0 using the GLKit. I'm using GLKTextureLoader to load textures synchronously.

The problem is that for a certain texture, it fails to load it the first time. It gives this error:

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

For this error code, the apple documentation says the following:


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

(not very much).

Could I be trying to load the texture while the opengl context is in some busy state or something like that?

Notes:

  • Before getting to load this texture I load other textures and those work on the first try.
    Also, the exact same texture file will load ok on the second try.
  • There should be enough free video memory as I have only a couple of textures loaded before this one.
  • The texture is an uncompressed PNG with alpha, but I also tried with TGA (24bit & 32bit) with no luck.

Any ideas are welcomed, thanks

EDIT:

More info:

  • the opengl context is shared between all my screens. I'm doing this to keep my shaders and textures loaded between screens.

  • the problem above happens when I go to my second screen. In the first screen I draw textured stuff with no problems (other textures though).

  • The problem above happens when I load my content (game entities) in the game world. Each entity tries to load the texture. I have a simple caching system that loads the texture only once and then returns the same id for all other entities. I'm loading the entities synchronously, in one method. The first entity fails to load the texture then comes the second and succeeds and then the third one gets the cached id.

  • I am calling the load entities method in viewDidAppear and I've tried to add a sleep for 2 seconds before I load any entities but nothing changed.

EDIT:

Texture loading code:


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


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

蔚蓝源自深海 2024-12-29 19:40:49

我也遇到了这种

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

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

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

果然,GL 报告了错误,但不需要我解决为了让 GLKTextureLoader 正常工作而出现的错误。仅仅得到 GL 错误就足够了。

I was also getting

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

when loading a texture late in runtime while several previous textures had loaded successfully closer to launch. I was able to solve the problem by inserting the following line of code before the GLKTextureLoader call:

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

Sure enough, GL was reporting an error, but it did not require me to address the error in order for GLKTextureLoader to work. Merely getting the GL Error was enough.

过期情话 2024-12-29 19:40:49

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

I got this when enabling textures before loading the texture. Simply moved glEnable(GL_TEXTURE) after the loading and the issue was gone.

鸩远一方 2024-12-29 19:40:49

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

所以不要使用 tex = [GLKTextureLoadertextureWithContentsOfFile: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
}];

Maybe you've resolved this, but are you using multiple contexts? maybe you should be loading your texture asynchronously with sharegroup.

so instead of using tex = [GLKTextureLoader textureWithContentsOfFile:bundlepath options:options error:&error];

use something like:

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
}];
酒解孤独 2024-12-29 19:40:49

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

I had a similar problem. Is was caused by a texture that had width / height not power of 2. GLKTextureLoader failed on loading this and the following images. Checking glGetError() after each texture load revealed the troublemakers :-).

回忆追雨的时光 2024-12-29 19:40:49

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

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

Ok, I'll try this one again as I ran into the error again. What appears to happen is that if there is some other glError that has not been processed, then you will have trouble with the texture loading on the first time.

Before you load that texture that fails, check for a glError and then track down where that error occurred. Or you can capture an opengl frame prior to where the texture is loaded and see if a glError is being thrown prior. This happened to me both times when I ran into the error 8, and both times this error disappeared once I fixed the error that had occurred earlier.

罪歌 2024-12-29 19:40:49

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

I ran into the same problem. I'm not exactly sure as to why it occurred exactly other than that it appeared that there were multiple file operations going on at the same time. For example, performing a file load (for model data) right AFTER using the texture loader for the first time would cause error 8 to pop up. I fixed it in my program by having some other operations occur after the texture loader is called for the first time.

忘你却要生生世世 2024-12-29 19:40:49

我还发现,当尝试使用大于最大纹理大小的图像创建 2D 纹理时,您会收到此错误。对于最大尺寸,您可以查看 Apple 的 Open GL ES 平台说明,尽管这些对于较新的设备来说似乎不正确,因此最好的选择是直接获取该值

I've also found that you get this error when trying to create a 2D texture with an image larger than the maximum texture size. For the max size you can see Apple's Open GL ES Platform Notes, although those do not appear correct for newer devices so the best bet is to get the value directly.

£噩梦荏苒 2024-12-29 19:40:49

我有非常类似的问题,它已经通过调用 setCurrentContext 解决了。

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

I had very similar problem and it has been solved by calling setCurrentContext.

self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.context];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文