一个不可变的纹理是否需要GL_TEXTURE_MAX_LEVEL?

3
使用glTexImage*函数分配纹理时,我知道需要将glTexParameteri(GL_TEXTURE_MAX_LEVEL)设置为合理的值,并指定所有级别直到该值,如此处所述。
我没有预料到在使用glTexStorage*函数的情况下也需要这样做,因为它们接受层数作为参数并提前为该层数分配内存。尽管如此,我注意到我不能对这种方式定义的不可变纹理进行采样 - 直到我调用了glGenerateMipmap或将GL_TEXTURE_MAX_LEVEL指定为levels-1
我没有找到任何官方原因说明为什么需要这样做,我希望不可变纹理的参数是不可变的(并且被很好地初始化)。有人能确认这种行为是否正确吗?或者这可能是AMD驱动程序的错误吗?
2个回答

3

好的,我明白了:

glTexStorage函数的参数levels确实存储在纹理对象中,但作为GL_TEXTURE_IMMUTABLE_LEVELS而不是我之前想到的GL_TEXTURE_MAX_LEVEL

因此,参数GL_TEXTURE_MAX_LEVEL仍然保持默认的大值。(可以手动更改:纹理对象的不可变标志只涉及纹理缓冲和其格式,而不涉及缓冲数据或参数。)

根据规范,纹理不可变性应按以下方式影响LOD计算:

如果TEXTURE_IMMUTABLE_FORMAT为TRUE,则levelbase被夹紧在[0;levelimmut-1]范围内。

因此,对于不可变纹理,将GL_TEXTURE_MAX_LEVEL保持不变(= 1000)与将其设置为levels-1具有相同的效果。

结论:驱动程序存在错误;驱动程序显然省略了这个夹紧步骤。


2
我知道需要将glTexParameteri(GL_TEXTURE_MAX_LEVEL)设置为合理的值,并指定所有级别,如此处所述。
但实际上你不必这样做。GL_TEXTURE_MAX_LEVEL的默认值为1000,因此比您实际使用的任何图像金字塔都要大得多。
不过,我注意到如果我不调用glGenerateMipmap或者将GL_TEXTURE_MAX_LEVEL指定为levels-1,则无法对以这种方式定义的不可变纹理进行采样。
是的,这是因为图像存储与图像采样是独立的。GL_TEXTURE_MAX_LEVEL的值是一个参数,它影响采样时的图像访问(您也可以将其设置为采样器对象),这与实际的纹理图像存储无关。您还可以在图像规格说明之后更改所使用的图像金字塔级别范围,如果您想在渲染期间仅选择一部分图像或仅将图像上传到已分配的图像金字塔子集中。

我有点怀疑这一点,但状态表列出了TEXTURE_BASE_LEVELTEXTURE_MAX_LEVEL作为纹理对象状态(而采样器对象状态具有TEXTURE_MIN_LODTEXTURE_MAX_LOD)。你能确认一下吗? - Kos
@Kos:纹理对象也有TEXTURE_MIN_LOD和TEXTURE_MAX_LOD(只需查看OpenGL-2规范,该规范尚未具有采样器对象)。还要记住,虽然使用glTexStorage初始化的纹理图像的大小不能更改,但可以随时更改各个子图像。因此,完全可以替换图像金字塔的一部分,并将基本级别和最大级别设置为实际上传到纹理存储中的图像范围。 - datenwolf
是的,我的观点是GL_TEXTURE_BASE/MAX_LEVEL可能不是采样参数,因为它在采样器对象中不存在,不像LOD参数。 - Kos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接