Difference between MAX_LEVEL and MAX_LOD

I’m wondering what is the actual difference between these two code snippets:


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, LODBias);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (mipmapsNum == 0 ? 1000 : mipmapsNum - 1));

and


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, LODBias);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, (mipmapsNum == 0 ? 1000 : mipmapsNum - 1));

Visually, they both do the same. If there are two distinc constans for one purpose, what is the difference then?

Thanks, I learned something !
I guess from the wording of the man page, that the *_LEVEL pair serves to define which levels are defined, and serve to define if texture is complete or not. So you says “ok I only bothered to define levels 2 to 8, use only that and don’t white out the texture”

The *_LOD is for the visual effect for defining dynamically a (typically smaller) range for ie. blurring purposes.

FWIW, I imagine if I were doing the hardware, that changing the *_LOD would be faster/better optimized than changing the *_LEVEL values, but someone with better insight can shed more light on this.

So the LEVEL functions determine which mipmaps should be loaded into the GPU? This way if I set, for instance, only the first mipmap by setting these values to 0 and 1, then a texture in GPU takes only it’s own memory and doesn’t require any more memory for it’s mipmaps.
On the other hand LOD functions would simply define which od the already loaded mipmaps should be used.
If my assumptions are true, then LEVEL functions are slower is change (as you mentioned ZbufferR) since they might require generation of mipmaps and storing them in GPU, whereas LOD functions are fast in use since they work on the already-loaded mipmaps.

btw: the funniest thing is that in OGL I can set this mipmaps interval in these two versions we’re condiering, whereas in D3D9 I can’t find any way to set maximal used mipmap level! Or maybe somebody knows?

So the LEVEL functions determine which mipmaps should be loaded into the GPU? This way if I set, for instance, only the first mipmap by setting these values to 0 and 1, then a texture in GPU takes only it’s own memory and doesn’t require any more memory for it’s mipmaps.

No. The GPU will load what you give it. So even if you set the max level to be 1, you can still use glTexImage* to upload to mipmap 2, and the GPU will dutifully store that mipmap.

What BASE_LEVEL and MAX_LEVEL do is ensure that nothing can sample from mipmaps outside of this range. The MAX/MIN_LOD parameters do not ensure this. This gives you the freedom to not upload anything with glTexImage calls for mipmaps outside of that range. But setting these values will not affect what actually is in GPU memory.

Okay, so I can still use glTexImage. And what about automatic mipmap generation on hardware? By default, all mipmaps are generated. Does any of these functions can force GPU to generate only a specific range of mipmaps?

Interesting thread. Didn’t even know about MIN/MAX_LOD.

Ok, so trying to gel what you said, I find this pseudocode in the ARB_texture_query_lod spec as the algorithm for applying MIN/MAX_LOD:


      float ComputeAccessedLod(float computedLod)
      {
        // Clamp the computed LOD according to the texture LOD clamps.
        if (computedLod < TEXTURE_MIN_LOD) computedLod = TEXTURE_MIN_LOD;
        if (computedLod > TEXTURE_MAX_LOD) computedLod = TEXTURE_MAX_LOD;

        // Clamp the computed LOD to the range of accessible levels.
        if (computedLod < 0)
            computedLod = 0.0;
        if (computedLod > (float)
            maxAccessibleLevel) computedLod = (float) maxAccessibleLevel;

        // Return a value according to the min filter.
        if (TEXTURE_MIN_FILTER is LINEAR or NEAREST) {
          return 0.0;
        } else if (TEXTURE_MIN_FILTER is NEAREST_MIPMAP_NEAREST
                   or LINEAR_MIPMAP_NEAREST) {
          return ceil(computedLod + 0.5) - 1.0;
        } else {
          return computedLod;
        }
      }

Spec sifting and browsing SGIS_texture_lod, I’m unclear but thinking maybe that that 2nd set of ifs should actually be the BASE_LEVEL/MAX_LEVEL clamp (?).

And similarly for the MIN_FILTER = LINEAR/NEAREST case, that should be “return BASE_LEVEL”, not “return 0.0”.

If so, then MIN/MAX_LOD and BASE/MAX_LEVEL are just clamps applied sequentially, but BASE/MAX_LEVEL gets the last word. And significantly, BASE/MAX_LEVEL must be non-negative whereas that’s not the case for MIN/MAX_LOD.

Is this right?

If so, then I’m not getting the point for MIN/MAX_LOD… When could you not get what you want from BASE/MAX_LEVEL alone?

Hm, I guess that LODs, since they can be negative, allows to set greater level of detail such that greater mipmaps can still be seen in further distance. However, there is also a state of glTexEnv called GL_TEXTURE_LOD_BIAS that can alse be used to set such option.
So maybe these MIN/MAX LODs simply bound GL_TEXTURE_LOD_BIAS to specified values?

According to the spec, min max lod clamps the lod after the texture lod bias have been applied.