在iphone上加载openGL游戏的屏幕?

时间:2009-11-12 18:11:07

标签: iphone opengl-es

我正在使用openGL for iPhone,虽然一切都很好,但我必须在游戏的某些部分等待大约一秒,这些部分使用了大量的精灵表。有没有办法为这些部分创建一个加载屏幕?或者任何方式来知道某个纹理是否已经用openGL完成加载?

编辑:

我使用此功能加载纹理:

-(void)loadTexture:(NSString*)nombre {

CGImageRef textureImage = [UIImage imageNamed:nombre].CGImage;
if (textureImage == nil) {
    NSLog(@"Failed to load texture image");
    return;
}

textureWidth = NextPowerOfTwo(CGImageGetWidth(textureImage));   
textureHeight = NextPowerOfTwo(CGImageGetHeight(textureImage));

imageSizeX= CGImageGetWidth(textureImage);
imageSizeY= CGImageGetHeight(textureImage);

GLubyte *textureData = (GLubyte *)calloc(1,textureWidth * textureHeight * 4); // Por 4 pues cada pixel necesita 4 bytes, RGBA

CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth,textureHeight,8, textureWidth * 4,CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast );
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)textureWidth, (float)textureHeight), textureImage);

CGContextRelease(textureContext);

glGenTextures(1, &textures[0]);

glBindTexture(GL_TEXTURE_2D, textures[0]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);

free(textureData);


glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   

}

我通常在游戏部分加载我需要的纹理,例如,一个或两个1024x1024纹理作为精灵表对我来说足够大,但在某些级别,比如boss战,例如,加载大约5或6个纹理(老板很大并且有大量不同的攻击)并且游戏大约需要2到3秒才能同时加载所有这些纹理。

3 个答案:

答案 0 :(得分:2)

正如Till所解释的那样,由于您正在同步加载纹理,因此一旦“loadTexture”完成就会加载它。

通过OpenGL渲染到另一个线程的屏幕,而通过OpenGL加载可能会变得非常麻烦。

A - 经常使用 - hack是在纹理加载之间更新屏幕:

  1. 渲染0%屏幕
  2. loadTexture
  3. 渲染10%的屏幕
  4. loadTexture
  5. 根据需要重复
  6. 通过一些额外的工作,很容易生成一个小表,其中包含有关加载的时间信息,因此“x%”接近事实;)

    我们通常会自动执行此步骤,在发布新版本之前执行“加载”运行,其中我们记录何时加载了资源以及需要多长时间。

答案 1 :(得分:1)

由于您正在同步加载纹理,因此很明显,只要loadTexture方法完成,就会完成对纹理的加载。

编辑/补充: 您应该避免/更改代码中的一些事项。并不是说这会真正解决你的实际问题,只是一般的建议......

1st:不要使用imageNamed来加载纹理图像 - 这通常是一个坏主意。使用imageWithContentsOfFile,因为它不会使用您不会重复使用的数据占用图像缓存。

第二:一旦加载了一个纹理,苹果就会称之为“加热纹理” - 这个术语基本上是为了快速和肮脏(甚至是屏幕外)渲染而短暂使用该纹理。这样,您可以确保纹理完全可用,并且在进行第一次“真实”渲染时不会施加额外的惩罚。我们正在谈论毫秒的惩罚 - 所以没有大事但很明显。

第三:尝试将纹理加载转移到应用程序空闲的点 - 例如。在启动屏幕中等待用户输入 - 但不要在applicationDidFinishLaunching方法中这样做。

这里有一个问题 - 为什么在渲染/在关卡内部时加载纹理。为什么不预装你可能需要的一切?你可以使用最多24mb的纹理内存而不会造成任何惩罚(好吧,减去fbo内存)。

答案 2 :(得分:0)

或者,您可以在加载纹理时简单地显示UIImageView动画。这具有绘制单独威胁的特殊好处......这是一个特殊情况,就像UIActivityIndi​​catorView(微调器)一样。我不确定苹果公司在技术上如何实现这一目标,但效果很好。

唯一的问题是你需要将加载动画帧保存在单独的文件中,而不是保存在精灵表中。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImageView_Class/Reference/Reference.html