【问题标题】:Is glTexStorage2D imperative when auto generating mipmaps自动生成 mipmap 时 glTexStorage2D 是否必要
【发布时间】:2013-03-14 09:49:26
【问题描述】:

我确实使用 gltexSubImage2D() 更新到 OpenGL 4.0 中的纹理 2D。纹理具有使用自动生成的 mipmaps

 glGenerateMipmap(GL_TEXTURE_2D); 

我的纹理更新失败,直到我明白我也必须在更新时重新生成 mipmap(或删除 mipmap 生成)。然后我阅读了this wiki,其中在生成 mipmap 时使用了glTexStorage2D。我实际上从未付费注意这个方法。所以我想知道我每次用mipmaps生成纹理时都必须使用它吗?

更新:

我从方法规范中看到它

指定所有级别的存储要求 一个二维纹理或一维纹理数组同时处理

我猜使用它应该可以提高生成 mipmap 时的性能?是真的吗?

【问题讨论】:

    标签: opengl opengl-4


    【解决方案1】:

    这两个函数是完全正交的。

    glTexImage2DglTexStorage2D 之间进行选择。这两个allocate storage for texture images;他们只是以不同的方式做到这一点。

    glTexImage2D 是分配存储的旧方式。它creates mutable storage (there are other functions that create mutable storage too)。如果您想要 mipmap,则必须通过单独调用函数来分配每个 mipmap 级别,手动计算 mipmap 图像的大小(请参阅下面的例外情况)。

    glTexStorage2D 分配immutable storage for the image data。它一次性分配所有你想要的 mipmap。

    不可变存储,顾名思义,无法更改。看,您可以在相同的 mipmap 级别上调用 glTexImage2D,但大小不同。如果你这样做了,OpenGL 将破坏原来的 mipmap 层并为新的层分配存储空间。您甚至可以更改格式。

    不可变存储不会让您更改任何内容。你可以upload new data, using functions like glTexSubImage2D。但是这些功能不会改变 storage;他们改变了内容。

    glTexImage2DglTexStorage2D 类似于 mallocglTexSubImage2D 就像 memcpy;它仅适用于现有内存。

    glGenerateMipmap 是一个函数,它将获取纹理的基础层和generate the data for all of the mipmaps from that base layer (given the mipmap range)。它只做一次。把它想象成一个渲染函数;它完成了它的工作,然后就完成了。

    对于可变存储纹理,glGenerateMipmap 还将为先前未分配的 mipmap 范围内的任何 mipmap 分配存储。这就是为什么您可以调用glTexImage2D 一次,然后调用glGenerateMipmap 来强制它制作所有其他mipmap,而无需手动进行。

    【讨论】:

    • 好的,现在它让我明白了很多。但是因为 Datenwolf 的分数较少,所以我将他标记为正确答案 ;)
    【解决方案2】:

    在 glTexStorage 出现之前,每个 mipmap 级别都必须通过单独调用 glTexImage 来初始化。 glTexImage 会触发很多复杂的内部状态变化,这些变化是相当昂贵的。每次调用 glTexImage 时,纹理对象的布局都会改变。

    因此,如果可能,请尽量避免使用它。正如您所发现的,您必须先初始化所有所需的 mipmap 级别,然后才能通过 glTexSubImage 更新它们。 glGenerateMipmap 将创建它们,这会引入布局更改,是的,很昂贵。

    glTexStorage 将整个纹理对象初始化一次,以获得所需的不可变格式。是的,当与 glGenerateMipmap 或 glTexSubImage 的数据更新一起使用时,使用 glTexStorage 可以提高性能,但是这些改进发生在纹理对象创建的早期,而不是在其数据更改时。

    【讨论】:

    • 好的,但这是否意味着,如果我使用 glTexStorage ,我每次更新纹理时都不需要调用 glGenerateMipmap ?
    • @MichaelIV:“这两个函数是完全正交的。”
    • @MichaelIV:Nicol Bolas 的意思是,它们不能相互替代。
    • 我知道如果我对不可变 mipmap 没有任何问题,那么我应该使用 glTexStorage。此外,如果您查看我提供的“常见错误”链接,您可以在纹理创建演示中看到 glTexStorage 是用过,作者直接用gltexsubimage。为什么?另外,我不明白,为什么我在更新纹理时必须再次重新生成 mipmap。
    • @MichaelIV:看,你不明白:不可变的格式布局并不意味着不可变的数据。 glTexStorage 使不可变的是纹理的格式布局,即它的尺寸、内部数据类型和格式以及 mipmap 级别的范围。但数据本身可以随时更改(变异)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多