Difference between revisions of "NPOT Texture"

From OpenGL Wiki
Jump to: navigation, search
m (Bot: Updating section links to use redirects.)
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This page discusses NPOT textures.<br>
+
{{infobox feature
<br>
+
| name = Non-Power-Of-Two Textures
=== Introduction ===
+
| core = 2.0
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.<br>
+
| arb_extension = [http://www.opengl.org/registry/specs/ARB/texture_non_power_of_two.txt GL_ARB_texture_non_power_of_two]
<br>
+
}}
=== 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<br>
 
http://www.opengl.com/registry<br>
 
<br>
 
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)<br>
 
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.<br>
 
3. You can't have mipmaps. Filter modes can be GL_LINEAR or GL_NEAREST<br>
 
4. You can't have anisotropy filtering<br>
 
5. texture_rectangle is basically a 2D texture. No 3D or cubemap support<br>
 
6. There is some performance loss when using it<br>
 
7. Some GPUs padd the texture in order to make them POWER OF 2 texture<br>
 
<br>
 
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. It adds sampler2DRect and sampler2DRectShadow. It also adds these<br>
 
vec4 texture2DRect(sampler2DRect sampler, vec2 coord)<br>
 
vec4 texture2DRectProj(sampler2DRect sampler, vec3 coord)<br>
 
vec4 texture2DRectProj(sampler2DRect sampler, vec4 coord)<br>
 
vec4 shadow2DRect(sampler2DRectShadow sampler, vec3 coord)<br>
 
vec4 shadow2DRectProj(sampler2DRectShadow sampler, vec4 coord)<br>
 
<br>
 
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);
 
  
  //Fragment Shader
+
An '''NPOT Texture''' is a texture whose dimensions are not powers of 2 ('''N'''on-'''P'''ower-'''O'''f-'''Two'''). In earlier hardware, there was a requirement that the dimensions of a texture were a power of two in size. NPOT textures are textures that are not restricted to powers of two.
  uniform sampler2DRect Texture0;
 
  varying vec2 TexCoord0;
 
  void main()
 
  {
 
      gl_FragColor = texture2DRect(Texture0, TexCoord0);
 
  }
 
  
And in the end, cleanup
+
== Usage ==
glDeleteTextures(1, &textureID);
 
  
=== OpenGL 2.0 and GL_ARB_texture_non_power_of_two ===
+
Using this is easy; simply pass arbitrary sizes when allocating [[Texture Storage]]. These will work for any kind of [[Texture]], from [[Cubemap Texture]]s (though the width and height of these must be the same) to [[Array Texture]]s.
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.<br>
 
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.<br>
 
Geforce FX is an exception. It will always do software rendering. You have to use GL_ARB_texture_rectangle for this GPU.<br>
 
  
Example for GL 2.0 NPOT 3D texture :
+
While modern hardware no longer has the power-of-two limitation on texture dimensions, it is generally a good idea to keep using power-of-two textures unless you specifically ''need'' NPOTs. [[Mipmap|Mip-mapping]] with such textures can have slightly unintended consequences, compared to the power-of-two case.
  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
+
[[Framebuffer Object|Render targets]] are a common place where you want to have a specific, arbitrary size for your textures.
glDeleteTextures(1, &textureID);
+
 
 +
=== Compression ===
 +
 
 +
Most of the non-generic [[Image Formats#Compressed formats|compressed texture formats]] are based around 4x4 blocks of pixels. While it is possible to have arbitrary sizes of these textures, you generally should keep them at a multiple of four in size. It won't lose you anything to do so.
 +
 
 +
=== Older hardware ===
 +
 
 +
The R300 and R400-based cards (Radeon 9500+ and X500+) are incapable of generic NPOT usage, despite allegedly supporting OpenGL 2.0 (which requires full support). These cards only allow you to use NPOTs if the texture has no mipmaps.
 +
 
 +
NV30-based cards (GeForce FX of any kind) are incapable of NPOTs at all, despite allegedly OpenGL 2.0 (which again requires NPOTs). It will do software rendering if you try to use it.
 +
 
 +
Any hardware beyond that can handle NPOTs of any kind perfectly.
 +
 
 +
== Rectangle Textures ==
 +
{{main|Rectangle Textures}}
 +
 
 +
Rectangle textures have never had a power-of-two restriction. However, they take texture coordinates in texture space rather than normalized texture coordinates like other kinds of textures. These have their uses, but they have fallen out of favor with the advent of generic NPOT textures.
 +
 
 +
[[Category:Textures]]

Latest revision as of 16:39, 6 May 2015

Non-Power-Of-Two Textures
Core in version 4.6
Core since version 2.0
ARB extension GL_ARB_texture_non_power_of_two

An NPOT Texture is a texture whose dimensions are not powers of 2 (Non-Power-Of-Two). In earlier hardware, there was a requirement that the dimensions of a texture were a power of two in size. NPOT textures are textures that are not restricted to powers of two.

Usage

Using this is easy; simply pass arbitrary sizes when allocating Texture Storage. These will work for any kind of Texture, from Cubemap Textures (though the width and height of these must be the same) to Array Textures.

While modern hardware no longer has the power-of-two limitation on texture dimensions, it is generally a good idea to keep using power-of-two textures unless you specifically need NPOTs. Mip-mapping with such textures can have slightly unintended consequences, compared to the power-of-two case.

Render targets are a common place where you want to have a specific, arbitrary size for your textures.

Compression

Most of the non-generic compressed texture formats are based around 4x4 blocks of pixels. While it is possible to have arbitrary sizes of these textures, you generally should keep them at a multiple of four in size. It won't lose you anything to do so.

Older hardware

The R300 and R400-based cards (Radeon 9500+ and X500+) are incapable of generic NPOT usage, despite allegedly supporting OpenGL 2.0 (which requires full support). These cards only allow you to use NPOTs if the texture has no mipmaps.

NV30-based cards (GeForce FX of any kind) are incapable of NPOTs at all, despite allegedly OpenGL 2.0 (which again requires NPOTs). It will do software rendering if you try to use it.

Any hardware beyond that can handle NPOTs of any kind perfectly.

Rectangle Textures

Rectangle textures have never had a power-of-two restriction. However, they take texture coordinates in texture space rather than normalized texture coordinates like other kinds of textures. These have their uses, but they have fallen out of favor with the advent of generic NPOT textures.