OpenGL4.5 - 绑定多个纹理和采样器

Car*_*ero 11 c++ opengl textures texture-mapping opengl-4

在此输入图像描述

我正在尝试理解OpenGL 4.5中的纹理,纹理单元和采样器.我附上了一张我想弄清楚的图片.我认为在我的例子中一切都是正确的,但我不太确定右侧带有问号的1D采样器.

所以,我知道OpenGL提供了许多纹理单元/绑定点,纹理和采样器可以绑定在一起,因此它们可以协同工作.

这些绑定点中的每一个都可以支持每个纹理目标中的一个(在我的情况下,我是绑定目标GL_TEXTURE_2DGL_TEXTURE_1D绑定点0,另一个GL_TEXTURE_2D绑定到绑定点1).

另外,采样器可以以相同的方式绑定到这些绑定点(我已经将2D采样器绑定0到pic中的绑定点).

执行这些操作的功能是glBindTextureUnitglBindSampler.

我最初的想法是将1D采样器绑定到绑定点0,并且在着色器中根据绑定点和采样器的类型进行匹配:

layout (binding = 0) uniform sampler1D tex1D;
layout (binding = 0) uniform sampler2D tex2D;
Run Code Online (Sandbox Code Playgroud)

引用来源:

每个纹理图像单元都支持绑定到所有目标.因此,2D纹理和阵列纹理可以绑定到同一图像单元,或者不同的2D纹理可以绑定在两个不同的图像单元中而不会相互影响.那么在渲染时会使用哪种纹理?在GLSL中,这取决于使用此纹理图像单元的采样器的类型.

但我发现了以下声明:

[..]听起来很可疑,就像你可以为不同的采样器使用相同的纹理图像单元,只要它们具有不同的纹理类型.不要这样做.该规范明确禁止它; 如果两个不同的GLSL采样器具有不同的纹理类型,但是与相同的纹理图像单元相关联,则渲染将失败.为每个采样器提供不同的纹理图像单元.

所以,我的问题是,如果最终单个采样器将被绑定到该绑定点,强制您选择,那么将不同纹理目标绑定到同一个绑定点的目的是什么?

我引用的信息:https://www.khronos.org/opengl/wiki/Texture#Texture_image_units

Nic*_*las 9

那为什么会存在呢?好...

曾几何时,没有纹理单元(这就是为什么glActiveTexture单独的功能glBindTexture).实际上,OpenGL 1.0中甚至没有纹理对象.但仍然需要不同种类的纹理.您仍然需要能够为2D纹理和3D纹理创建数据.因此,他们提出了纹理目标的区别,他们使用glEnables来确定在渲染操作中使用哪个目标.

当纹理对象在GL 1.1中出现时,他们必须决定纹理对象和目标之间的关系.他们决定,一旦一个物体被绑定到一个目标,它就会永久地与该目标相关联.由于上述需要具有不同类型的多个纹理,使用旧的启用功能,因此决定每个目标表示单独的对象绑定点.并且他们让你重复绑定点glBindTexture,这样对于代码的读者来说,哪个绑定点的数据令你不安.

当多重纹理问世时,切入OpenGL 1.2.所以现在他们需要你能够绑定同一目标的多个纹理,但需要绑定到不同的"单位".但他们无法改变glBindTexture以指定一个特定的单位; 这将是一个向后不兼容的变化.

现在,他们可以彻底改变纹理的工作方式,创建一个专门用于多纹理等的新绑定功能.但是OpenGL ARB喜欢向后兼容; 他们喜欢使旧的API函数工作,无论生成的API是什么样的.因此,他们决定纹理单元将是一整套绑定,每个集合都有一个启用状态,说明哪个目标是要使用的目标.你在单位之间切换glActiveTexture.

当然,一旦着色器出现,你可以看到这一切都发生了变化.启用状态成为着色器中的采样器类型.所以现在没有明确的代码描述启用了哪个纹理目标; 它只是着色器的东西.因此,他们必须制定一条规则,即如果两个采样器的类型不同,则不能使用相同的单元.

这就是为什么每个纹理单元都有多个独立的绑定点:OpenGL对向后兼容性的承诺.

最好忽略此功能存在.绑定特定着色器所需的正确纹理.因此,请专注于使用这些功能,并且不要担心可能有两个纹理绑定到同一目标.如果要确保不会意外使用错误的纹理,可以使用glBindTexturesglBindTextureUnit使用纹理名称0,这将取消绑定特定纹理单元中的所有目标.

  • @Ripi2:从字面上看,标题的第一个词是“OpenGL4.5”。很明显,OP 正在询问 OpenGL 4.5 版,因此无需提供 3.3 版替代方案。此外,该问题被标记为“opengl-4”,因此 3.3 在这里没有任何意义。 (2认同)