2009-11-12 46 views
1

我正在用于iPhone的openGL,虽然一切都很好,但我必须在游戏的某些部分使用大量的精灵表等待一秒钟。有没有办法为这些部分创建一个加载屏幕?或者通过任何方式来知道某个纹理是否完成了openGL加载?在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); 

} 

我通常加载我需要deppending对游戏的部分的纹理,例如,一个或两个1024x1024的贴图,其用于因为精灵表对于大多数关卡都是足够的,但是在某些关卡中,例如boss战,我会加载大约5或6个纹理(老板很大,有很多不同的攻击),而且游戏需要大约2或3秒一次加载所有这些纹理。

+0

由于_you_装入纹理(通过OpenGL的), 当你的代码完成后,你应该知道。 如何加载纹理?代码示例将非常有用。 – Andreas 2009-11-12 18:29:28

+0

这个问题听起来很多,就像你没有自己实现GL-stuff一样。 – Till 2009-11-12 18:49:23

+0

@Andreas:我为这个问题添加了一些代码,希望现在更清楚。谢谢。 @Till:?。 – 2009-11-12 20:30:48

回答

2

As Till解释说,由于您正在同步加载纹理,所以一旦“loadTexture”完成,它就会被加载。

通过OpenGL在另一个线程中渲染到另一个线程,而通过OpenGL加载时会变得非常麻烦。

A - 经常使用 - 黑客是更新纹理加载的屏幕:

  1. 呈现0%的屏幕
  2. loadTexture
  3. 呈现10%的屏幕
  4. loadTexture
  5. 重复的需要

随着一点额外的工作很容易生成一个具有关于加载时间信息的小表,因此“x%”非常接近实际;)

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

1

由于您正在同步加载纹理,因此,只要loadTexture方法完成,就可以立即加载该纹理。

编辑/添加: 有几件事情你应该避免/改变你的代码。不是说这样可以真正解决你的实际问题,只是一般性的建议......

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

第二次:一旦加载了纹理,就会有一个术语叫做“加热纹理” - 它基本上是简单地使用该纹理进行快速和肮脏的(甚至是离屏)渲染。这样,您可以确定纹理将完全可用,并且在进行第一次“真实”渲染时不会受到额外的惩罚。我们正在谈论几毫秒的惩罚 - 所以没有太大的影响,但显而易见。

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

这里给你一个问题 - 你为什么要在渲染/关卡内加载纹理。为什么不预先加载你可能需要的一切?您可以使用高达24mb的纹理内存而不会施加任何处罚(以及减去fbo内存)。

+0

谢谢。任何关于如何减少加载的想法,也许只是在屏幕上绘制一个小的加载动画并在我的方法加载完纹理后立即移除它,或者其他建议? – 2009-11-12 21:22:29

+0

@Til:“你为什么要在渲染时加载纹理/为什么不预加载你可能需要的所有东西?你可以使用高达24mb的纹理内存而不用施加任何惩罚(好吧,减去fbo内存)。”我原本是在一开始就预加载所有的纹理......但是当我一次尝试加载太多纹理时(总共有大约10 MB的png纹理!),应用程序将我踢出去了。我想立刻预先加载所有纹理,但我不知道如何... – 2009-11-24 05:31:32

0

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

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

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