我使用gltexSubImage2D()更新到OpenGL 4.0中的texture2D。纹理使用
自动生成mipmap glGenerateMipmap(GL_TEXTURE_2D);
我的纹理更新失败,直到我理解我还必须在更新时重新生成mipmap(或删除mipmaps生成)。然后我在生成mipmap时阅读了this wiki,其中有glTexStorage2D用法。我实际上从来没有注意过这种方法。所以我想知道每次使用mipmap生成纹理时是否必须使用它?
更新:
我从方法规格中看到它
指定所有级别的存储要求 二维纹理或一维纹理数组的同时
我想在使用它时应该会在生成mipmap时提高性能?这是真的吗?
答案 0 :(得分:23)
这两个函数完全正交。
选择在glTexImage2D
和glTexStorage2D
之间。这两个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级别并为新的mipmap级别分配存储空间。你甚至可以改变格式。
不可变存储不会让您更改任何内容。你可以upload new data, using functions like glTexSubImage2D
。但这些功能不会改变存储;他们改变了内容。
glTexImage2D
和glTexStorage2D
与malloc
类似。 glTexSubImage2D
就像memcpy
;它仅适用于现有的内存。
glGenerateMipmap
是一个将采用纹理基础层和generate the data for all of the mipmaps from that base layer (given the mipmap range)的函数。它这样做一次。把它想象成渲染函数;它完成了它的工作,然后就完成了。
对于可变存储纹理,glGenerateMipmap
还将为mipmap范围中以前未分配的任何mipmap分配存储空间。这就是为什么你可以调用glTexImage2D
一次,然后调用glGenerateMipmap
强制它制作所有其他mipmap而不必手动完成。
答案 1 :(得分:8)
在有glTexStorage之前,每个mipmap级别都必须通过单独调用glTexImage来初始化。 glTexImage触发了许多复杂的内部状态变化,这些变化相当昂贵。每次调用glTexImage时,都会改变纹理对象的布局。
因此,如果可能,请尽量避免使用它。正如您所发现的那样,必须首先初始化所有需要的mipmap级别,然后才能通过glTexSubImage更新它们。 glGenerateMipmap将创建它们,这会引入布局更改,这是非常昂贵的。
glTexStorage初始化整个纹理对象一次,以获得所需的不可变格式。是的,使用glTexStorage可以通过glTneSubImage同时使用glGenerateMipmap或数据更新来提高性能,但是这些改进在纹理对象创建时很早就发生了,而在数据更改时却没有那么多。