glTexStorage做什么?

时间:2012-02-10 07:35:45

标签: opengl

documentation表示这会为纹理及其级别“分配”存储空间。提供的伪代码似乎表明这是针对mipmap级别的。

glTexStorage的使用与glGenerateMipmap的关系如何? glTexStorage似乎“锁定”纹理的存储大小。在我看来,这只会使事情变得不那么灵活。是否意味着要在这里获得性能提升?

这是非常新的,只能在4.2中使用,所以我会尽量避免使用它,但我很困惑,因为它的描述使它听起来很重要。

如何在早期GL版本中管理纹理存储?当我调用glTexImage2D时,我有效地擦除并释放先前与纹理句柄关联的存储空,是吗?并且生成mipmap也会自动为我处理存储空间。

我记得使用旧式glTexSubImage2D方法实现OpenGL 2样式渲染到纹理,以便在我之前的引擎实验中执行一些后期处理效果。因为我们有更好的方法来进行RTT,glTexStorage将带来一种更合理的方式来管理与纹理相关的资源,这是有道理的。

2 个答案:

答案 0 :(得分:28)

要了解glTexStorage的作用,您需要了解glTexImage*函数的作用。

glTexImage2D做了三件事:

  1. 它为特定的mipmap图层分配OpenGL存储,具有特定的大小。例如,您可以将64x64 2D图像分配为mipmap level 2.。
  2. 设置mipmap级别的内部格式。
  3. 它将像素数据上传到纹理。最后一步是可选的;如果您将NULL作为指针值传递(并且没有缓冲区对象绑定到GL_PIXEL_UNPACK_BUFFER),则不会发生像素传输。
  4. 手动创建mipmap纹理需要一系列glTexImage次调用,每个mipmap级别一次。 mipmap级别的每个大小都必须是基于先前级别大小的适当大小。

    现在,如果你看一下GL 4.2规范的第3.9.14节,你会看到两页规则,纹理对象必须遵循这些规则才能“完成”。无法访问不完整的纹理对象。

    在这些规则中,“mipmap必须具有适当的大小”。以上面给出的示例为例:一个64x64 2D图像,它是mipmap level 2.它将完全有效的OpenGL代码来分配使用256x256纹理的mipmap level 1。或16x16。或10x345。就源代码而言,所有这些都将是完美的功能。显然,它们会产生无意义的纹理,因为纹理不完整。

    再次考虑64x64 mipmap 2.我将其创建为我的第一张图片。现在,我可以创建一个128x128 mipmap 1.但是我可以 创建一个128x12 9 mipmap 1.这两个都是完全与64x64 mipmap级别2一致的(mipmap大小始终向下舍入)。虽然它们都是一致的,但它们也都是不同的尺寸。如果驱动程序必须立即分配完整的mipmap链(这是完全可能的),它分配的大小是多少?它不知道。直到您明确分配其余部分才能知道。

    这是另一个问题。假设我有一个带有完整mipmap链的纹理。根据规则,它完全是纹理完整的。然后我再次打电话给glTexImage2D。怎么办?我可能会意外更改内部格式。每个mipmap级别都有一个单独的内部格式;如果他们不同意,那么纹理是不完整的。我可能会意外地改变纹理的大小,再次使纹理不完整。

    glTexStorage可以防止所有这些可能的错误。考虑到基本级别的大小,它会创建您想要的所有mipmap。它使用相同的图像格式分配所有这些mipmap,因此你无法搞砸它。它使纹理不可变,所以你不能出现并尝试通过错误的glTexImage2D调用来破坏纹理。并且它可以防止我甚至懒得解决的其他错误。

    问题不在于“glTexStorage做什么?”问题是“为什么我们这么长时间没有它。”

    glTexStorageglGenerateMipmap无关;它们是正交功能。 glTexStorage完全按照它所说的做法:它分配纹理存储空间。它没有用任何东西填充那个空间。因此,它会创建一个给定大小的纹理,并填充未初始化的数据。就像glRenderbufferStorage分配一个填充了未初始化数据的给定大小的渲染缓冲区一样。如果您使用glTexStorage,则需要使用glTexSubImage上传数据(因为glTexImage在不可变纹理上是禁止的。)

    glTexStorage为mipmap创建空间。 glGenerateMipmap自己创建mipmap数据(基础层的较小版本)。如果该空间尚不存在,它还可以为mipmap创建空间。它们用于两种不同的事情。

答案 1 :(得分:2)

在调用glGenerateMipmap之前,必须建立基本mipmap级别。 (使用可变或不可变的存储).so ...,您只能使用glTexImage2D+glGenerateMipmap,更简单!