Non power-of-2 textures

I have seen a demo loading a 320*240 sized image and using it in ortho-mode to cover the whole screen with it.
Well, i tried it out myself and it worked.

However, as far as i know, in the OpenGL standard it is not defined, that gfx cards have to be able to handle such textures, is it? So can i expect that all gfx card are able to handle this, or is it unsafe to do it?

Jan.

when mipmaps are generated, the image gets correctly resized.

I suppose you’re using gluBuildMipmaps(), right? It will resize it for you to get power of two’s.

Otherwise, there’s GL_EXT_texture_rectangle, but it uses another target (GL_TEXTURE_RECTANGLE_EXT as opposed to GL_TEXTURE2D), so it won’t just work without you actually using it.

When you use gluBuild2DMipmaps non-power of 2 images get rescaled, so it is possible to have some distortion in image, but fortunately there is this nice GL_NV_texture_rectangle extension. Check it out.

I dont understand why there is no GL_EXT_texture_rectangle in registry when it is same as GL_NV_texture_rectangle?

And what happens, when i render to a texture, which is sized 1024*768. Is that possible? Or do these extensions make that possible, too?

Two issues:

  1. It is possible to fill a screen with a non-power-of-2 texture without using any extensions. You just need to set your texture coordinates properly. For instance, say you have a 320x240 window, and you just want to draw a 320x240 flat image (i.e. texture) right to the window. To make sure you don’t have any weird distortions in the image, create a texture of resolution 512x256 (the next higher power-of-2 in each dimension), and fill the lower-left 320x240 pixels with the image data you want. The remaining pixels in the image can be anything; doesn’t matter.

Then, in your GL rendering code, draw the quad with texture coordinates (0, 0), (320/512, 0), (320/512, 240/256), (0, 240/256). Thus you will map the relevant part of your texture to the quad without any distortion.

The advantage of this approach is that you don’t need extensions. The downside is that your texture image needs to be a power of 2, so like in the above case it’s 512x256 even though you only need 320x240 of the pixels.

  1. You can use NV_texture_rectangle so that your texture can be exactly 320x240. With this extension, texture coordinates go from [0, width] and [0, height] instead of [0, 1].

Eric

I believe that EXT_texture_rectangle is still a work in progress. It is not finalized yet, which is why it doesn’t appear in the official GL extension listings yet.

That said, I believe the latest public ATI GL drivers support EXT_texture_rectangle.

Eric

EXT_texture_rectangle is an Apple-ism which ATI appear to have adopted. NVidia refuse to adopt it. Fortunately, the extensions are almost identical other than the EXT vs NV naming issue. Also fortunately, the ARB appears to be considering rectangular textures for an ARB extension.

EXT_texture_rectangle is an Apple-ism which ATI appear to have adopted.

What is an “Apple-ism”, precisely?

Roughly the same thing as Orange-ism

Originally posted by Korval:
What is an “Apple-ism”, precisely?

http://developer.apple.com/opengl/extensions.html

Figured I’d just post an update since I couldn’t find precisely what I needed to know searching the list:

For availability of non-pow2 textures check for extension:
“GL_EXT_texture_rectangle” or
“GL_NV_texture_rectangle”
(ATI uses GL_EXT_texture_rectangle NVidia uses GL_NV_texture_rectangle)

For texture format for any card simply use
GL_TEXTURE_RECTANGLE_NV

BTW: I’m curious on anyones opinion on this: There seem to definately be cases where GL_TEXTURE_RECTANGLE_NV can be faster. In particular if you’re not binding the texture. The combo glTexImage2D & glTexSubImage2D is definately slower than a single glTexImage2D with GL_TEXTURE_RECTANGLE_NV. Since the amount of data transferred is the same I don’t quite see why. The time hit is increased if internal format & type are ‘unfortunate’ and require some munging by the driver.

This leads me to the following speculation: Could it be that even though we use glTexSubImage2D the chunk of memory processed & sent to the card is actually the size allocated with glTexImage2D. It certainly looks that way comparing the performance numbers.

Originally posted by vmh5:
BTW: I’m curious on anyones opinion on this: There seem to definately be cases where GL_TEXTURE_RECTANGLE_NV can be faster. In particular if you’re not binding the texture. The combo glTexImage2D & glTexSubImage2D is definately slower than a single glTexImage2D with GL_TEXTURE_RECTANGLE_NV. Since the amount of data transferred is the same I don’t quite see why. The time hit is increased if internal format & type are ‘unfortunate’ and require some munging by the driver.
IMO ‘normal’ mipmapped textures aren’t stored in a strictly linear fashion in video memory. They are swizzled to achieve better bandwidth efficiency for “typical” sampling patterns (and to increase cache locality).
OTOH rectangle textures would be stored in video memory unswizzled.

If that’s true, then rectangle texture updates are easier to do = faster.

This leads me to the following speculation: Could it be that even though we use glTexSubImage2D the chunk of memory processed & sent to the card is actually the size allocated with glTexImage2D. It certainly looks that way comparing the performance numbers.
It will have to at least once transfer the whole allocated texture size. Even if you TexImage2D(<…>,NULL);, the ‘empty’ regions of the texture must be set to black at some point. This is required behaviour.

The most optimum point in time would be the first TexSubImage2D call after a TexImage2D(<…>,NULL). If the driver keeps doing this after the first TexSubImage2D (if the texture hasn’t been NULLed again in the meantime), it needs further optimization.

i think it’s about time to ARB create it’s ownd rectangle texture extension since it’s an important resource to use in especial effects like motion blur, image space glow, and other special effects that copy the contents of the frame buffer to a texture since using a non-power-of-2 texture represnts in some cases a big waste of the graphic card’s memory.

using different extension for each card (nvidia, ati) to work with such a basic thing like rectangle textures is just ridiculous.

[This message has been edited by jcabeleira (edited 02-18-2004).]

Originally posted by jcabeleira:
i think it’s about time to ARB create it’s ownd rectangle texture extension
It’s here since some months ago. Do someone heard of ARB_non_power_of_two? It’s simply much better than NV/EXT_rect
Originally posted by jcabeleira:
using different extension for each card (nvidia, ati) to work with such a basic thing like rectangle textures is just ridiculous.

It’s not card-specific. I’ve seen an ATi card displaying support for NV_rect and EXT_rect (which are the same extension anyway). Some time ago this was discussed on beginner’s forum, you should check out that thread.

EDIT: broken UBB tags. Fixed.

[This message has been edited by Obli (edited 02-18-2004).]

Hi,
The ARB_non_power_of_two is indeed much better, if you have drivers to support it. I asked the question on the drivers in the begginers’ forum, but got no answer. Maybe the new ForceWare 55.xx do support it?

Just saw a report on Delphi3D, with a Quadro1000 with 56.54 drivers, and it doens’t seem to support ARB_npotd…
But they claim OpenGL 1.5, and AFAIK 1.5 should have the ARB_npotd!

[This message has been edited by Tzupy (edited 02-19-2004).]

I doubt the ARB non power of two extension is supported on any curently shipping hardware (maybe some workstation cards, but I doubt it).

does anyone know for sure if there’s already any hardware supporting the ARB non power of two extension? or is this just a driver issue?

But they claim OpenGL 1.5, and AFAIK 1.5 should have the ARB_npotd!

No, the non-power-of-two extension is not a part of 1.5 core. There’s a good reason for this; they actually want people to have 1.5 implementations.

No modern consumer hardware can handle npot textures, in the way that the ARB_npotd extension wants them to, that is. This may change with later hardware (R420, or NV40), but for the time being, all we have are the texture_rectangle extensions.