Carga de imágenes sin potencia de dos en OpenGL ES iPhone

Does anyone know an efficient way to load textures into OpenGL ES that are not in sizes of a power of two? I am new to OpenGL, and I'm working on a 2D game for iPhone and I have a lot of textures already made. It would be very tedious job to go back and resize all of my textures to a power of two.

preguntado el 27 de agosto de 11 a las 17:08

I'm quite sure you mean powers of two, sorry for being that pedantic. -

It's no problem. Thank you for pointing that out. -

Newer iOS devices (iPhone 3G S and on) support non-power-of-two textures in OpenGL ES 1.1 via an extension, or natively in 2.0. You don't need to do redo these textures to work with them on those devices, as I describe in my answer aquí. -

2 Respuestas

For performance reasons, it's best to putt all your sprites into an atlas. An atlas is a large texture, that contains all your sprites. There are tools to automate this process. For example TexturePacker: http://www.texturepacker.com/

Depending on which technology you're using, you might have to parse the output from texture packer to get the UV-Offsets.

Respondido 27 ago 11, 23:08

btw.: The reason for the performance loss is because texture switches are damn expensive on the iphone. You want to have the fewest number of texture switches possible. a little background can be found here: imgtec.com/powervr/insider/docs/… - Benjamin Schulz

Thank you very much. This helped a lot. - Marc

If you're using linear blending, this approach will cause sprites to be blended with their neighbor texels within the atlas instead of via something like CLAMP, which is likely what you want for the sprite. Something to keep in mind when you start scaling down. - nacitar sevaht

unsigned int NextPOT(unsigned int x)
{
    x = x - 1;
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >>16);
    return x + 1;
}

unsigned int width  = CGImageGetWidth(image.CGImage);
unsigned int height = CGImageGetHeight(image.CGImage);
unsigned int Width_POT  = NextPOT(width);
unsigned int Height_POT = NextPOT(height);
CGRect Rect = CGRectMake(0,0,width, height);
CGSize size         = CGSizeMake(Width_POT, Height_POT);
UIGraphicsBeginImageContext(size);
[image drawInRect:Rect];
UIImage* result     = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

image is the source image which size is non pow of 2, result is the image you can pass to OpenGL

Respondido 31 ago 11, 19:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.