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?
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…
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.
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).
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.
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%.
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);
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’ ?
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.
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.