Wednesday, March 28, 2012

(The easy way) OpenGL, Bypass the power of two (POT) restriction

Many friends have mailed me and told me that they faced difficulties when they tried to apply inside their application the algorithm in my previous post about how to bypass the ‘power of two’ restriction in Open GL ES.

Thus I decided to approach the issue with a much simpler algorithm than the previous one.

Why didn't I do that already in the first post ?

Well, the cost of the simplicity is a little loss of quality.

No, no, don't leave the page. It will be insignificant loss and you can base on this method even commercial products and nobody will observe any issue in the final product.

Let me start again by telling the same story: Your designer has drawn nice backgrounds in a 320x240 resolution like the one with the colored circles in picture 1




picture 1

During the development you test the application on the emulator and you are happy seeing that everything goes fine. Suddenly you transfer your application on the real device and instead of nice backgrounds you see a white rectangle 320x240.

What happened???

OpenGL ES binds as textures only images where the width and the height are both power of 2 (POT). This means that only 32×16, 128×64, 8×256 etc images are supported. It does not sound flexible, huh? It is a certain restriction for your designer (I bet it is you!).

Newer GPU`s that support OpenGL version 2.0 or above can load any arbitrary dimension but why to take such a huge risk for the marketing of your application?

The main idea is very simple: OpenGL is stupid enough to load a texture where width & height are of power of two but since the texture is loaded and bound OpenGL accepts to scale it even using different scale factors for width and height.
What does it mean for our example?

After the picture is ready by your artist and well painted open it in your editor ( I use GIMP) and scale it by giving for new dimensions what you believe is the nearest values that are of power of two. For our example it could be 256x128. Then you have it a stretched image like in picture 2.




picture 1


This image is perfectly loaded and bound as an OpenGL-texture.
But you don’t want it to be 256x128. You want to see circles on the screen, not ellipses.

I am sure you know what the next step will be: You have to stretch it back to the original dimensions. For this there must be calculated the scale factors for width and height.

float fScaleWidth = 320/256 = 1.25f
float fScaleHeight = 240/128 = 1.875f


Q: What values do you need to have as fixed to make it full parametrically?

And then in the render function

if  ( mesh.isBackground == true )
{
     g.glScalef(fScaleFactor*fScaleWidth, fScaleFactor*fBgrScaleHeight, 1.0f);
}


where fScaleFactor is the global scale factor, assuming that you may have designed everything in your game initially for a resolution 320x240 but you want it to fill screens even with bigger resolutions.

Good luck.

No comments:

Post a Comment