views:

270

answers:

2

I'm working in an openGL for iPhone , and although everything works great I have to wait about a second in certain sections of the game which use a ton of sprite sheets. It's there any way to create a loading screen for such sections ?, or any way to know if a certain texture has finished loading with openGL?

EDIT:

I load my textures with this function:

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

}

I usually load the textures i need deppending on the section of the game, for example, one or two 1024x1024 textures which serve me as sprite sheets are enough for most levels, but in certain levels, like boss battles for example, I load about 5 or 6 textures ( the boss is big and has a ton of different attacks) and the game takes about 2 or 3 secs to load all those textures at once.

A: 

Since you are loading the texture synchronously, it is rather obvious that the loading of that texture is done as soon as your loadTexture-method is done.

EDIT / ADDITIONS: There is a couple of things you should avoid / change in your code. Not that this would really solve your actual problem, just a general advice....

1st: Do not use imageNamed for loading a texture image - that is generally a bad idea. Use imageWithContentsOfFile as that does not hog the image cache with data that you wont be reusing anyways.

2nd: Once a texture is loaded, there is a term that Apple calls "warming the texture" - which basically is using that texture briefly for a quick and dirty (even offscreen) rendering. That way you can be sure that the texture will be fully available and no extra penalties are imposed when doing the first "real" rendering. We are talking milliseconds of penalty - so no biggy but noticeable.

3rd: Try to shift the texture loading to a point where the application is idle anyways - eg. waiting for user input in the startup screen - but refrain from doing that in the applicationDidFinishLaunching method.

Here comes a question to you - why do you load the textures while rendering / inside the level. Why not preloading everything you possibly need? You can use up to 24mb of texture memory without imposing any penalties (well, minus the fbo memory).

Till
Thanks. Any Idea about how to make the loading less annoying, maybe just draw a small loading animation on screen and remove It as soon as my method finishes loading the textures ?, or any other suggestion ?
José Joel.
@Til: "why do you load the textures while rendering / inside the level. Why not preloading everything you possibly need? You can use up to 24mb of texture memory without imposing any penalties (well, minus the fbo memory)." I originally used to preload all my textures at the beginning...but the app kicked me out whenever I tried to load too many textures at once ( and I have about 10 MBs of .png textures in total !). I would like to preload all my textures at once, but I didnt know how...
José Joel.
+2  A: 

As Till explained, since you are loading the texture synchronously, it will be loaded once "loadTexture" is done.

Rendering to the screen in another thread via OpenGL while loading via OpenGL can become really messy real quick.

A - quite often used - hack is to update the screen between texture loads:

  1. render 0% screen
  2. loadTexture
  3. render 10% screen
  4. loadTexture
  5. repeat as needed

With a little bit of extra work it's easy to generate a small table that has timing information about the loading, so the "x%" is close to the truth ;)

We usually automate this step and before shipping a new version do a "load through" run, in which we log when what resource is loaded and how long it takes.

Andreas