2

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.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Marc
  • 159
  • 2
  • 7
  • See http://stackoverflow.com/questions/3014352/fullscreen-texture-iphone-opengl-es – sam hocevar Aug 27 '11 at 17:48
  • I'm quite sure you mean powers of two, sorry for being that pedantic. – Christian Rau Aug 27 '11 at 18:58
  • 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 [here](http://stackoverflow.com/questions/4760174/rendering-to-non-power-of-two-texture-on-iphone/4761453#4761453). – Brad Larson Aug 31 '11 at 16:07

2 Answers2

3

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.

  • 1
    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: http://www.imgtec.com/powervr/insider/docs/PowerVR%20Series5%20Graphics.SGX%20architecture%20guide%20for%20developers.1.0.8.External.pdf – Benjamin Schulz Aug 27 '11 at 19:41
  • 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 Mar 14 '12 at 17:07
0
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

Lijiayu
  • 7
  • 1