views:

2169

answers:

6

I need to display 2d images in opengl using textures.
The image dimensions are not necessarily powers of 2.
I thought of creating a larger texture and restricting the display to the part I was using but the image data will be shared with openCV so I don't want to copy data a pixel at a time into a larger texture.

EDIT - it turns out that even the simplest Intel on board graphics under Windows supports none-power-of-2 textures.

EDIT2 - and even if you don't have arb texture size, then making your image smaller and rescaling to the window size it is very fast even on low end hardware

A: 

First of all, most modern videocards actually support texture dimensions that are both non-square and non-power-of-two sized. But for maximum compatibility, using only power of two textures is probably recommended.

Start off by determining the closest power of two that is larger for each of the image dimensions (width and height) and creating a texture of that size. Then you have two options. The first one is to do a software resize of the pixel data to fit the image, and then size your quad according to the original aspect ration when you need to display it. Or, you can just fill part of the texture with your image data and put transparent pixels in the rest.

korona
That's what I was doing but it breaks the data ordering between the texture data and image processing data so involves a lot of expensive copying.
Martin Beckett
+2  A: 

A couple of GL extensions come to mind. Have a look at GL_ARB_texture_rectangle (if you don't need mipmapping), or GL_ARB_texture_non_power_of_two (if you do).

Drew Hall
Thanks. Note to check if this is available do. strstr((const char*)glGetString(GL_EXTENSIONS),"GL_ARB_texture_non_power_of_two")
Martin Beckett
A: 

If you want to use power of 2 textures, create the smallest one that can take up your image, and compute proper texture coordinates to only display the part of the texture containing your image. E.g. if your image is 400x300, you'd use a 512x512 texture, copy your image over there line by line, and your right texture coordinate would be 400.0/512.0, the lower one 300.0/512.0. That will look better than software scaling.

karx11erx
A: 

I do exactly as you describe, copy into a power-of-2 texture and adjust my uv's accordingly. Extensions would be nice, but you're not guaranteed that they are supported on an arbitrary computer.

Jim Buck
The issue is that I want the data to be shared with image processing functions and the repacking would be a pain.
Martin Beckett
+1  A: 

One pitfall to avoid is that for some reason some video cards require GL_UNPACK_ALIGNMENT to be set to 1 ( glPixelStorei(GL_UNPACK_ALIGNMENT, 1); ) for non-power-of-two texture to be loaded correctly.

Kronikarz
+1  A: 

If I can just add for anyone coming across this in the future- most of the documentation and tutorials/examples you find on the web about OpenGL is many years out of date, including the nehe.gamedev stuff, and will lead you to believe that things like non-power-of-two texture sizes are a problem when they realistically aren't, or encourage you to use long-since deprecated opengl functions, or libraries that haven't been updated for a decade.

agard