Difference between revisions of "NPOT Texture"

From OpenGL Wiki
Jump to: navigation, search
m
m (OpenGL 2.0 and GL_ARB_texture_non_power_of_two)
Line 45: Line 45:
 
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 +
  glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAPS, GL_TRUE);
 
   glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 10, 20, 19, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
 
   glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 10, 20, 19, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
  glGenerateMipmapEXT(GL_TEXTURE_3D);  //Generate mipmaps automatically
 
  
 
And in the end, cleanup
 
And in the end, cleanup
 
  glDeleteTextures(1, &textureID);
 
  glDeleteTextures(1, &textureID);

Revision as of 19:31, 15 December 2008

This page discusses NPOT textures.

Introduction

You might need to render your viewport to a texture and do some scene effect. You would probably need a RECT texture to do this. It is always possible to do it with a POWER OF TWO 2D texture of course. In case you want to use RECT textures, here is some information you might need.

More Information

The first extension to support NPOT textures was GL_NV_texture_rectangle. Later on, GL_EXT_texture_rectangle was added on the Apple platform and this same extension was made available later on for Window and Linux. Both extensions were identical. They had the same limitation since the GPUs of the time had the same limitation (Radeon 9700 and Geforce FX 5800). You can view the OpenGL registry
http://www.opengl.com/registry

1. With those extensions, instead of the texture coordinates being normalized (0.0 to 1.0), you would have to use (0.0 to width and 0.0 to height)
2. The texture wrap mode needs to be GL_CLAMP_TO_EDGE, GL_CLAMP, GL_CLAMP_TO_BORDER. GL_CLAMP_TO_EDGE recommended for best performance.
3. You can't have mipmaps. Filter modes can be GL_LINEAR or GL_NEAREST
4. You can't have anisotropy filtering
5. texture_rectangle is basically a 2D texture. No 3D or cubemap support
6. There is some performance loss when using it
7. Some GPUs padd the texture in order to make them POWER OF 2 texture

GL_ARB_texture_rectangle was added which has the same limitations as the predecessors. It just adds support for sampling the RECT texture from GLSL shaders.

Example:

  uint textureID;
  glGenTextures(1, &textureID);
  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureID);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

And in the end, cleanup

glDeleteTextures(1, &textureID);

OpenGL 2.0 and GL_ARB_texture_non_power_of_two

With GL 2.0, you can make textures of any type (2D, 3D, cubemap), with any dimension, any filter mode, mipmaps, anisotropy, any wrap mode. It may however run in software mode. If GL_ARB_texture_non_power_of_two is present, it should always run in hw mode. GL_ARB_texture_non_power_of_two is thus an indicator extension.
If you don't have GL_ARB_texture_non_power_of_two, then you can make NPOT texture, just that follow the same limitation as for GL_ARB_texture_rectangle (no mipmaps, GL_CLAMP_TO_EDGE, etc) and it will be hw accelerated.
Geforce FX is an exception. It will always do software rendering. You have to use GL_ARB_texture_rectangle for this GPU.

Example for GL 2.0 NPOT 3D texture :

  uint textureID;
  glGenTextures(1, &textureID);
  glBindTexture(GL_TEXTURE_3D, textureID);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAPS, GL_TRUE);
  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 10, 20, 19, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

And in the end, cleanup

glDeleteTextures(1, &textureID);