OpenGL ES Texture2D: Power of two

As most of you have figured out, OpenGL ES doesn’t like textures to be non power of two, and I really didn’t want to have to force all of my textures to be powers of two before loading them into my game. This presented me with a problem that had to be solved in-code.

To really understand texture mapping, especially if you’re doing iPhone development or OpenGL ES development in general, it is a good idea to visit Jeff’s blog on the subject located: HERE, and look up chapter 6 on Texture Mapping. I’ll wait, its a great read and should be glanced over at the very least!

Back? OKAY! So the problem is only powers of two can be used in OpenGL ES, so how do we convert our texture to a power of two? There are several ways to do this, but I chose to look at apples version of a texture file and learn from them.

They came up with the following to convert the width and height into a power of two:

//     Adjust the width and height to be a power of two
if( (_width != 1) && (_width & (_width - 1)) ) 
        {
                i = 1;
                while((sizeToFit ? 2 * i : i) < _width)
                        i *= 2;
                _width = i;
        }
        
        if( (_height != 1) && (_height & (_height - 1)) ) 
        {
                i = 1;
                while((sizeToFit ? 2 * i : i) < _height)
                        i *= 2;
                _height = i;
        }
&#91;/sourcecode&#93;

The first portion of the code will convert the texture to a power of 2. Since the texture will be stretched, and never shrunk, apple had to figure out a way  to shrink the texture if it became larger than the max texture size of 1024. The following code will do just that:

&#91;sourcecode="cpp"&#93;
        //      scale down an image greater than the max texture size
        while((_width > kMaxTextureSize) || (_height > kMaxTextureSize)) 
        {
                _width /= 2;
                _height /= 2;
                transform = CGAffineTransformScale(transform, 0.5, 0.5);
                imageSize.x *= 0.5;
                imageSize.y *= 0.5;
        }

the ‘transform’ is nothing more than a CGAffineTransform; in case you were confused with that. So, now that you’ve glanced over the code, you remember in the article where Jeff was talking about S and T coordinates? We’ll take care of those like this:

        _maxS = imageSize.x / (float)_width;
        _maxT = imageSize.y / (float)_height;

This will give us a number between 0 and 1, depending if the texture was re-sized or not. _maxS and _maxT will also be used in our textureCoordinates array for drawing the texture to screen. This should only render the portion of the texture that has any data, and not the padding we added to the texture.

While I am still learning OpenGL, I figured that a lot of people would be interested in the following solution.. especially if you did what I had, and had thrown out the Apple Texture2D file and re-wrote your own. Full source code to the Texture2D, or any other file within the D’Jinn Engine can be found HERE.

Hope this was informative! If anyone has any further information they would like to add, feel free!

Happy Coding Everyone!

Advertisements

9 comments so far

  1. […] accepts textures that are power 2. What if we have non standard textures ? Craig Giles has posted a solution for the same with the code […]

  2. […] out OpenGL ES Texture2D:Power of Two for the full post including code snippets and an […]

  3. […] a cute little snippet for automatically transmogrifying your OpenGL textures into iPhone-acceptable dimensions at runtime […]

  4. Kouba on

    I read a few topics. I respect your work and added blog to favorites.

    • Craig on

      Thanks for the kind words Kouba! Glad you enjoy the reading material!

  5. David Amador on

    Hi there.
    Well it’s not just OpenGl that likes power of 2 images.
    Most cards nowdays work better with power of 2 images. It’s preferable to have a 1024×1024 than a 1024×768 sometimes, even on DirectX.
    I made a habit to use power of 2 images on every game/prototype I made

  6. michaelvk on

    To really understand texture mapping, especially if you’re doing iPhone development or OpenGL ES development in general, it is a good idea to visit Jeff’s blog on the subject located:

  7. cityville on

    i probably would not have concluded this was trendy one or two years back nevertheless it’s crazy precisely how years switches the manner you have an understanding of new kinds of ideas, many thanks with regard to the piece of writing it is pleasing to see something clever occasionally in lieu of the basic nonsense mascarading as blogs and forums on the web


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: