我使用gltexSubImage2D()更新到OpenGL 4.0中的texture2D。纹理具有使用
自动生成的mipmaps glGenerateMipmap(GL_TEXTURE_2D);
我的纹理更新失败,直到我明白我必须在更新时重新生成mipmaps(或删除mipmaps生成)。然后我读了这个wiki,在生成地图时使用了glTexStorage2D。其实我从来没有注意过这个方法。所以我想知道我是否必须使用它每次我生成一个纹理与mipmaps?
更新:我从方法规范中看到它
指定了所有级别的存储要求二维纹理或一维纹理数组的同时
我猜使用它应该提高性能时,生成地图?这是真的吗?
两个函数是完全正交的
在glTexImage2D
和glTexStorage2D
之间进行选择。这两种方法都为纹理图像分配存储空间;他们只是用不同的方式。
glTexImage2D
是旧的存储分配方式。它创建可变存储(也有其他函数创建可变存储)。如果你想要mipmap,你必须通过一个单独的函数调用来分配每个mipmap级别,手动计算mipmap图像的大小(见下面的例外情况)。
glTexStorage2D
为映像数据分配不可变存储。它会一次性分配你想要的所有mipmap。
不可变存储,顾名思义,是不能更改的。看,您可以在相同的mipmap级别上调用glTexImage2D
,但大小不同。如果你这样做,OpenGL将销毁原来的mipmap级别并为新的mipmap级别分配存储。你甚至可以改变格式。
不可变存储不允许你改变这些。您可以使用glTexSubImage2D
等函数上传新数据。但是这些函数不会改变存储;他们改变了内容。
glTexImage2D
和glTexStorage2D
与malloc
相似。glTexSubImage2D
类似于memcpy
;它只适用于现有的内存。
glGenerateMipmap
是一个函数,它将获取纹理的基础层并从该基础层生成所有mipmap的数据(给定mipmap范围)。它只执行一次。把它想象成一个渲染函数;它完成了它的工作,然后就完成了。
对于可变存储纹理,glGenerateMipmap
还将为mipmap范围内的任何先前未分配的mipmap分配存储空间。这就是为什么您可以调用一次glTexImage2D
,然后调用glGenerateMipmap
来强制它制作所有其他的mipmap,而不必手动执行。
在有glTexStorage之前,每个mipmap级别必须通过对glTexImage的单独调用来初始化。glTexImage触发了许多复杂的内部状态变化,这是相当昂贵的。每次调用glTexImage时,纹理对象的布局都会被改变。
因此,如果可能的话,尽量避免使用。正如您所发现的,您必须首先初始化所有所需的mipmap级别,然后才能通过glTexSubImage更新它们。glGenerateMipmap会创建它们,它们会引入布局变化,这是,是的,昂贵的。
glTexStorage为所需的不可变格式初始化整个纹理对象一次。是的,当glTexStorage与glGenerateMipmap或glTexSubImage的数据更新一起使用时,使用glTexStorage可以提高性能,但改进发生在纹理对象创建的早期,而不是在其数据更改时。