20

没关系,我是第一个创建纹理的人,我应该非常清楚我为它加载/生成了多少个 mipmap。我这样做是为了进行单元测试。似乎没有glGetTexParameter参数可以找出这一点。我最接近的是这样的:

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;
    }
)

无论如何,glGetTexLevelParameter()如果我使用 NVidia GPU,将为不存在的 mipmap 返回 0 宽度,但使用 Mesa,它会返回GL_INVALID_VALUE,这让我相信这是非常错误的事情

如何找出我填充了纹理的 mipmap 级别?

4

3 回答 3

14

规范对此有点模糊。它表示GL_INVALID_VALUE如果 level 参数“大于最大允许的详细级别”,您将得到。没有说明具体如何定义。

函数的文档稍微澄清了一点,说它是最大可能纹理的最大可能 LOD 数 ( GL_MAX_TEXTURE_SIZE)。其他类似的函数(如glFramebufferTexture家庭)明确将此声明为GL_INVALID_VALUE. 所以我会这样期待。

因此,Mesa 有一个错误。但是,您可以通过假设 0 或GL_INVALID_VALUE错误意味着您已离开 mipmap 数组的末尾来解决此问题。

话虽如此,我建议雇用glTexStorage,甚至不必再问这个问题。这将强制阻止某人将 MAX_LEVEL 设置为太大的值。从 GL 4.2 开始,它是相当新的,但它已在所有仍受支持的非英特尔硬件上实施(或将很快实施)。

于 2012-03-05T19:38:00.720 回答
12

看起来目前没有办法查询纹理有多少个 mipmap 级别,除了 @NicolBolas 的无效值检查的 OP 试验/错误。对于大多数情况,我猜如果 0 级大小不经常变化,它的性能就无关紧要了。

但是,假设纹理的级别数没有限制,规范给出了首选计算(注意使用floor,而不是 ceiling像某些示例给出的那样):

numLevels = 1 + floor(log2(max(w, h, d)))
  1. 每个连续更小的 mipmap 级别的降维规则是什么?

    每个连续更小的 mipmap 级别是前一个级别的一半大小,但如果这个一半的值是小数值,则应该向下舍入到下一个最大整数。
    ...
    请注意,此扩展与支持其他规则兼容,因为它只是放宽了 mipmap 的错误和完整性条件。同时,为开发人员提供单一一致的规则是有意义的,因为开发人员不太可能希望为不同的规则生成不必要的 mipmap。一个合理的规则就足够且可取,而“地板”约定是最佳选择。

    [ARB_texture_non_power_of_two]

这当然可以使用 OPs 方法进行验证,或者在我收到GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENTwith 时glFramebufferTexture2D(..., numLevels)

于 2014-09-03T08:51:27.443 回答
2

假设您以标准方式构建 mipmap,唯一图像的数量将类似于 ceil(log_2(max(width,height)))+1。这可以通过注意到 mipmap 每次将图像大小减小两倍直到只有一个像素来轻松得出。

于 2012-03-24T21:53:23.797 回答