Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many mipmaps does a texture have in OpenGL

Tags:

Nevermind that I'm the one who created the texture in the first place and I should know perfectly well how many mipmaps I loaded/generated for it. I'm doing this for a unit test. There doesn't seem to be a glGetTexParameter parameter to find this out. The closest I've come is something like this:

int max_level;
glGetTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &max_level );
int max_mipmap = -1;
for ( int i = 0; i < max_level; ++i )
{
    int width;
    glGetTexLevelParameter( GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &width );
    if ( 0 == width )
    {
        max_mipmap = i-1;
        break;
    }
)

Anyhow, glGetTexLevelParameter() will return 0 width for a nonexistent mipmap if I'm using an NVidia GPU, but with Mesa, it returns GL_INVALID_VALUE, which leads me to believe that this is very much the Wrong Thing To Do.

How do I find out which mipmap levels I've populated a texture with?

like image 703
Ted Middleton Avatar asked Mar 05 '12 19:03

Ted Middleton


People also ask

What are mipmaps in textures?

A mipmap is a sequence of textures, each of which is a progressively lower resolution representation of the same image. The height and width of each image, or level, in the mipmap is a power of two smaller than the previous level.

What is mipmaps in OpenGL?

Mipmaps are smaller, pre-filtered versions of a texture image, representing different levels of detail (LOD) of the texture. They are often stored in sequences of progressively smaller textures called mipmap chains with each level half as small as the previous one.

What is a texture unit OpenGL?

Texture units are references to texture objects that can be sampled in a shader. Textures are bound to texture units using the glBindTexture function you've used before. Because you didn't explicitly specify which texture unit to use, the texture was bound to GL_TEXTURE0 .

How do you show textures in OpenGL?

in display() function : GLuint texture; texture = LoadTexture("bubble. png"); glBindTexture(GL_TEXTURE_2D, texture);


2 Answers

The spec is kinda fuzzy on this. It says that you will get GL_INVALID_VALUE if the level parameter is "larger than the maximum allowable level-of-detail". Exactly how this is defined is not stated.

The documentation for the function clears it up a bit, saying that it is the maximum possible number of LODs for the largest possible texture (GL_MAX_TEXTURE_SIZE). Other similar functions like the glFramebufferTexture family explicitly state this as the limit for GL_INVALID_VALUE. So I would expect that.

Therefore, Mesa has a bug. However, you could work around this by assuming that either 0 or a GL_INVALID_VALUE error means you've walked off the end of the mipmap array.

That being said, I would suggest employing glTexStorage and never having to even ask the question again. This will forcibly prevent someone from setting MAX_LEVEL to a value that's too large. It's pretty new, from GL 4.2, but it's implemented (or will be very soon) across all non-Intel hardware that's still being supported.

like image 138
Nicol Bolas Avatar answered Sep 25 '22 13:09

Nicol Bolas


It looks like there is currently no way to query how many mipmap levels a texture has, short of the OPs trial/error with @NicolBolas' invalid value check. For most cases I guess its performance wouldn't matter if the level 0 size doesn't change often.

However, assuming the texture does not have a limited number of levels, the specs give the preferred calculation (note the use of floor, and not ceiling as some examples give):

numLevels = 1 + floor(log2(max(w, h, d)))
  1. What is the dimension reduction rule for each successively smaller mipmap level?

    Each successively smaller mipmap level is half the size of the previous level, but if this half value is a fractional value, you should round down to the next largest integer.
    ...
    Note that this extension is compatible with supporting other rules because it merely relaxes the error and completeness conditions for mipmaps. At the same time, it makes sense to provide developers a single consistent rule since developers are unlikely to want to generate mipmaps for different rules unnecessarily. One reasonable rule is sufficient and preferable, and the "floor" convention is the best choice.

    [ARB_texture_non_power_of_two]

This can of course be verified with the OPs method, or in my case when I received a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT with glFramebufferTexture2D(..., numLevels).

like image 21
jozxyqk Avatar answered Sep 25 '22 13:09

jozxyqk