PDA

View Full Version : Downsampling a Texture



Spikx
06-04-2010, 02:01 AM
I want to downsample a texture, in my case textures from framebuffer objects, to 1/2 or 1/4 their size or even down to just 1x1. In theory, this should be easy by letting OpenGL trigger mip map generation for the texture, at least that's the info you find everywhere on the subject. However, I could not find specific information on how to implement it and I can't seem to get it to work :(.

What I do is this:

bind the texture
call glGenerateMipmap()

bind an fbo with e.g. a 1x1 sized texture
resize the viewport to 1x1
create an ortho projection with a 1x1 size
render the texture on to a (off-)screen sized quad

The fbo texture should now contain the 1x1 version of the original texture, or not? However, I always only seem to get downsampled versions without interpolation. I.e. in case of the 1x1 texture, only the fragment in the center of the original image. Or in case of the 1/4 sized version, I see flickering.


What am I doing wrong here? What did I misunderstand?


I wanted to implement the HDR/bloom/tonemapping pipeline from here: http://msdn.microsoft.com/en-us/library/ee417769%28v=VS.85%29.aspx
But instead of doing the tedious task of downsampling the texture with multiple passes and custom shaders, I thought that it's more efficient to take advantage of hardware mipmapping?

ZbuffeR
06-04-2010, 02:38 AM
Can't you just do :
bind the texture
call glGenerateMipmap()
glGetTexImage with correct mipmap level ?

There is a workaround here about mipmap generation sometimes not working on ATI, maybe you suffer from something similar ?
http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation

Spikx
06-04-2010, 04:00 AM
Hm... but with glGetTexImage, isn't the texture data actually downloaded from the GPU to the CPU memory? How would I copy a mip map image from one texture directly to another texture object?

// edit: ah, do I have to use pixel buffer objects for that? I thought that these things are extinct since frame buffer objects, but they still seem to have its uses? :)
// hm, even with PBOs, I still don't get how I could directly copy the mip map image to another texture :confused:

ZbuffeR
06-04-2010, 05:15 AM
No you are right, I wrongly assumed you needed the downsampled texture on CPU side.

To verify that indeed mipmaps are wrong, you can check what happens when rendering animated zooms of the texture, with different minifications, skipping extra steps.
By the way, do you actually texture with one of the _MIPMAP_ modes on MIN filter ?

PBO is orthogonal with FBO, both are useful and current. You may confuse with windows pbuffers, which where indeed a cumbersome precursor of FBO.

Spikx
06-04-2010, 05:36 AM
Yes, the textures of the framebuffer objects are created with
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

So my steps of creating a downsampled texture from the mip maps purely on the hardware are correct in theory? i.e.

bind the texture
call glGenerateMipmap()

bind an fbo with e.g. a 1x1 sized texture
resize the viewport to 1x1
create an ortho projection with a 1x1 size
render the texture on to a quad from (0,0) to (1,1)

This FBO should, in theory, hold the correctly downsampled texture, with the image from the mipmap level that holds the 1x1 image of the original texture?

Spikx
06-04-2010, 06:05 AM
glGenerateMipmap() definitely does generate mip maps. If I create the textures with GL_LINEAR_MIPMAP_LINEAR and then do not execute glGenerateMipmap(), the output of the downsized texture is black.

However, with GL_LINEAR_MIPMAP_LINEAR and glGenerateMipmap() enabled, the output still looks like it's not interpolated. I will make a proper test set up later today in my application, to show a checker texture or something like that at various sizes.

ZbuffeR
06-08-2010, 04:36 AM
Any update on this alleged bug ?

mhagain
06-08-2010, 08:12 AM
There's a glHint for mipmap generation (glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST)) that may help you here, but with the caveat that as with any other glHint it's going to be implementation-dependent.

BionicBytes
06-16-2010, 01:45 AM
Having gone through all this pain...you are likely to find that the simple box filter that is mipmapping is going to give you horible results. If your version of Tone mapping is simple then you'll get away with it, if not you'll need custom shaders to ensure your downsampled textures conatin the correct information at every pixel.