Skip to content

NPOT textures support in OpenGL

If you already done OpenGL development, you should be aware of POT (Power of two) texture. Because of very old conventions, the texture size must be a power of two size. Not necessarily the same for width and height though : 256×256 is valid as 128×512.

The usual thing to do when you want to load an NPOT texture (like 23×61) is to:

  • take his closed POT size: 32×64
  • depending of the book you’re reading: blit/strech the 23×61 to the 32×64 texture
  • OR blit without stretch, and adjust texture coordinate (this is what kivy does right now.)

The downside part of this approach is that you’re lost a part of memory. Bad.

While ago, i remember to found the Rectangle texture support from NVidia. Aaah, finally, is it what we was waiting from a long time ? Erm, no. Their implementation have lot of downsides:

  • The usage of a specific texture target: GL_TEXTURE_RECTANGLE_NV
  • No mipmap support
  • The texture coordinates are not normalized from 0-1… but from 0-width/height of the image
  • Some wrap mode are not supported (GL_REPEAT for eg.)

But today… i discover that most graphics card are supporting rectangle texture. If the extension GL_ARB_texture_non_power_of_two (OES_texture_npot for OpenGL ES platform), you can finally ensure that loading NPOT texture will… just work as expected :

  • You can still use GL_TEXTURE_2D
  • Mipmapping are supported
  • Texture coordinates are from 0-1
  • All wrap mode are supported

A little note here, in OpenGL ES 2, they have a native support for NPOT texture, but with somes limitations related to mipmapping.

If you want to just load NPOT texture safely without using rectangle texture, just check the availability of theses extensions :

extensions = glGetString(GL_EXTENSIONS).split()
npot_support = ('OES_texture_npot' in extensions or \
                'GL_ARB_texture_non_power_of_two' in extensions)