OpenGL4.5-绑定多个纹理和采样器 [英] OpenGL4.5 - bind multiple textures and samplers

查看:527
本文介绍了OpenGL4.5-绑定多个纹理和采样器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解OpenGL 4.5中的纹理,纹理单位和采样器.我附上一张我想弄清楚的图片.我认为我的示例中的所有内容都是正确的,但是我不确定带有问号的右侧的一维采样器.

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

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

此外,采样器可以以几乎相同的方式绑定到这些绑定点(我已将2D采样器绑定到图片中的绑定点0).

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

我最初的想法是将一维采样器也绑定到绑定点0,然后在着色器区域中根据绑定点和采样器的类型进行匹配:

layout (binding = 0) uniform sampler1D tex1D;
layout (binding = 0) uniform sampler2D tex2D;

引用来源:

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

但是我发现以下语句:

[..]听起来可疑,就像您可以使用相同的纹理图像单元一样 对于不同的采样器,只要它们具有不同的纹理类型即可. 不要这样做.规范明确禁止它;如果两个不同 GLSL采样器具有不同的纹理类型,但与 相同的纹理图像单元,则渲染将失败. 互赠 采样器使用其他纹理图像单元.

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

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

解决方案

那为什么存在?好吧...

从前,没有纹理单位(这就是glActiveTexture是与glBindTexture分开的功能的原因).确实,OpenGL 1.0中甚至没有纹理 objects .但是仍然需要不同种类的纹理.您仍然需要能够为2D纹理和3D纹理创建数据.因此,他们提出了纹理目标的区别,并使用glEnable s确定在渲染操作中将使用哪个目标.

当纹理对象在GL 1.1中出现时,他们必须决定纹理对象与目标之间的关系.他们决定,一旦将对象绑定到目标,该对象便会永久与该目标相关联.由于前述需要具有不同类型的多个纹理以及旧的启用功能,因此决定每个目标代表一个单独的对象绑定点.并且它们使您在glBindTexture中重复绑定点,以便代码的读者可以清楚地看到您正在干扰哪个绑定点的数据.

当多重纹理出现时,请切入OpenGL 1.2.因此,现在他们需要您能够将同一目标的多个纹理绑定到不同的单元".但是他们不能更改glBindTexture来指定特定的单位.那将是一个向后不兼容的更改.

现在,他们本可以彻底修改纹理的工作方式,从而创建专门用于多重纹理等的新绑定功能.但是OpenGL ARB喜欢向后兼容.他们喜欢使旧的API函数正常工作,无论最终的API外观如何.因此,相反,他们决定纹理单元将是绑定的整个 set ,每个集合都具有启用状态,该状态说明哪个目标是要使用的目标.然后您可以使用glActiveTexture在单位之间进行切换.

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

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

最好忽略此功能的存在.绑定特定的着色器所需的正确纹理.因此,专注于使用这些功能,而不必担心您可能将两个纹理绑定到同一目标这一事实.如果要确定您不是偶然使用了错误的纹理,可以使用glBindTexturesglBindTextureUnit的纹理名称为0,这将取消绑定特定纹理单元中的所有目标.

I'm trying to understand Textures, Texture Units and Samplers in OpenGL 4.5. I'm attaching a picture of what I'm trying to figure out. I think in my example everything is correct, but I am not so sure about the 1D Sampler on the right side with the question mark.

So, I know OpenGL offers a number of texture units/binding points where textures and samplers can be bound so they work together.

Each of these binding points can support one of each texture targets (in my case, I'm binding targets GL_TEXTURE_2D and GL_TEXTURE_1D to binding point 0, and another GL_TEXTURE_2D to binding point 1).

Additionally, samplers can be bound to these binding points in much the same way (I have bound a 2D sampler to binding point 0 in the pic).

The functions to perform these operations are glBindTextureUnit and glBindSampler.

My initial thought was to bind the 1D sampler to binding point 0, too, and in shader land do the matching based on the binding point and the type of the sampler:

layout (binding = 0) uniform sampler1D tex1D;
layout (binding = 0) uniform sampler2D tex2D;

Quoting the source:

Each texture image unit supports bindings to all targets. So a 2D texture and an array texture can be bound to the same image unit, or different 2D textures can be bound in two different image units without affecting each other. So which texture gets used when rendering? In GLSL, this depends on the type of sampler that uses this texture image unit.

but I found the following statement:

[..] sounds suspiciously like you can use the same texture image unit for different samplers, as long as they have different texture types. Do not do this. The spec explicitly disallows it; if two different GLSL samplers have different texture types, but are associated with the same texture image unit, then rendering will fail. Give each sampler a different texture image unit.

So, my question is, what is the purpose of binding different texture targets to the same binding point at all, if ultimately a single sampler is going to be bound to that binding point, forcing you to choose?

The information I'm quoting: https://www.khronos.org/opengl/wiki/Texture#Texture_image_units

解决方案

So why does this exist? Well...

Once upon a time, there were no texture units (this is why glActiveTexture is a separate function from glBindTexture). Indeed, there weren't even texture objects in OpenGL 1.0. But there still needed to be different kinds of textures. You still needed to be able to create data for a 2D texture and a 3D texture. So they came up with the texture target distinction, and they used glEnables to determine which target would be used in a rendering operation.

When texture objects came into being in GL 1.1, they had to decide on the relationship between a texture object and the target. They decided that once an object was bound to a target, it was permanently associated with that target. Because of the aforementioned need to have multiple textures of different types, with the old enable functionality, it was decided that each target represented a separate object binding point. And they made you repeat the binding point in glBindTexture, so that it would be clear to the reader of the code which binding point's data you were disturbing.

Cut to OpenGL 1.2, when multitexture came out. So now they need you to be able to bind multiple textures of the same target, but to different "units". But they couldn't change glBindTexture to specify a particular unit; that would be a backwards-incompatible change.

Now, they could have completely revamped how textures work, creating a new binding function specifically for multitexturing and the like. But the OpenGL ARB loves backwards compatibility; they like making the old API functions work, no matter what the resulting API looks like. So instead, they decided that a texture unit would be an entire set of bindings, with each set having an enable state saying which target was the one to be used. And you switch between units with glActiveTexture.

Of course, once shaders came about, you can see how this all changes. The enable state becomes the sampler type in the shader. So now there's no explicit code describing which texture target is enabled; it's just shader stuff. So they had to make a rule that says that two samplers cannot use the same unit if they're different types.

That's why each texture unit has multiple independent binding points: OpenGL's commitment to backwards compatibility.

It is best to ignore that this capability exists. Bind the right textures that your particular shader needs. So focus on using those functions, and don't worry about the fact that you could have two textures bound to the same target. If you want to make certain that you're not accidentally using the wrong texture, you can use glBindTextures or glBindTextureUnit with a texture name of 0, which will unbind all targets in the particular texture unit(s).

这篇关于OpenGL4.5-绑定多个纹理和采样器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆