views:

259

answers:

3

I'm aware that OpenGL textures on the the iphone are required to be a power of 2, is this true of OpenGL 2.0 as well? If I have an image that is 320 x 480 in size and want to draw it full screen is there any possible way to do this with OpenGL.

Thanks

+1  A: 

Assuming you don't have too many full-screen textures, you could just use a 512x512 texture and only use 320x480 of it. It will definitely work.

Xavier Ho
+1  A: 

I guess that depends on the hardware. I used to create the closest power of 2 texture i.e if my texture is 320x480 then I will create a texture of 512x512 which will have the original texture data. this ensures portability but consumes a bit more memory ;)

+1  A: 

NPOT textures are supported on PowerVR SGX hardware, but have restrictions. NPOT textures cannot use mipmaps, must be 2D (no cube-maps or 3D textures) and must use the GL_CLAMP_TO_EDGE for texture wrapping in both dimensions; this is supported by default in OpenGL ES 2.0 and under ES 1.1 by the extension GL_APPLE_texture_2D_limited_npot

For ES 1.1, you can check at runtime to see if this extension is present with this code:

const char* extensions = (char*) glGetString(GL_EXTENSIONS);
bool npot = strstr(extensions, "GL_APPLE_texture_2D_limited_npot") != 0;

Since this is only present on the SGX and not the MBX, be aware that relying on NPOT texture support will limit you to the newer SGX devices. Of course, relying on ES 2.0 will do the same, so if that's your intended target, NPOT support is a moot point and you can go ahead with NPOT textures.

Here's an alternate solution that lets you keep using ES 1.1 and retain full device support. Put the 320x480 texture inside a 512x512, fill the whitespace with other background tiles, glyphs, or other textures that will be drawn at the same time (to avoid multiple glBindTexture calls) and then use one of my favourite ES 1.1 extensions, GL_OES_draw_texture, to quickly copy the 320x480 section onto the viewport:

int rect[4] = {0, 0, 480, 320};
glBindTexture(GL_TEXTURE_2D, texBackground);
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);
glDrawTexiOES(0, 0, z, 480, 320);

Sidebar: The OpenGL ES 2.0 spec itself doesn't specify any restrictions on NPOT textures; unless I'm mistaken, Apple is imposing the limitations - of course, in the ES 1.1 world, NPOT support doesn't exist at all, so it's an addition there.

Chris Peredun
Thanks Chris, very good info. Excuse me for being a noob, but what is the z parameter in glDrawTexiOES()? depth? I can't seem to find any documentation. Thanks
Ben Reeves
@Ben: Whoops, sorry about that. Z is the depth of the rectangle - 0 is the near plane, 1 is the far plane, and decimal values give you that percentage of distance between them. In the example above, it was for a strictly 2D scene managing its own depth with the "painter's algorithm" so z=0; for most uses of backgrounds you'll want z=1 unless you've inverted your depth range. The OpenGL spec page lays it out a bit better: (http://www.khronos.org/registry/gles/extensions/OES/OES_draw_texture.txt - about halfway down the page)Clear as mud? :)
Chris Peredun