2013-03-14 568 views
4

我在OpenGL 4.0使用gltexSubImage2D()做更新一个Texture2D,纹理有使用是glTexStorage2D必要时自动生成的贴图

glGenerateMipmap(GL_TEXTURE_2D); 

我的纹理更新是失败,直到我明白我必须重新生成的mipmap汽车(或删除mipmaps世代)。然后我读this维基在生成mipmaps时有glTexStorage2D的用法。实际上我从未注意过这个方法。所以我想知道每次生成时都必须使用它吗?纹理与mipmap?

更新:

我从方法规范,它

指定二维纹理或同时一维纹理阵列

各级 的存储要求看

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

回答

7

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

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

glTexStorage为所需的不可变格式初始化整个纹理对象一次。是的,使用glTexStorage可以在兼容glGenrateMipmap或通过glTexSubImage进行数据更新时提高性能,但是在创建纹理对象时很快就会发生改进,而在改变数据时则不会发生。

+0

好吧,但这是否意味着,如果我使用glTexStorage,每次更新纹理时都不需要调用glGenerateMipmap? – 2013-03-14 11:01:36

+0

@MichaelIV:“这两个函数是完全正交的。” – 2013-03-14 11:08:41

+0

@MichaelIV:尼科波拉斯的意思是,他们不能相互取代。 – datenwolf 2013-03-14 13:20:32

22

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

选择范围在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。但这些功能不会更改存储;他们改变内容。

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无需手动执行。

+0

好吧,现在它澄清了我很多。但是因为Datenwolf少了点,所以我把他标记为正确答案;) – 2013-03-14 19:28:34