PDA

View Full Version : MipMaps



devdept
08-21-2007, 06:22 AM
Hi All,

I am trying to avoid to call the gluBuild2DMipmaps() because is VERY SLOW. Don't want even to call a specific glu 1.3 func missing on many machines (gluBuild2DMipmapLevels).

The question is: if I generate mipmaps manually like in the RedBook samples mipmaps.c can I stop the process earlier to go faster.

For example: if I have a texture of 1024x1024, can I make only 2 mipmaps levels to generate 512x512 and 256x256 mipmaps instead of going to 1x1?

Is this a good approach? Will I save time?

Thanks a lot,

Alberto

Roderic (Ingenu)
08-21-2007, 06:56 AM
Not a good option, better store the mipmaps in the file, or generate ALL levels (with your own function or GLU), hardware is likely to need more than only the first few levels, especially if you use anisotropic filtering.

I remember someone (think it was Humus) said the hardware prefered to have all levels, even the 1x1 one...

devdept
08-21-2007, 07:17 AM
Roderic,

So there is no way to go faster generating mipmaps than gluBuild2DMipmaps?

The only way is to provide square textures and with dimension power of two? We noticed that gluBuild2DMipmaps go faster if it is like this.

Mmm... in my opinion we are missing something...


Thanks,

Alberto

Jan
08-21-2007, 07:40 AM
If you textures are not power-of-two, gluBuild2DMipmaps will rescale them to be power-of-two, that's why it is slower.

Storing all mipmap-levels on disk (dds-file-format) can give you huge speed-ups, especially when they are additionally precompressed, so that you can read and upload them without any further processing (and need to read fewer data, since they are compressed).

Other than that, maybe automatic mipmap generation is faster than gluBuild2DMipmaps, but i am not sure about that.

Generating less mipmaps is possible, you can tell the driver, that it should only use mipmap-levels 0 to n, then n+1 ... don't need to be present. But this is a fragile feature, i would not depend on drivers implementing it correctly. And as mentioned above, some hardware might not like it that much, if some levels are missing.

Jan.

devdept
08-21-2007, 07:49 AM
Jan,

>> Other than that, maybe automatic mipmap generation is faster than gluBuild2DMipmaps, but i am not sure about that.

What do you mena with "automatic mipmap generation"?

Thanks,

Alberto

ebray99
08-21-2007, 08:22 AM
I personally either use the automatic mipmap generation (seems to do a good enough job), or I generate mipmaps myself using the most basic of all methods... the box filter =). I find that generating mipmaps after loading the base image is actually quite a bit faster than storing them in a file (at least on the machines I've tried it on). Image quality is the best argument for storing mipmaps on disk, simply because you can use much more sophisticated filters than the box filter.

Automatic mipmap generation can be done with GL_SGIS_generate_mipmap (very widely supported at this point).

Kevin B

devdept
08-21-2007, 08:59 AM
Kevin,


GL_SGIS_GENERATE_MIPMAP

I find it on my Graphics Card,

Can you provide a small c/c++ sample of the usage? So I can test performances?


Thanks,

Alberto

Jan
08-21-2007, 09:45 AM
Get used to take a look into the extension registry:
http://opengl.org/registry/

The specification is here:
http://opengl.org/registry/specs/SGIS/generate_mipmap.txt

And google is your friend :)

Actually for this extension it is very simple. Here is a snippet of my code:

if (GLEW_SGIS_generate_mipmap)
{
glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, true);
glTexImage2D (GL_TEXTURE_2D, 0, iInternalFormat, tex->m_iSizeX, tex->m_iSizeY, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*) tex->mp_ucTexture);
glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, false);
}
else
{
gluBuild2DMipmaps (GL_TEXTURE_2D, iInternalFormat, tex->m_iSizeX, tex->m_iSizeY, GL_BGRA, GL_UNSIGNED_BYTE, (void*) tex->mp_ucTexture);
}


Jan.

Nighthawk
08-21-2007, 09:45 AM
Hi,

just found what you are looking for in my code;-)

//enable automatic mipmap generation:
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, true);

// enable mipmaping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

// upload texture
glTexImage2D(...)

Hope this helps...

Martin

Korval
08-21-2007, 10:32 AM
There is also an extension function (found in, of all places, the FBO spec) that allows you to tell the hardware to generate mipmaps. It's called, "glGenerateMipmapEXT", which will generate mipmaps from the currently bound texture.

The problem with gluBuild3DMipmaps is that it's all CPU work. glGenerateMipmapEXT allows the hardware to do the filtering. It's also nicer than the SGIS extension, since that extension will build mipmaps anytime the texture changes, whereas glGenerateMipmapEXT does it only when you ask for it.

Humus
08-21-2007, 11:11 AM
Originally posted by devdept:
Is this a good approach? Will I save time?No. After generating just two mipmaps you've already done 94% of all processing, so stopping at that point just saves the last 6%. I would recommend you to always generate all mipmaps. There's no little to no gain worrying about the mipmaps. Even if you removed all mipmaps and just saved the base level you still only save 25%.

devdept
08-21-2007, 01:28 PM
Thanks a lot to you all.

I will try first GL_GENERATE_MIPMAP_SGIS and then glGenerateMipmapEXT and let you know.

Alberto

devdept
08-23-2007, 06:16 AM
Hi Jan,


I tried your code but after creating mipmaps with the GL_GENERATE_MIPMAP_SGIS I don't see them in action...Why?

If I disable them and use gluBuild2DMipmaps everything work perfectly.

The loading time difference is 0.025 sec with in house reascaling & resquaring & GL_GENERATE_MIPMAP_SGIS while 0.250 sec with the gluBuild2DMipmaps, that is very good.

Now I need only to fix the issue above. Of course I tried to call gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);

before and after.

Thanks,

Alberto

ZbuffeR
08-23-2007, 06:32 AM
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);

devdept
08-23-2007, 06:42 AM
Thanks zBuffer, but I am using the following code and does not work:

gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 1);
gl.TexImage2D (gl.TEXTURE_2D, 0, gl.RGBA, data.Width, data.Height,
0, gl.BGRA, gl.UNSIGNED_BYTE, data.Scan0);
gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 0);

Why?

Alberto

ebray99
08-23-2007, 09:01 AM
change:

gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 0);

to

gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 1);

=)
Kevin B

ZbuffeR
08-23-2007, 09:08 AM
Surprising.
Not sure what programming language you use but did you try :
gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, gl.TRUE);

and remove the gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 0);

From the extension spec :


If GENERATE_MIPMAP_SGIS is enabled, the side effect occurs whenever
any change is made to the interior or edge image values of the base
level texture array. The side effect is computation of a complete
set of mipmap arrays, all derived from the modified base level array.
Array levels BASE+1 through BASE+p are replaced with derived arrays,
regardless of their previous contents. All other texture arrays,
including the base array, are left unchanged by this mipmap computation.Maybe at another place you change the texture ?

I don't see them in action...Why?
You mean only the base level is here, and when the texture becomes too small on screen it turns white ?
I never had problems with this auto texture generation.
Did you try with GL_NEAREST_MIPMAP_NEAREST to better see the mipmap 'jump' ?

Jan
08-23-2007, 10:22 AM
Well, my code-snippet, that you used, does enable automatic-texture generation, then uploads the texture and then disables automatic-texture generation, to make sure, that the driver does not need to keep track of any changes, since there won't be any.

This works for me, i use this code for several years now and i never had any issues neither on ATI nor NV hardware.

As mentioned above, try without the additional disabling of mipmap generation. However, i am a bit surprised and i cannot see any errors in your posted code snippet.


Of course, if you DO change the texture later on, you DO need to have mipmap generation left ON. I only disable it, because i KNOW that after loading the textures once, they won't change anymore.


Jan.

devdept
08-23-2007, 01:45 PM
Yes Guys,


Removing the

gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 0);

solves the problem and everything works fine. My Hardware is ATI FireGL 7200.


if (Viewport.OpenglExtensions.Contains("GL_SGIS_generate_mipmap"))
{

MakeSquareAndPowerOfTwo(ref bitmap);

gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 1);
gl.TexImage2D (gl.TEXTURE_2D, 0, gl.RGBA, data.Width, data.Height,
0, gl.BGRA, gl.UNSIGNED_BYTE, data.Scan0);
// gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 0);

}
else
{

glu.Build2DMipmaps(gl.TEXTURE_2D, gl.RGBA,
data.Width, data.Height,
gl.BGRA, gl.UNSIGNED_BYTE,
data.Scan0);
}This code is called every time a texture is loaded. Should I call the gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP_SGIS, 1); every time or I can place it at the beginning of the program? What happens if the extension is not available? Our textures are loaded once, there is no need to change them at runtime.


Thanks again,

Alberto

ZbuffeR
08-23-2007, 02:02 PM
1) this is a gltexparameter, so put it with the others, like texture filters etc.
2) you should always test for the extension presence, but this one is very largely supported :
http://www.delphi3d.net/hardware/extsupport.php?extension=GL_SGIS_generate_mipmap

Eosie
08-23-2007, 05:04 PM
Originally posted by Korval:
There is also an extension function (found in, of all places, the FBO spec) that allows you to tell the hardware to generate mipmaps. It's called, "glGenerateMipmapEXT", which will generate mipmaps from the currently bound texture.I tried it a few months ago. I called glGenerateMipmapEXT right after glTexImage2D or glCompressedTexImage2D (not sure about it now) and the texture was damaged (not entirely but some random parts were). The spec says it is allowed but as we see... I have legacy ATI driver on WinXP (because there isn't their new one). So I must stick with automatic mipmap generation, which works well.

Jan
08-24-2007, 04:11 AM
Yes, i had similar problems. When i tried glGenerateMipmap on an early ATI implementation, it crashed. But i'm sure recent drivers should handle it just fine.

Jan.

Yandersen
12-13-2010, 08:44 PM
--------------------
Q: does ORDER of mipmap' levels uploding (using glTexImage2D) matter? I mean, is it legal to start upload mipmaps from smallest (level n) to largest (base, level 0)? Everywhere I have seen only standard approach - from base image to 1x1. What about reverse, or even mixed order of uploading?
I have a complete set of required mipmaps in file (don't ask what format is it :) ), from level 0 to level n, howether, in file each image stored individually, and levels may be mixed up (however, each image has header, containing correct info about it's level). I really do not want to seek through the file collecting mipmaps in order {0-1-2-...n} - I just want to read-and-load mipmaps in whatever sequence they stored. Loading such images in reverse order (1x1, 2x2, 4x4, ...) on my configuration did not caused problems - texture works just fine. Howether, I want to be sure that such approach is legal and will work on all implementations. In official specs I didn't found any solid declaration about order of mipmap loading - all it states that mipmaps' set must be complete, have correct dimensions and so on - all this is guaranteed. But what about ORDER of loading those mipmaps?